J'ai besoin d'intimité. Non pas parce que mes actions sont douteuses, mais parce que votre jugement et vos intentions le sont.
5138 links
In the last few years CSS preprocessors had a lot of success. It was very common for greenfield projects to start with Less or Sass. And it’s still a very popular technology.
The main benefits of those technologies are, in my opinion:
Modern CSS has a new powerful feature called CSS Custom Properties, also commonly known as CSS Variables.
CSS is not a programming language like JavaScript, Python, PHP, Ruby or Go where variables are key to do something useful. CSS is very limited in what it can do, and it’s mainly a declarative syntax to tell browsers how they should display an HTML page.
But a variable is a variable: a name that refers to a value, and variables in CSS helps reduce repetition and inconsistencies in your CSS, by centralizing the values definition.
And it introduces a unique feature that CSS preprocessors won’t never have: you can access and change the value of a CSS Variable programmatically using JavaScript.
A CSS Variable is defined with a special syntax, prepending two dashes to a name (--variable-name
), then a colon and a value. Like this:
:root {
--primary-color: yellow;
}
(more on :root
later)
You can access the variable value using var()
:
p {
color: var(--primary-color)
}
The variable value can be any valid CSS value, for example:
:root {
--default-padding: 30px 30px 20px 20px;
--default-color: red;
--default-background: #fff;
}
CSS Variables can be defined inside any element. Some examples:
:root {
--default-color: red;
}
body {
--default-color: red;
}
main {
--default-color: red;
}
p {
--default-color: red;
}
span {
--default-color: red;
}
a:hover {
--default-color: red;
}
What changes in those different examples is the scope.
Adding variables to a selector makes them available to all the children of it.
In the example above you saw the use of :root
when defining a CSS variable:
:root {
--primary-color: yellow;
}
:root
is a CSS pseudo-class that identifies the document, so adding a variable to :root
makes it available to all the elements in the page.
It’s just like targeting the html
element, except that :root
has higher specificity (takes priority).
If you add a variable inside a .container
selector, it’s only going to be available to children of .container
:
.container {
--secondary-color: yellow;
}
and using it outside of this element is not going to work.
Variables can be reassigned:
:root {
--primary-color: yellow;
}
.container {
--primary-color: blue;
}
Outside .container
, --primary-color
will be yellow, but inside it will be blue.
You can also assign or overwrite a variable inside the HTML using inline styles:
<main style="--primary-color: orange;">
<!-- ... -->
</main>
CSS Variables follow the normal CSS cascading rules, with precedence set according to specificity
The coolest thing with CSS Variables is the ability to access and edit them using JavaScript.
Here’s how you set a variable value using plain JavaScript:
const element = document.getElementById('my-element')
element.style.setProperty('--variable-name', 'a-value')
This code below can be used to access a variable value instead, in case the variable is defined on :root
:
const styles = getComputedStyle(document.documentElement)
const value = String(styles.getPropertyValue('--variable-name')).trim()
Or, to get the style applied to a specific element, in case of variables set with a different scope:
const element = document.getElementById('my-element')
const styles = getComputedStyle(element)
const value = String(styles.getPropertyValue('--variable-name')).trim()
If a variable is assigned to a property which does not accept the variable value, it’s considered invalid.
For example you might pass a pixel value to a position
property, or a rem value to a color property.
In this case the line is considered invalid and ignored.
Browser support for CSS Variables at the time of writing (Mar 2018) is very good, according to Can I Use.
CSS Variables are here to stay, and you can use them today if you don’t need to support Internet Explorer and old versions of the other browsers.
If you need to support older browsers you can use libraries like PostCSS or Myth, but you’ll lose the ability to interact with variables via JavaScript or the Browser Developer Tools, as they are transpiled to good old variable-less CSS (and as such, you lose most of the power of CSS Variables).
This variable:
--width: 100px;
is different than:
--Width: 100px;
To do math in CSS Variables, you need to use calc()
, for example:
:root {
--default-left-padding: calc(10px * 2);
}
Nothing special here. CSS Variables normally apply to media queries:
body {
--width: 500px;
}
@media screen and (max-width: 1000px) and (min-width: 700px) {
--width: 800px;
}
.container {
width: var(--width);
}
var()
accepts a second parameter, which is the default fallback value when the variable value is not set:
.container {
margin: var(--default-margin, 30px);
}