Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-values] Vendor prefix in <dashed-ident> #6099

Closed
Crissov opened this issue Mar 13, 2021 · 17 comments
Closed

[css-values] Vendor prefix in <dashed-ident> #6099

Crissov opened this issue Mar 13, 2021 · 17 comments

Comments

@Crissov
Copy link
Contributor

Crissov commented Mar 13, 2021

The double-hyphen prefix in custom properties came to life, basically, as an empty vendor prefix, i.e. -vnd-ident wherein vnd is the empty string.

Much later, <dashed-ident> was specified explicitly for author-defined private idents (not just properties). However, its documentation suggests that third parties, e.g. frameworks and preprocessors, should again include vendor-identifying pseudo-namespaces, but now with two hyphens in front!

Even better, it should use @--library1-custom, (…)

Can we please change this (back) to a single hyphen? Start a simple namespace registry if you must.

I understand that <custom-property-name> as used in var() could remain being restricted to double-hyphen prefixes, but other places could accept vendored idents as well. Actually, I would like vendored custom properties, too, e.g. for industry-standard color names like -ral-5002 #817 or media sizes like -iso-a2 #328 and -vesa-xga.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 14, 2021

PS: For such single-hyphen third-party property names in particular, it would be cool if their value could be (marked as) final, because although they are not defined by the CSS WG and not by the system environment, they should not be changed by authors in general.

@svgeesus svgeesus added the css-values-4 Current Work label Mar 15, 2021
@tabatkins
Copy link
Member

Vendored idents are implicitly allowed by virtue of those vendors defining that they're valid; they don't need special permission from us beyond the general guidelines in https://drafts.csswg.org/css-2018/#proprietary

The guidance you're referring to is explicitly about things that don't control the CSS implementation, and thus don't have access to vendored single-dash syntax. Allowing arbitrary access to the single-dash prefix would clash with vendored implementations.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 16, 2021

Since single-dashed properties must have no public meaning, there would actually be no serious problem in making their values available to standard properties through var() in the same way double-dashed property values are.

That’s not my main point, though, not my intent. It is rather, why should a handful of browser (engine) vendors have exclusive access to this namespace, when there is at least dozens, if not hundreds or even thousands of entities that would like to provide pseudo-constants as property–value pairs to millions of authors?

@faceless2
Copy link

What we have now is a fairly simple naming scheme - no hyphen = universal and specified in CSS, one hyphen = browser-wide, browser-specific and possibly experimental, two-hyphens = site-specific, variable, and under author control.

First, there's a lot to be said for looking at a property and immediately knowing its provenance. I'm not sure authors would give that up if they thought about it.

Second, if single-hyphen prefixes were used universally, you immediately introduce a whole new class of failure: authors choosing a prefix, unaware that it's in use by a CSS engine they haven't heard of. Try and render that page on that engine and you'll potentially get different results. I'm sure you'd steer clear of -moz-NNN, -webkit-NNN or -chrome-NNN, but off the top of my head I can name six other prefixes in use today, and I'm sure there are more.

In short, from an author perspective you're saving a hyphen. From a vendor perspective outside of the big-three, what you're suggesting is a long-term disaster.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 16, 2021

The potential namespace conflicts exist regardless the number of hyphens in front. In practice, they are highly unlikely even without a registry.

no hyphen = universal and specified in CSS,
one hyphen = browser-wide, browser-specific and possibly experimental,
two-hyphens = site-specific, variable, and under author control.

Since the one hyphen case is, by definition, irrelevant for public stylesheets, I’m arguing that it is free for:

one hyphen = cross-site, library or framework specific

@faceless2
Copy link

Since the one hyphen case is, by definition, irrelevant for public stylesheets

That's clearly not true. Vendor-prefixed properties are used on millions, billions of public facing websites.

The potential namespace conflicts exist regardless the number of hyphens in front. In practice, they are highly unlikely even without a registry.

The chance of collision on a single page is remote, which is why the current system works. Because your proposal combines the namespace used by authors with the namespace use by each browser vendor, what you need to consider is the chance of collision for any combination of page and that browser. As more pages are processed by that engine, that number approaches one.

To illustrate: I define -moz-NNN custom property in a page, and it happens to collide with an internal undocumented property name used in Firefox. My page now renders differently in Firefox than it does in Webkit, or Firefox crashes because I've messed with some internal state. Multiply four billion webpages by N vendor prefixes, and the likelihood of this happening approaches certainty. It's bad for vendors, bad for authors, and brings virtually no benefit. It's not a good idea.

@tabatkins
Copy link
Member

Since single-dashed properties must have no public meaning, there would actually be no serious problem in making their values available to standard properties

That's not at all true. Vendored properties have vendor-private meanings. Me and Mike have both explained this, but you seem to be intentionally misinterpreting it. :/

Anyway, this sort of syntax change isn't going to happen. We kept custom properties away from vendored properties for a good reason.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 17, 2021

Yes, there are legacy single-dash properties in use on public webpages. Those, and especially their browser vendor prefixes, are well known. There should not be new ones.

I’m not at all saying that a random author should be able to specify and respecify a value for a custom property like -vnd-foo. I’m talking about reusable standards, libraries, frameworks etc.

We actually do have a mechanism for namespaces already that could be reused, <namespace-prefix>.

@namespace vnd url("https://example.com/ns");

foo {content: var(-vnd-bar);}

webkit etc. could be specified as predefined namespace prefixes in the default stylesheet.

@Crissov Crissov changed the title Vendor prefix in <dashed-ident> [css-values][css-namespaces] Vendor prefix in <dashed-ident> Mar 17, 2021
@faceless2
Copy link

