if statements and for loops in CSS

I am likely going to write a “CSS for JavaScripters” book, and therefore I need to figure out how to explain CSS to JavaScripters. This series of article snippets are a sort of try-out — pre-drafts I’d like to get feedback on in order to figure out if I’m on the right track.

Today I continue to look at CSS as a programming language. The question whether it is one or not is a very hot topic right now, but I’m not terribly interested in the answer.

Instead, I’d like to know if describing certain CSS structures in programming terms helps you learn CSS better or quicker, or if it hinders you. In other words, is there any educational value in treating CSS as a programming language?

Please tell me if the explanation below is helpful or confusing to you.

if statements

An area where the CSS programming language is less developed than JavaScript is control structures — or so it would seem.

Still, CSS has if statements. Here are a few examples:

@media all and (max-width: 900px) {
}
@supports (display: flex) {
}

These mean “if the layout viewport is at most 900px wide” and “if the CSS engine accepts display: flex.” There is no doubt that these are actual if statements: the code blocks are only applied if the condition is true. (Also, the specification for @media and @supports is called CSS Conditional Rules. That’s a dead giveaway: at-rules are meant to be if statements.)

But let’s take a look at a — dare I say it? — more iffy example. Is the following also an if statement?

menu a {
color: red;
}

“If there is a link within a menu, make it red.” Several people I interviewed for the book were passionate in their belief that selectors are if statements as well.

Do you agree? Do I agree? I’m not sure, although I do see the point: it is possible to see selectors as such. Whether you consider them true if statements probably depends on your definition of an if statement.

for loops

Let’s make things slightly more complicated by considering for loops. Now at first sight it would appear CSS doesn’t have any. Still, what about the same bit of code we saw above?

menu a {
color: red;
}

In a way, a selector like the one above could be considered a primitive for-loop. The browser is told to loop through all <a> elements inside a <menu> element and apply a red colour.

Is a selector a for loop? Can it even be an if statement and for loop at the same time? Again, this depends on your definitions of for loops and if statements.

I’d like to mention in passing that it is possible to add extra logic to CSS for loops.

These extra selectors can be treated as if statements within a for loop: go through all links in a menu, but skip this one and give that one special treatment.

Declarative vs imperative

Let’s take the most expansive view and say that CSS selectors can be considered both if statements and for loops. That will sound fairly weird for anyone with a background in JavaScript, since these two types of control structures are simply not the same. So how can you replace both by a single structure?

Here, I think, we once again see that CSS is a declarative language, and not an imperative one. In declarative languages some simple control structures can be expressed much more succinctly than in imperative ones.

Take the last code example above. In JavaScript we’d have to say something like:

for (all menus) {
for (all links in this menu) {
let first = [figure out if this is the first link in the menu]
if (first) {
link.color = 'blue'
} else if (link.id !== 'current') {
link.color = 'red';
}
}
}

The drawback of the JavaScript version is that it’s more verbose than the CSS version, and hence more prone to error. The advantage is that it offers much finer control than CSS. In CSS, we’ve just about reached the limits of what we can express. We could add a lot more logic to the JavaScript version, if we wish.

In CSS, we tell the browser how links should look. In JavaScript, we describe the algorithm for figuring out how an individual link should look. Neither is wrong, but in this example the CSS way is the more efficient way.

Personally, I’m fine with seeing CSS selectors as if statements and for loops at the same time. However, I feel that once you start understanding CSS, the fact that selectors are ifs/fors becomes less and less relevant. Instead, selectors are just selectors: great for relatively simple declarations; less so for very complex ones.

Helpful or confusing?

If you’re a JavaScripter who’d like to get to know CSS better I’d love to hear if the few examples above are helping or confusing you. The more feedback I get, the better I can write a book that helps you learn CSS instead of just confusing you.

Thanks.

Feedback

Badly formatted

See also https://csswizardry.com/2015/04/cyclomatic-complexity-logic-in-css/

See also https://adactio.com/journal/14574

I did a presentation about this topic at AmsterdamJS, and the feedback I got made me conclude that this approach is not really suited for learning CSS. Everybody understood my point, but most thought it didn't really help them understand CSS better. So this is going to become a sidebar in the book, and not main text.