CSS Variables

Scoping & Inheritance

A cat looking at a computer screen

CSS Variables…

  • can be defined globally or locally. 🌎🏡
  • can be REDFINED 😎
  • are scoped to the element they are declared on. 👯
  • are inherited by child elements. 🐣
  • can be overridden by cascading or specificity rules. 😒
  • can pass through the shadow DOM boundary. 🪄
  • can not modify content inside of iframes. ☹️
  • can be declared within media queries but not as media query rules or values(YET). 🫢

Scope

CSS scoping works similar to how it works in languages like Javascript:

// index.js =======================================

let color = 'red'; // define color

function changeColor() {
   color = 'blue'; // redefine color within scope
   console.log(color); // 'blue'

   let backgroundColor = 'yellow' // define backgroundColor
   console.log(backgroundColor); // 'yellow'
}

console.log(backgroundColor); // Uncaught ReferenceError: backgroundColor is not defined
console.log(color); // 'red'

Similarly, in CSS we might write:

:where(html) {
   --color: red;
}

.card {
   border-color: var(--color); /* red */
}

.card__header {
   --background-color: blue;
   --color: yellow;

   background-color: var(--background-color); /* blue */
   color: var(--color); /* yellow */
}

.card__footer {
   background-color: var(--background-color); /* undefined */
   color: var(--color); /* red */
}

Did you know?

:root is a pseudo-class that matches the root element of a tree representing the document. It is equivalent to html in CSS. However :root has higher specificity. When setting global variables, I recommend using :where(html) instead to keep the specificity low.

:where(html) {
   --color: red;
}