Those, and especially their browser vendor prefixes, are well known. There should not be new ones.

You've just shut the door on any new browser vendors, as well as any new features being added to CSS. I really think you need to pause and take a step back here to weigh up the benefits of your proposal vs the costs, in terms of developer time and risks.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 17, 2021

Huh? I even suggested a method to make prefixes – regardless whether old or new – unambiguous, using existing features of CSS.

@tabatkins
Copy link
Member

@namespace doesn't work that way. It's for referring to XML namespaces, and only works in tagname and attribute selectors. Namespaces are also scoped to the stylesheet they appear in, and don't affect imported or importing sheets, meaning it wouldn't help with this issue in any case, since vendored properties often appear in other stylesheets; we'd have to grandfather in all the existing prefixes and then require any new prefixes to spam @namespace rules around. (Which I'm moderately opposed to in any case, since XML namespaces are a terrible design, for several reasons.)

Since the use-case here is "it would be nice if we could use one less dash in custom properties", but the presence of two dashes doesn't seem to have meaningfully impaired uptake of custom properties nor spawned any major complaints that I'm aware of, I don't see a reason why we should introduce the potential confusion of mixing vendored prefixes with custom properties, not to mention increasing the complexity of other little-known features just to solve the new problems subsequently introduced by this change.

@Crissov
Copy link
Contributor Author

Crissov commented Mar 17, 2021

I didn’t say there would be no changes needed to [css-namespaces].

The use case this would solve is the following:

Have pseudo-constant pseudo-custom properties
specified by a third party,
which are usable by many authors
who will neither want to nor be able to overwrite the values.

In other words, this would introduce write-protected variables in the space accessible by var().

In https://example.com/ns:

:root {--green: #090;}
.foo  {--green: #3F3;}
.bar  {
    -vnd-green: #C00; /* invalid property */
}

In my stylesheet:

@namespace vnd url("https://example.com/ns");
@namespace svg url("http://www.w3.org/2000/svg");

:root {--green: #2A2;}
.foo  {--green: #1E1;}
.bar  {
    -vnd-green: #F00; /* invalid assignment of known property */ 
    -svg-green: #E00; /* invalid assignment of unknown property */ 
    -moz-green: #D00; /* invalid assignment of unknown property */ 
}

.bar {
  color: var(--green);    /* #2A2 */
  color: var(-vnd-green); /* #090 */
  color: var(-svg-green); /* undefined */
  color: var(-moz-green); /* undefined */
}
.foo {
  color: var(--green);    /* #1E1 */
  color: var(-vnd-green); /* #3F3 */
}

@Crissov
Copy link
Contributor Author

Crissov commented Mar 22, 2021

This does not need to reuse @namespace, of course.

@prefix foo url("http://example.com/external.css");

It may even be useful to alternatively be able to specify values inline, although I'm not sure whether such an at rule should contain rulesets with selectors:

@prefix foo {
  :root {
    --bar: baz;
  }
}

or just rules:

@prefix foo {
  --bar: baz;
}

I'm also not sure whether the prefix should be a quoted string or unquoted identifier when it is specified in the at rule:

@prefix "foo" /*...*/

@tabatkins
Copy link
Member

Whether it uses @namespace or a new at-rule, it's still a lot of complexity just to avoid the fact that you've created a clash with vendor prefixes. We can just... not clash with vendor prefixes, as we do today.

Have pseudo-constant pseudo-custom properties
specified by a third party,
which are usable by many authors
who will neither want to nor be able to overwrite the values.

As far as I can determine, this use-case is already satisfied sufficiently well by "custom properties with a prefix". I haven't seen authors clamoring for the ability to protect their custom properties from being overwritten. Do you have examples of authors asking for this?

@Crissov
Copy link
Contributor Author

Crissov commented Mar 23, 2021

Except this doesn’t actually clash with vendor-prefixed properties, because those cannot be used inside var() #5729, and the prefix would never be used directly in property names on the left side of a colon, where vendor-prefixed properties are used.

-browser-property: var(-library-value), 
                   -browser-value;

One example use case for constant values that should not be changed by authors are color palettes and sets #817, as mentioned in my initial comment.

@Crissov
Copy link
Contributor Author

Crissov commented Jan 24, 2023

I think some of my @prefix variants described above could become part of the @sheet proposal in #5629.

/* stylesheet.css */
:root {--value: green;}
/* other.css */
@import foo as bar from url(stylesheet.css);

a {
  --value: red;
  color: var(--value); /* red */
  background: var(-foo-value); /* undefined */
  border-color: var(-bar-value); /* green */
}

b {
  color: var(--value); /* green */
}

@Crissov
Copy link
Contributor Author

Crissov commented Jan 26, 2023

An alternative use of prefixes within custom properties could be explicitly accessing cascade layers defined by @layer at-rules.

@layer bar, foo;
@layer foo {
  :root {
    --value: green;
  }
}
@layer bar {
  :root {
    --value: red;
  }
}

 
a {
  color: var(--value); /* green */
  background: var(-foo-value); /* green */
  border-color: var(-bar-value); /* red */
}

@layer bar {

b {
  color: var(--value); /* red!? */
  background: var(-foo-value); /* green */
  border-color: var(-bar-value); /* red */
}

}

@Crissov Crissov changed the title [css-values][css-namespaces] Vendor prefix in <dashed-ident> [css-values] Pseudo-constants with prefix in <dashed-ident> Feb 12, 2023
@Crissov Crissov changed the title [css-values] Pseudo-constants with prefix in <dashed-ident> [css-values] Vendor prefix in <dashed-ident> Feb 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants