Custom CSS properties are so ugly with those leading dashes!


For example:


      /* Make all toolbar titles in this host green by default */
      :host {
        --my-toolbar-title-color: green;

      /* Make only toolbars with the .warning class red */
      .warning {
        --my-toolbar-title-color: red;


I think it just looks horrible. Why not just remove those?


      /* Make all toolbar titles in this host green by default */
      :host {
        my-toolbar-title-color: green;

      /* Make only toolbars with the .warning class red */
      .warning {
        my-toolbar-title-color: red;



I spoke too soon. I see now that the -- prefix is needed in order for the engine to know a var is defined, but it’s still an eye sore.

What about something like

      /* Make only toolbars with the .warning class red */
      .warning {
        var my-toolbar-title-color: red;



Custom CSS properties already started with var- in earlier spec drafts. But then the syntax has been changed to use the -- prefix. AFAIK, one of purposes of this was to make custom properties somewhat more clear as a way for polyfilling and make the difference between static preprocessor variables and CSS variables (custom properties) more obvious. It’s also in line with future custom things like Custom media queries that are planned to use the same -- prefix.

But actually, exact prefix is not a problem at all.

The real problem with CSS custom properties as for polyfilling is that elements cannot be selected by custom property like getElementsByStyleProperty('--foo'). So to write a polyfill, we need to enumerate ALL elements in the document and check value of specific property for each of them one by one.

Another problem with CSS custom properties is that they are inherited, and there is no way to determine whether specific property has been specified for specific element itself or for its ancestor. So when writing a polyfill, we are forced to ignore all descendants of elements that have the custom property though this wouldn’t necessarily be needed for the polyfilled thing itself.

So for polyfilling, it’s currently easier just to use a JS-powered CSS parser as if there were no CSS variables at all.


The exact syntax with its benefits and drawbacks has been discussed back in forth during the specification process and changed several times in the Editor’s Drafts. I for one argued in favor of non-prefixed names and even making default keywords like red overwritable.

The double hyphen is an ugly but okayish compromise, but I’m not sure why it had to be a prefix. It could as well be an infix (my-toolbar--title-color) or a suffix (my-toolbar-title-color--) or any of that at the author’s decision, and it could even have been repeatable (my--toolbar--title--color).


With properties and values you’ll be able to define if a custom property should inherit or not.

(as a side note the -- prefix can also be thought as a vendorless prefix, e.g. -webkit-foo is --foo ).


Thanks, Ian. I am aware of that document, but it is unfortunately not even an official draft spec, instead it’s just “a collection of interesting ideas”™ that probably have not too big chances to become available as working features in the foreseeable future. And, actually, ability to select elements by CSS variables is more crucial as for polyfilling.


Properties and Values should be a first public working draft within the next few days.

The blink team are going to begin to implement parts of this spec in the next couple of months.


Thanks, Ian. Nice to hear that (are you an insider?). Hopefully a JS method to select elements by custom property could then be added to that draft too.


Is @iank an insider, I believe he’s in the running for CSS Houdini man of the year.


Fwiw, I have no idea what you mean.


Could you give a practical example this feature to show why/how it would be useful and in which situations?


As I said, to write a polyfill to emulate a nonstandard CSS property, we currently need to enumerate ALL elements in the document and check value of the corresponding custom property [subject to be polyfilled] for each of them one by one.

That’s like enumerating all elements in the document and check each of the elements for matching a selector one by one instead of just using querySelectorAll(), or checking all elements for having a specific class instead of just using getElementsByClassName().

Having a native function to select elements by CSS property, we could get a narrow set of just those elements that have the specific property, and this would be not just more usable, but probably much faster in terms of JS/DOM performance.


The Custom Properties spec handles that use-case much better, by actually hooking into the CSS style pipeline.


Tab, could you be more specific? (E.g. what “this”, better than what exactly, with a provided explicit link or code example.) Thanks.


The thing you just said - using JS to polyfill a property using a custom property. Check the Custom Properties houdini spec, that’s literally what that spec is about.


Check the Custom Properties houdini spec

Are you meaning the CSS Properties and Values API spec or some other spec named exactly as you said (Custom Properties)? (Hint: providing a link would rule out any ambiguity.)

I have read the draft, it’s interesting and seems to solve the forced-inheritance issue, but I can’t figure out how it helps to search elements by property. (Fwiw, forced inheritance of CSS variables and inability to select elements by property are two separate unrelated issues with CSS variables in their current state as for polyfilling). Thanks.


Ian works on a ton of the specs and is actively involved in implementing them. Was just giving him the props :slight_smile:


Yes, the Houdini “CSS Properties & Values” spec.

All of the Houdini specs are real specs; the editors are just cheekily using the “DREAM” status in Bikeshed (the preprocessor that builds the specs) rather than “ED”. And we agreed at the recent Houdini f2f to take these all to Working Draft.


Thanks. Still unclear about getting elements by (custom) style property.


There is nothing for that, because so far there’s been no demonstrated use-case for it. Anything along the lines of “I want to make a custom property do X on an element…” is solved by the Custom Properties spec already, in a better way.