Découverte des variables CSS4 !
Hop, un petit article autour des variables CSS4. Dans la joie et la bonne humeur :)
Je veux les utiliser !
Tout d'abord, il faut savoir que le taux d'adoption de cette feature est au delà des 87% des navigateurs: https://caniuse.com/#feat=css-variables
En somme, si vous visez IE11 ou moins, vous ne pourrez pas les utiliser, à condition alors d'utiliser un "ponyfill" tel que https://github.com/jhildenbiddle/css-vars-ponyfill qui ne s'activera que si vous le lui dites:
<script src="https://unpkg.com/css-vars-ponyfill"></script> <script> // Call using defaults cssVars(); // Or call with options cssVars({ variables: { color: 'red', unknown: '5px' } }); </script>
Les variables CSS, c'est quoi ?
C'est tout simplement la possibilité de déclarer une variable dans le sens propre du terme et de stocker une valeur qui pourra être réutilisée.
Cela a déjà était introduit, dans les frameworks de préprocesseurs CSS tel que LESS, Stylus, Sass, etc ...
Un exemple en LESS:
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
Quelles sont les avantages ?
- Un code plus lissible
- Nous connaissons la sémantique de la valeur en se basant sur son nom
- Les variables peuvent être regroupées
- Évitant de parcourir tous le code pour modifier la valeur
- Changement plus rapide
- Si nous exploitons bien les variables, les modifications de valeurs seront automatiques répercutées
- Résolution d'erreurs plus rapides
Définir une variable CSS
Une variable CSS est obligatoire définie dans une "CSS Rule", à savoir un bloc de condition CSS.
Exemple:
.block {
/* CSS Rule block */
}
Pour déclarer une CSS, rien de plus simple, un simple "--nameOfMyVariable" suffit:
.block { --color: blue }
Notons néanmoins qu'elle ne peut stocker que des valeurs de propriétés CSS, et pas de nom de propriétés en elle même (en somme, elle ne peut être utilisé qu'à droite du séparateur clé/Valeur ":").
Si la valeur de la variable est invalide, la propriété CSS ne sera pas appliquée.
Ceci est très important car l'exemple suivant montre un usage qui n'est pas autorisé:
:root { --size: 20 } div { font-size: var(--size)px /*WRONG*/ }
Ensuite, retenons que nous avons une équivalence avec le monde JavaScript sur la portabilité des variables, à savoir la notion de "scope".
Nous pouvons avoir:
- Des scopes globaux
- Des scopes locaux
Dans l'exemple précédent, la variable "--color" ne sera accessible que dans le bloc CSS définie. Nous avons un scope locale.
Si nous souhaitons autoriser la diffusion des variables de manière globale, il faut alors faire:
:root {
--main-color: red
}
Et là, n'importe quel bloc CSS aura accès aux variables définies.
Utiliser une variable
Contrairement aux frameworks de préprocesseurs CSS, nous ne pouvons pas utiliser la variable directement, mais uniquement via une nouvelle fonction CSS: "var".
:root { --color: red; --font: 'Arial'; } .block { color: var(--color); font-family: var(--font); }
Cette fonction a un second paramètre qui est la valeur par défaut. Ainsi, si cette variable ne peut pas être trouvée ou si cette dernière n'est pas une valeur de propriété valide.
.component .header { color: var(--header-color, blue); } .component .text { color: var(--text-color, black); } .component { --text-color: #080; }
Nous pouvons également définir une variable CSS et l'utiliser dans l'attribut style de nos éléments HTML !
<html style="--color: red">
Allons plus loin dans le scope
Entrons en détail sur cette notion de scope. Que se passe-t-il si nous avons des variables de même nom entre un scope global et local ? Et bien c'est le scope locale qui gagne:
:root { /* Global scope */ --color: red; --font: 'Arial'; } .block { /* --color === blue, --font === 'Arial' */ --color: blue; }
Tout comme en JavaScript.
En revanche, on disait plus haut que la variable de scope locale se limitait au bloc CSS. Ce n'est pas tout à fait juste, car elle applique l'héritage et le cascading des régles CSS.
Ainsi, nous pouvons tout à fait avoir:
div { --color: red; } div.test { color: var(--color) } div.ew { color: var(--color) }
Et cette notion de scope s'applique également aux media queries, ou au supports:
:root { --color: red; } @media screen and (min-width: 600px) { --color: green; } @supports (display: grid) { --color: blue; }
BEM & scoping
Si nous faisions du nested module en CSS (qui n'est pas encore implémenté) et qui est présent dans nos préprocesseurs CSS, le scope de la variabke locale serait propagé dans les nested.
Dans le cas où nous pouvons pas faire de nested, et que nous voulons faire du BEM par exemple, comme cela se passe ?
Et bien il faut savoir que comme dans tout héritage et cascading CSS, les propriétés sont propagés aux enfants, ainsi que les variables.
L'exemple suivant l'illustre très bien:
Theming facilité
Grâce aux variables CSS4, rien de plus simple de mettre en oeuvre un theming:
Et mieux encore: de pouvoir le changer on the fly:
Api JavaScript
Cette évolution de la norme CSS permet nous amène une évolution de l'api JavaScript.
En effet, pour chaque élément du DOM HTML, nous avons une api JavaScript qui nous fournit la propriété JavaScript "style" qui nous donne les informations de style de notre élément.
Cette propriété contient les méthodes "getProperty" et "setProperty" qui permettent de lire et modifier des propriétés CSS.
Et bien nous pouvons les utiliser pour modifier les variables CSS !
const root = document.documentElement const element = document.querySelector('.my-element'); root.style.setProperty('--bg', 'black'); root.style.setProperty('--bg-text', 'grey'); element.style.setProperty('--bg-text', 'white');
Cela est d'autant plus intéressant car cela permet tout simplement de faire des effets plus poussés:
D'ailleurs, voici le lien d'une application qui expérimente cela: https://googlechrome.github.io/samples/css-custom-properties/index.html
Et nos préprocesseurs alors ?
En LESS, nous pouvons les utiliser, mais pas dans les fonctions LESS (en fait, il plus que conseillé d'utiliser l'un ou l'autre).Dans le cas de SASS, nous pouvons les mixer, en faisant une simple fonction CSS:
@function color($color-name) {
@return var(--color-#{$color-name});
}
Enjoy !
Commentaires
Enregistrer un commentaire