Open cdoublev opened 1 year ago
I think a type should always be defined as a "global" value, then a rule/property/descriptor/type can restrict or contextualize its definition.
Global and local definitions are conceptually correct but the main problem is probably the lack of consistency across specs, making it harder to process the data. That heterogeneity is likely a simple result of there being different spec authors (who approach definitions with slightly different mental models), and of this likely being seen as low priority in any case. If it becomes clear that a global (or local) approach is the way to go, we could envision curating the data in Reffy.
To start with, I think it would be useful to list values (and specs) that look like types or functions and that don't have corresponding global type or function definitions. Do you have that at hand by any chance? I'll explore the data otherwise.
A side question is whether definitions that have a data-dfn-type
equal to type
or function
can also have a data-dfn-for
attribute. I think that there are some occurrences of that in the extracts.
To start with, I think it would be useful to list values (and specs) that look like types or functions and that don't have corresponding global type or function definitions
A quick look at data yields the following list of types and functions that don't have a global definition (number of occurrences is the number of occurrences as value in the extract, not in the spec):
<timeline-name>
<content-replacement>
<content-list>
(2 occurrences)cubic-bezier()
steps()
stylistic()
styleset()
character-variant()
swash()
ornaments()
annotation()
<feature-tag-value>
<palette-identifier>
minmax()
(2 occurrences)fit-content()
(2 occurrences)<grid-line>
(4 occurrences)type()
rect()
fade()
snap-block()
snap-inline()
<coordinate-pair>
<by-to>
<move-command>
<line-command>
<hv-line-command>
<curve-command>
<smooth-command>
<arc-command>
<arc-sweep>
<arc-size>
inset()
xywh()
rect()
circle()
ellipse()
polygon()
path()
fit-content()
(7 occurrences)<decibel>
(2 occurrences)<age>
<gender>
<semitones>
(3 occurrences)auto()
<lang>
<length-percentages>
matrix()
translate()
translateX()
translateY()
rotate()
skew()
skewX()
skewY()
<url-set>
<compat-auto>
<compat-special>
<start-value>
<end-value>
child()
blur()
brightness()
contrast()
drop-shadow()
grayscale()
hue-rotate()
invert()
opacity()
saturate()
sepia()
ray()
<size>
I was wrong, sorry: it is fine that a type is declared only under a namespace.
A side question is whether definitions that have a
data-dfn-type
equal to type or function can also have adata-dfn-for
attribute.
The problem is that <timeline-name>
is only ever defined with data-dfn-type
equal to value
, with its production rule wrapped in the corresponding <dd>
. Maybe the spec author should add data-dfn-type=type
on its <dfn>
to supersede data-dfn-type=value
on the parent <dl>
?
Restricting the search to value
s whose name
looks like a type
but are never defined as such, I only have the following results (excluding <timeline-name>
):
<feature-tag-value>
: same problem, I think it should be defined with dfn-type=type
here<length-percentages>
: it should not exist, cf. related issue[motion] (fixed)<size>
: same problem, cf. related issue
the main problem is probably the lack of consistency across specs, making it harder to process the data
Yes. I also agree that it is likely being seen as low priority in any case.
I was thinking that adding some templates in the Bikeshed documentation, that spec authors could refer to, may help a bit. Ideally, the existing specs should be correct and such templates would not be needed.
I don't know what the correct way of defining CSS things should be, but if the argument is that there should always be an underlying type
definition of a value when it is actually a type, I think that the same should apply for functions. Completing your list with function-like values that are only defined as value
yields:
<timeline-name>
stylistic()
styleset()
character-variant()
swash()
ornaments()
annotation()
<feature-tag-value>
minmax()
(2 occurrences)fit-content()
(2 occurrences)fit-content()
(7 occurrences)auto()
<length-percentages>
child()
<size>
On top of these, there are at least a couple of places where things look a bit clunky:
<content-list>
is defined as a local type
for the content
property, but also as a value
for the bookmark-label
property. The second definition references the first, but the first does not have bookmark-label
in its data-dfn-for
and probably should.<decibel>
is defined as both a type
and a value
for the voice-volume
property. Both definitions could probably be merged into a single type
definition. Same thing for <semitones>
.I was thinking that adding some templates in the Bikeshed documentation, that spec authors could refer to, may help a bit. Ideally, the existing specs should be correct and such templates would not be needed.
Always a good idea to add more documentation for spec authors. Pull requests that improve the documentation would most likely be well received :)
For what it's worth, the definitions data model currently embedded in Bikeshed's documentation is also followed by ReSpec (even though ReSpec's documentation currently says that only dfn
and idl
are supported) and the editing tool that powers the HTML spec. With a few exceptions. We tried to move the model to a separate document and converge on a single model some time ago, see https://github.com/speced/spec-dfn-contract. That did not go very far for lack of a dedicated editor.
[...] if the argument is that there should always be an underlying
type
definition of a value when it is actually a type, I think that the same should apply for functions
I do not think so. Here is my understanding, removing any I think and ignoring that you may already agree with some of these statements.
foo()
can be defined as foo() = foo(<length>)
for a property distance
, and as foo() = foo(<time>)
for a property duration
. foo()
must be defined with <dfn dfn-type="value">
in both property definitions. It must never be defined with <dfn dfn-type="function">
, and it cannot be referenced as <foo()>
.
When the syntax of foo()
is not context-sensitive and is used in different context, it must be defined with <dfn dfn-type="type">
and it can be referenced as <foo()>
. Some property may define it with <dfn dfn-type="value">
to provide some specific (context-sensitive) parsing or serialization rules in prose, or some context to interpret the result from parsing.
These cases are examples where a template may be usefull.
Thanks for giving me some context on this.
When the syntax of
foo()
is not context-sensitive and is used in different context, it must be defined with<dfn dfn-type="type">
and it can be referenced as<foo()>
Did you mean dfn-type="function"
or are you intentionally suggesting to get rid of function
as a definition type?
foo()
can be defined asfoo() = foo(<length>)
for a propertydistance
, and asfoo() = foo(<time>)
for a propertyduration
.foo()
must be defined with<dfn dfn-type="value">
in both property definitions. It must never be defined with<dfn dfn-type="function">
, and it cannot be referenced as<foo()>
.
That would work. That said, as with selectors, I'm personally interested in foo
being exposed as a function directly because all developers are going to understand foo(<length>)
as "calling function foo
with a length as parameter", and some people will want to document or talk about foo
as a function as a result. Hiding it as a value does not help. Whether the meaning foo
depends on the underlying property is orthogonal.
The fact that such functions sometimes appear using a functional notation (<foo()>
) coupled with a real function definition, and sometimes directly as a combination of keyword, literals and type references (foo(<length>
) does not help either.
One example where this affected MDN pages for the fit-content()
function page is described in https://github.com/mdn/content/issues/18780#issuecomment-1216912692
Also, having functions directly at hand makes it easier to build or validate pages such as the CSS Functional index.
As usual, the CSS Working Group would be the right place to go to suggest changes. The approaches mentioned above or the hybrid model currently followed by CSS specs all more or less work as far as I can tell. Re-constructing the list of functions automatically from values is not too hard in particular.
Yes, I meantfunction
, and I totally agree with the rest.
Fwiw, css-module
seems to be a CSS-specific template. It does not include an example of a function namespaced under a property, a type namespaced under a function, a rule, a type defined in a definition list of values, etc.
Maybe we can discuss the examples it might include in another issue, before making a PR? Or you can do this without me. I am just offering my help if you do not want or do not have time to do it.
It's a good idea to crystallize guidelines in the css-module
template. Your help is definitely welcome! I indeed don't think I'll have much time to do that. Feel free to engage with the CSS WG directly and/or to list the different cases in an issue here beforehand!
I also note that I don't exactly know what to suggest in corner cases. For instance, I didn't address the definition of <wcag2>
in CSS Color 6 to expose a function after all, because I realized I did not really know what to recommend. The wcag2
value and the wcag2()
functional notation are scoped to contrast-color()
. The function would be useless in any other context so that makes sense to me. That said, the wcag2()
function appears in <wcag2>
which, as a "type" in the global namespace. It does not make sense to me to reference a scoped definition from a global definition (that would make the scoped definition part of the global namespace). In the end, I don't really know what markup to suggest.
Since this change (I think),
<timeline-name>
is not extracted as atype
but only as avalue
namespaced under<single-animation-timeline>
. The HTML markup looks like this:I think a type should always be defined as a "global" value, then a rule/property/descriptor/type can restrict or contextualize its definition.
However I do not think it should be the responsibility of Reffy to provide this guarantee, and the above markup looks wrong to me. I would like to get your opinion before asking for a fix on
w3c/csswg-drafts
.EDIT:
<timeline-name>
has been replaced by<custom-ident>
, which is a well defined terminal / CSS basic type, but the root problem remains, ie. a type should be defined at least once as atype
.