Skip to content

Instantly share code, notes, and snippets.

@pieterbeulque
Last active February 26, 2019 16:25
Show Gist options
  • Save pieterbeulque/df1309a19a548c951ad1514a02adb434 to your computer and use it in GitHub Desktop.
Save pieterbeulque/df1309a19a548c951ad1514a02adb434 to your computer and use it in GitHub Desktop.

This is a reply to @ppk's article "The CSS mental model"

I like the idea of explaining CSS to JavaScript developers using JavaScript analogies! I'm not really sure about the example you're giving, to be honest.

Would it make more sense to explain the declarative part as some code that runs on every frame to render the page again? Every part of a CSS selector then becomes either a loop or a conditional inside a loop. See below.

The given example (I dropped the :hover for reasons later explained)

nav a {
	background-color: red;
}

would then translate to this piece of code being run on every frame in a render loop.

Option 1

Makes more sense, less correct

const allNavs = Array.from(document.querySelectorAll('nav'));

allNavs.forEach((nav) => {
  const allAnchors = Array.from(nav.querySelectorAll('a'));
  
  allAnchors.forEach((a) => {
    a.style.backgroundColor = 'red';
  }
});

Option 2

More correct, but feels weird for people that don't know how CSS is interpreted

const allAnchors = Array.from(nav.querySelectorAll('a'));

allAnchors.forEach((a) => {
  if (a.closest('nav')) {
    a.style.backgroundColor = 'red';
  }
});

I also think the :hover example and pseudo-classes in general are harder to make sense when trying to explain the analogy, because the JavaScript equivalent is non-existent.

It would make more sense to explain it like this:

const allAnchors = Array.from(nav.querySelectorAll('a'));

allAnchors.forEach((a) => {              // CSS selector: a {}
  if (a.hover === true) {                // CSS selector: a:hover {}
    if (a.closest('nav')) {              // CSS selector: nav a:hover {}
      a.style.backgroundColor = 'red';
    }
  }
});

but in another way, that doesn't make sense, because it won't work. The :hover example shows the main difference between the declarative nature of CSS and the imperative nature of JavaScript.

So, while I feel it perfectly shows the difference between the two, I don't think it's an obvious enough example to explain the difference, especially for people comfortable with either CSS or JavaScript, but not both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment