CSS: Selector Variables

Published on February 7, 2008 (↻ June 18, 2022), filed under (RSS feed for all categories).

This post is partially outdated.

Complex projects suffer from higher cost of selector changes, and long sequences of simple selectors do impact the understandability and efficiency of style sheets. One solution could be selector variables or “synonyms,” a concept I proposed to the CSS Working Group yesterday, again if you want as Carmelo Capinpin did suggest something similar in 2006.

The ongoing discussion brought up a few questions concerning definition and behavior (David Baron) and use cases (Elika Etemad) and revealed issues concerning the specification and implementation of these variables.

Here the proposal again:

The basic idea is to syntactically allow definitions like

E = F;


so that rules matching E would match F as well (and the other way around), while variable (or synonym) declarations could probably be located at the beginning of a style sheet or within a certain @-rule.

A more advanced step [for] even more benefits is to allow selector grouping and a specific placeholder syntax as well, as in

E = F, G;
@H = I;


where @H wouldn’t mean a “regular” selector but a “placeholder” only viable in style sheets and requiring a “regular” selector equivalent.

While current selector grouping [
] covers some use cases [for] these variables, there are a few specific benefits to them (omitting “when used right” and cutting examples):

  • Improved maintainability and “refactorability”:

    Currently, the wish [
] for ID and class name changes can only be addressed when both markup and style sheets are changed. Selector variables could not only offer faster changes and better maintainability by allowing “change CSS now, HTML later” cases, they could also mean a helpful precaution, for example, when IDs/classes are changed “anywhere” but authors are not or can not be sure if [there are any leftovers], or when they need to tolerate delayed changes on partner sites using the same CSS files. (Talking complex projects, this is.)

    Example: .old = .new;

  • Improved style sheet clarity:

    Extensive use of contextual selectors and/or long ID and class names usually resulting in less clear style sheets might be avoided by selector variables.

    Example: @foo = #navigation li a;

  • Improved CSS efficiency:

    Not talking about possible compression tools, style sheet size might easily be decreased by “compressing” long selectors through variables—without style sheets necessarily getting less readable or understandable.

Elika’s question for use cases and the problems the suggestion tries to solve lead me to additional reasoning:

The main problem the suggestion attempts to solve is the cost of selector changes. Currently, selector changes (above all referring to ID and class names) require changes in both HTML and CSS. There are cases, however, where especially complex sites cannot guarantee all HTML to be changed, at least not in a timely fashion, while in these cases, selector grouping reduces maintainability (after all, the selectors in question should be changed, not extended) and bears a larger risk of getting overlooked later. Thus, improvements are either delayed or even dropped, and both cost and risk of changes are relatively high.

Selector variables could offer low-cost, instant changes without any risk of formatting and “compatibility” problems, via .old = .new; or @foo = .old, .new;, for example.

Another use case I see is the effect the (by all means desirable) way to use sequences of simple selectors has on CSS understandability and efficiency, meaning that “contextual selectors” are elegant but tend to be longer [and therefore] less understandable than simple selectors (referring to more complex style sheets again).

Example (HTML 4):

<ul id="nav">
  <li><strong>Home</strong>
  <li><a href="/exit">Exit</a>
  <!-- 
 -->
</ul>
#nav strong {}

Assuming that the default li/strong element styling is not desired and the author wants to style indicators of “active” pages differently, the selector #nav strong appears to be an appropriate choice. However, a simple selector like #on would be shorter[, though it’s] not elegant HTML:

<ul id="nav">
  <li><strong id="on">Home</strong>
  <li><a href="/exit">Exit</a>
  <!-- 
 -->
</ul>
#on {}

Although there are even less characters used in the second example, it [shouldn’t] mean too much abstraction to project that on cases where the selector in question is used more than once, and that exactly is the other problem: How can style sheets get more compact while at the same time preventing unneeded HTML changes and staying readable?

As for the example above and given that our selector is used five times, selector variables/placeholders could make

@on = #nav strong; /* user agent just replacing ”@on” by ”#nav-strong” */
@on {}
@on, .foo {}
@on, .bar {}
@on, .baz {}
@on, .qux {}

out of

#nav strong {}
#nav strong, .foo {}
#nav strong, .bar {}
#nav strong, .baz {}
#nav strong, .qux {}

I’m looking forward to feedback from the Working Group, though it won’t be easy for me to “talk spec” and address all issues. See specific problems like the handling of @foo, E = .bar, #baz; E@foo {} or test cases; things will boil down to articulating sound arguments.

In case my English lets me down: Can you challenge this, or support the case?

Was this useful or interesting? Share (toot) this post, or support my work by buying one of my books (they’re affordable, and many receive updates). Thanks!

About Me

Jens Oliver Meiert, on September 30, 2021.

I’m Jens (long: Jens Oliver Meiert), and I’m a frontend engineering leader and tech author/publisher. I’ve worked as a technical lead for companies like Google and as an engineering manager for companies like Miro, I’m close to W3C and WHATWG, and I write and review books for O’Reilly and Frontend Dogma.

I love trying things, not only in web development (and engineering management), but also in other areas like philosophy. Here on meiert.com I share some of my views and experiences.

If you’d like to do me a favor, interpret charitably (I speak three languages, and they do collide), yet be critical and give feedback for me to fix issues, learn, and improve. Thank you!

Comments (Closed)

  1. On June 18, 2011, 20:32 CEST, Kammreiter said:

    Die Idee, E=F soll bedeuten, F verhalte sich wie E, oder die Erweiterung E=F,G; daß sich F und G so verhalten sollen wie E ist eine konsequent weitergedachte Variabilierung von CSS, hat meiner Meinung nach aber den Beigeschmack, das Konzept von Variablen an sich zu ĂŒberfrachten. Mir fehlt in CSS die Möglichkeit, direkt Variablen einzufĂŒhren, fĂŒr die genau diese Schreibweise, aber eben im Sinne der mathematisch-informatorischen Zuweisung gelten wĂŒrde: varMeinWert=1.8em; und dann halt font-size:varMeinWert; etc.

    Den Vorteil, in komplexen Projekten Ungleichzeitigkeiten von VerĂ€nderungen in CSS und HTML damit auszugleichen sehe ich wohl. Die durchaus mögliche Klarheit könnte aber durch die Namensgebung wieder konterkariert werden, wĂ€hrend die bisherige - ausfĂŒhrliche - Codierung unmißverstĂ€ndlich, im Realfall leider auch sehr komplex bleibt.

    Der zweite Vorschlag, mit @H=I; eine echte Variable, nĂ€mlich H einzufĂŒhren, die dann genau das tut, was I bezeichnet, aber als Variable halt, scheint mir sinnvoll zu sein, wenn etwa der Variablenname die intendierte Funktion wiedergibt und die Zuordnung die aktuell gefundene oder gewĂ€hlte Realisierung darstellt.

    FĂŒr die erste Möglichkeit bleibe ich aber bei dem Wunsche, wenn nicht statt, dann ergĂ€nzend zu dem Vorschlag von dir die Zuweisung von Werten vorzuschlagen.

    Ich schreibe das auf deutsch, weil ich durch Bezugnahme auf den Inhalt die Sache auch dem deutschen Publikum leicht verstĂ€ndlich mache đŸ˜Š

  2. On June 20, 2011, 18:48 CEST, Jens Oliver Meiert said:

    Thank you. I believe variables have been brought up a number of times; I’m not sure where we are with respect to Tab’s latest proposal.

    (Please comment in English.)

  3. On July 6, 2012, 21:34 CEST, Brian Kardell said:

    Tab’s latest proposal would not allow selector variables. In fact, the confusion over the word variables for what it describes caused much confusion on the lists. Francois Remy and I have put forward for W3C consideration alternative version of the same Draft in order to remedy the confusion. I recently wrote an article about it: http://briankardell.wordpress.com/2012/06/28/properties-the-new-variables/
    We’d love to hear your thoughts and have you and your readers participate in the poll there to provide some kind of at least anecdotal data for the working group to consider.

    I proposed something similar to a few W3C members last year and it came up on the list (http://lists.w3.org/Archives/Public/www-style/2011Nov/0207.html). We have an open source project that uses this (http://www.hitchjs.com / http://hitchjs.com/describe/native.html#consts) as a global concept (not limited to selectors) and I quite like it - it is cheap to process as well - but if not limited to selectors it really does start turning CSS into a preprocessor which almost always shuts down the argument.