Tour d’horizon des 3 grandes méthodologies CSS
JS-STAR Paris | 28/09/2016 | @verekia
Jonathan Verrecchia
Jonathan Verrecchia
Jonathan Verrecchia
Jonathan Verrecchia
Jonathan Verrecchia
Créateur d'Initializr
Co-auteur d'un livre sur HTML5 chez Dunod
Ex-ingénieur Front-End chez Yelp
Freelance
Jonathan Verrecchia
Créateur d'Initializr
Co-auteur d'un livre sur HTML5 chez Dunod
Ex-ingénieur Front-End chez Yelp
Freelance
CSS : Résumé des épisodes précédents
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 :
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...)
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
A partir de 2012 :
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
A partir de 2012 : Changement de paradigme sur la sémantique CSS (.newsfeed ⇒ .blocklist)
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
A partir de 2012 : Changement de paradigme sur la sémantique CSS (.newsfeed ⇒ .blocklist), démocratisation des classes utilitaires (.float-right)
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
A partir de 2012 : Changement de paradigme sur la sémantique CSS (.newsfeed ⇒ .blocklist), démocratisation des classes utilitaires (.float-right) et apparition des conventions de nommage (.l-grid, .MyComponent-Child--modifier, .u-text-center)
CSS : Résumé des épisodes précédents
Avant 2010 : CSS pur (en général). Peu de conventions. 1 fichier CSS global, 1 fichier CSS par page spécifique pour économiser les requêtes HTTP.
A partir de 2011 : Avènement des préprocesseurs (imports de fichiers, variables, mixins réutilisables...) ⇒ Apparition d'une étape de build
A partir de 2012 : Changement de paradigme sur la sémantique CSS (.newsfeed ⇒ .blocklist), démocratisation des classes utilitaires (.float-right) et apparition des conventions de nommage (.l-grid, .MyComponent-Child--modifier, .u-text-center)
A partir de 2015 : PostCSS, CSS Modules, CSS-in-JS...
Le CSS en 2016...
Le CSS en 2016...
BEM
SUITCSS
OOCSS
Aphrodite
JSS
SMACSS
PostCSS
SASS
Less
Stylus
Atomic CSS
ITCSS
Tachyons
Basscss
CSS Modules
Radium
React Inline Styles
CSSX
Web Components
React Native for Web
Le plus gros problème du CSS
Le plus gros problème du CSS
Mutabilité + pas d'encapsulation = imprédictibilité
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
promo.css : .promo a { color: red }
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
promo.css : .promo a { color: red }
HTML : <a class="pretty-link">Lien</a>
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
promo.css : .promo a { color: red }
HTML : <a class="pretty-link">Lien</a>
Impossible de savoir si un pretty-link sera effectivement bleu.
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
promo.css : .promo a { color: red }
HTML : <a class="pretty-link">Lien</a>
Impossible de savoir si un pretty-link sera effectivement bleu.
C'est un peu comme si const num = 5 pouvait contenir d'autres valeurs que 5 selon l'endroit où vous la déclarez.
Mutabilité + pas d'encapsulation = imprédictibilité
global.css : .pretty-link { font-weight: bold; color: blue }
sidebar.css : .sidebar .pretty-link { color: green }
promo.css : .promo a { color: red }
HTML : <a class="pretty-link">Lien</a>
Impossible de savoir si un pretty-link sera effectivement bleu.
C'est un peu comme si const num = 5 pouvait contenir d'autres valeurs que 5 selon l'endroit où vous la déclarez. Ouch.
Les solutions : 3 grandes familles
CSS-in-...
CSS-in-CSS
CSS-in-HTML
CSS-in-JS
CSS-in-CSS
La méthodologie classique
CSS-in-CSS | Les préprocesseurs
CSS-in-CSS | Les préprocesseurs
CSS-in-CSS | Les préprocesseurs
CSS-in-CSS | Les préprocesseurs
CSS-in-CSS | Les préprocesseurs
Ça a donné naissance aux préprocesseurs. CSS devient du pseudo-CSS.
CSS-in-CSS | Les préprocesseurs
Ça a donné naissance aux préprocesseurs. CSS devient du pseudo-CSS.
CSS-in-CSS | Les préprocesseurs
Ça a donné naissance aux préprocesseurs. CSS devient du pseudo-CSS.
CSS-in-CSS | Méthodologie et nommage
CSS-in-CSS | Méthodologie et nommage
CSS-in-CSS | Méthodologie et nommage
SMACSS
SUIT
CSS
BEM
CSS-in-CSS | Méthodologie et nommage
SMACSS
SUIT
CSS
BEM
CSS-in-CSS | Méthodologie et nommage
.PrettyForm-Password--disabled
SMACSS
SUIT
CSS
BEM
CSS-in-CSS | Méthodologie et nommage
.PrettyForm-Password--disabled
SMACSS
SUIT
CSS
BEM
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-CSS | Ma stack idéale
CSS-in-HTML
La méthodologie moche mais efficace
CSS-in-HTML | 100% classes utilitaires
CSS-in-HTML | 100% classes utilitaires
<button class="fl-r bgc-primary m-b-20">Sign Up</button>
CSS-in-HTML | 100% classes utilitaires
<button class="fl-r bgc-primary m-b-20">Sign Up</button>
CSS-in-HTML | 100% classes utilitaires
<button class="fl-r bgc-primary m-b-20">Sign Up</button>
CSS-in-HTML | 100% classes utilitaires
<button class="fl-r bgc-primary m-b-20">Sign Up</button>
CSS-in-HTML | 100% classes utilitaires
<button class="fl-r bgc-primary m-b-20">Sign Up</button>
Les fichiers HTML s'alourdissent, mais aucun fichier CSS supplémentaire n'est nécessaire. Le développement de pages en CSS-in-HTML est très rapide.
CSS-in-HTML | Tachyons et Basscss
CSS-in-HTML | Tachyons et Basscss
CSS-in-HTML | Tachyons et Basscss
CSS-in-HTML | Atomic CSS
CSS-in-HTML | Atomic CSS
CSS-in-HTML | Atomic CSS
CSS-in-HTML | Atomic CSS
<div class="Bgc(mycolor) Bgc(#0280ae):h Mend(0) My(0) D(ib)--sm">
CSS-in-HTML | Atomic CSS
<div class="Bgc(mycolor) Bgc(#0280ae):h Mend(0) My(0) D(ib)--sm">
Ces caractères spéciaux dans les sélecteurs sont valides,
mais doivent être échappés par un \ dans le CSS.
CSS-in-HTML | Atomic CSS
<div class="Bgc(mycolor) Bgc(#0280ae):h Mend(0) My(0) D(ib)--sm">
Ces caractères spéciaux dans les sélecteurs sont valides,
mais doivent être échappés par un \ dans le CSS.
Suivez Thierry Koblentz (@thierrykoblentz)
CSS-in-HTML | ZeroCSS
CSS-in-HTML | ZeroCSS
ZeroCSS est mon générateur de classes utilitaires.
CSS-in-HTML | ZeroCSS
ZeroCSS est mon générateur de classes utilitaires.
Syntaxe similaire à Atomic CSS, en plus légère, et personnalisable :
bgc(primary) bgc(primarydark):h p(20) fl(r)[md-up] w(100%)[sm-down]
CSS-in-HTML | ZeroCSS
ZeroCSS est mon générateur de classes utilitaires.
Syntaxe similaire à Atomic CSS, en plus légère, et personnalisable :
bgc(primary) bgc(primarydark):h p(20) fl(r)[md-up] w(100%)[sm-down]
Moins perfectionné qu'Atomic CSS, mais plus intuitif et léger.
CSS-in-HTML | ZeroCSS
ZeroCSS est mon générateur de classes utilitaires.
Syntaxe similaire à Atomic CSS, en plus légère, et personnalisable :
bgc(primary) bgc(primarydark):h p(20) fl(r)[md-up] w(100%)[sm-down]
Moins perfectionné qu'Atomic CSS, mais plus intuitif et léger.
github.com/verekia/zerocss
CSS-in-HTML | Composants réutilisables
CSS-in-HTML | Composants réutilisables
components.yaml – Que votre serveur web va lire et passer aux templates
primaryButton: dis(ib) bgc(primary) bgc(primarydarker):h
CSS-in-HTML | Composants réutilisables
components.yaml – Que votre serveur web va lire et passer aux templates
primaryButton: dis(ib) bgc(primary) bgc(primarydarker):h
button.mustache
<button class="{{ components.primaryButton }} m(b,20)">
CSS-in-HTML | Composants réutilisables
components.yaml – Que votre serveur web va lire et passer aux templates
primaryButton: dis(ib) bgc(primary) bgc(primarydarker):h
button.mustache
<button class="{{ components.primaryButton }} m(b,20)">
Sortie :
<button class="dis(ib) bgc(primary) bgc(primarydarker):h m(b,20)">
CSS-in-JS
La méthodologie la plus prometteuse
CSS-in-JS | Préprocesseurs vs. "vrais" langages
Pourquoi a-t-on inventé un nouveau langage de programmation comme SASS, alors qu'il y a déjà plein de langages qui pourraient générer du CSS?
CSS-in-JS | Préprocesseurs vs. "vrais" langages
Pourquoi a-t-on inventé un nouveau langage de programmation comme SASS, alors qu'il y a déjà plein de langages qui pourraient générer du CSS?
Les préprocesseurs ne font qu'une seule chose c'est générer une string de CSS. Peu importe si la string est générée en SASS, Python, JS ou Ruby, au final, c'est juste une chaîne de caractères pour le navigateur du client.
CSS-in-JS | Préprocesseurs vs. "vrais" langages
Pourquoi a-t-on inventé un nouveau langage de programmation comme SASS, alors qu'il y a déjà plein de langages qui pourraient générer du CSS?
Les préprocesseurs ne font qu'une seule chose c'est générer une string de CSS. Peu importe si la string est générée en SASS, Python, JS ou Ruby, au final, c'est juste une chaîne de caractères pour le navigateur du client.
JavaScript a l'avantage de fonctionner côté client et d'être connu par la plupart des développeurs CSS, c'est donc naturellement le langage de choix.
CSS-in-JS | Préprocesseurs vs. "vrais" langages
Pourquoi a-t-on inventé un nouveau langage de programmation comme SASS, alors qu'il y a déjà plein de langages qui pourraient générer du CSS?
Les préprocesseurs ne font qu'une seule chose c'est générer une string de CSS. Peu importe si la string est générée en SASS, Python, JS ou Ruby, au final, c'est juste une chaîne de caractères pour le navigateur du client.
JavaScript a l'avantage de fonctionner côté client et d'être connu par la plupart des développeurs CSS, c'est donc naturellement le langage de choix.
JavaScript a toutes les fonctionnalités de programmation qu'a SASS, avec les tests unitaires, le linting, et tout l'écosystème Node / NPM (npm -i -S color).
CSS-in-JS | Les styles inline React
CSS-in-JS | Les styles inline React
L'idée initiale pour une encapsulation simple :
CSS-in-JS | Les styles inline React
L'idée initiale pour une encapsulation simple :
const styles = { button: { color: blue } };
<div style={ styles.button }>
CSS-in-JS | Les styles inline React
L'idée initiale pour une encapsulation simple :
const styles = { button: { color: blue } };
<div style={ styles.button }>
Ça marche mais...
CSS-in-JS | Les styles inline React
L'idée initiale pour une encapsulation simple :
const styles = { button: { color: blue } };
<div style={ styles.button }>
Ça marche mais...
CSS-in-JS | Les styles inline React
L'idée initiale pour une encapsulation simple :
const styles = { button: { color: blue } };
<div style={ styles.button }>
Ça marche mais...
speakerdeck.com/vjeux/react-css-in-js
CSS-in-JS | JSS et Aphrodite
CSS-in-JS | JSS et Aphrodite
2 librairies similaires qui me semblent les plus prometteuses.
CSS-in-JS | JSS et Aphrodite
2 librairies similaires qui me semblent les plus prometteuses.
JSS semble avoir la préférence de l'équipe React. Dan Abramov, auteur de Redux, membre de la core team React a travaillé sur react-jss.
CSS-in-JS | JSS et Aphrodite
CSS-in-JS | JSS et Aphrodite
2 librairies similaires qui me semblent les plus prometteuses.
JSS semble avoir la préférence de l'équipe React. Dan Abramov, auteur de Redux, membre de la core team React a travaillé sur react-jss.
Aphrodite a été créé par Khan Academy.
Les 2 supportent les pseudo-classes, media queries, le rendering côté serveur.
CSS-in-JS | JSS et Aphrodite
2 librairies similaires qui me semblent les plus prometteuses.
JSS semble avoir la préférence de l'équipe React. Dan Abramov, auteur de Redux, membre de la core team React a travaillé sur react-jss.
Aphrodite a été créé par Khan Academy.
Les 2 supportent les pseudo-classes, media queries, le rendering côté serveur.
Le binding entre élément HTML et styles CSS ne se fait plus par des classes nommées à la main. Des classes uniques sont générées.
CSS-in-JS | JSS et Aphrodite
const styles = {
prettyLink: {
color: 'blue',
},
};
CSS-in-JS | JSS et Aphrodite
const styles = {
prettyLink: {
color: 'blue',
},
};
const classes = jss.createStyleSheet(styles).classes;
console.log(`<a class="${classes.prettyLink}">Lien</a>`);
console.log(jss.sheets.toString());
CSS-in-JS | JSS et Aphrodite
const styles = {
prettyLink: {
color: 'blue',
},
};
const classes = jss.createStyleSheet(styles).classes;
console.log(`<a class="${classes.prettyLink}">Lien</a>`);
console.log(jss.sheets.toString());
// <a class="prettyLink-1289375814">Lien</a>
// prettyLink-1289375814 { color: blue }
CSS-in-JS (presque) | CSS Modules
CSS-in-JS (presque) | CSS Modules
Même approche de génération de classes uniques, mais les styles se déclarent dans des fichiers CSS. (button.css, qui va avec button.jsx par exemple).
CSS-in-JS (presque) | CSS Modules
Même approche de génération de classes uniques, mais les styles se déclarent dans des fichiers CSS. (button.css, qui va avec button.jsx par exemple).
Possibilité d'intégrer des librairies CSS existantes avec un peu de travail. Impossible avec JSS et Aphrodite.
CSS-in-JS (presque) | CSS Modules
Même approche de génération de classes uniques, mais les styles se déclarent dans des fichiers CSS. (button.css, qui va avec button.jsx par exemple).
Possibilité d'intégrer des librairies CSS existantes avec un peu de travail. Impossible avec JSS et Aphrodite.
Présente les faiblesses de langage du CSS comparé à JavaScript.
CSS-in-JS (presque) | CSS Modules
Même approche de génération de classes uniques, mais les styles se déclarent dans des fichiers CSS. (button.css, qui va avec button.jsx par exemple).
Possibilité d'intégrer des librairies CSS existantes avec un peu de travail. Impossible avec JSS et Aphrodite.
Présente les faiblesses de langage du CSS comparé à JavaScript.
S'intègre facilement avec Webpack pour le côté client.
CSS-in-JS (presque) | CSS Modules
Même approche de génération de classes uniques, mais les styles se déclarent dans des fichiers CSS. (button.css, qui va avec button.jsx par exemple).
Possibilité d'intégrer des librairies CSS existantes avec un peu de travail. Impossible avec JSS et Aphrodite.
Présente les faiblesses de langage du CSS comparé à JavaScript.
S'intègre facilement avec Webpack pour le côté client.
Plugin PostCSS pour le rendering côté serveur qui renvoie un JSON de mapping entre les classes CSS normales et les classes CSS hashées.
CSS-in-JS | Rendering côté serveur
CSS-in-JS | Rendering côté serveur
Vital pour le SEO, et pour un chargement initial rapide.
CSS-in-JS | Rendering côté serveur
Vital pour le SEO, et pour un chargement initial rapide.
Côté client c'est facile, les libraires connectent automatiquement les styles aux éléments HTML.
CSS-in-JS | Rendering côté serveur
Vital pour le SEO, et pour un chargement initial rapide.
Côté client c'est facile, les libraires connectent automatiquement les styles aux éléments HTML.
Côté serveur, si votre backend est en JS, l'intégration est simple. Sinon, vous pouvez générer les classes uniques au build, mais vous devrez faire de la plomberie et connecter ces classes avec vos templates vous-mêmes.
CSS-in-JS | Rendering côté serveur
Vital pour le SEO, et pour un chargement initial rapide.
Côté client c'est facile, les libraires connectent automatiquement les styles aux éléments HTML.
Côté serveur, si votre backend est en JS, l'intégration est simple. Sinon, vous pouvez générer les classes uniques au build, mais vous devrez faire de la plomberie et connecter ces classes avec vos templates vous-mêmes.
header.mustache
<button class="{{ myclasses.primaryButton }}">
CSS-in-JS | Des tonnes de librairies
github.com/MicheleBertoli/css-in-js
CSSX, Radium (React-only), babel-plugin-css-in-js, React Native for Web...
Et les Web Components ?
Et les Web Components ?
Permet entre autres les Custom Elements et l'encapsulation du CSS.
Et les Web Components ?
Permet entre autres les Custom Elements et l'encapsulation du CSS.
Mauvais support navigateur (Polymer répare le support sur IE11+)
Et les Web Components ?
Permet entre autres les Custom Elements et l'encapsulation du CSS.
Mauvais support navigateur (Polymer répare le support sur IE11+)
Pas / peu SEO-friendly
Et les Web Components ?
Permet entre autres les Custom Elements et l'encapsulation du CSS.
Mauvais support navigateur (Polymer répare le support sur IE11+)
Pas / peu SEO-friendly
React résout beaucoup des problématiques soulevées par Web Components avec une implémentation qui fonctionne partout dès aujourd'hui. L'engouement pour Web Components s'essouffle donc un peu.
Et les Web Components ?
Permet entre autres les Custom Elements et l'encapsulation du CSS.
Mauvais support navigateur (Polymer répare le support sur IE11+)
Pas / peu SEO-friendly
React résout beaucoup des problématiques soulevées par Web Components avec une implémentation qui fonctionne partout dès aujourd'hui. L'engouement pour Web Components s'essouffle donc un peu.
A reconsidérer lorsqu'il y aura un meilleur support navigateur.
Et Bootstrap dans tout ça ?
Et Bootstrap dans tout ça ?
Bootstrap et Foundation peuvent s'utiliser avec les 3 méthodologies.
Et Bootstrap dans tout ça ?
Bootstrap et Foundation peuvent s'utiliser avec les 3 méthodologies.
CSS-in-CSS apportera plus de flexibilité pour pouvoir modifier les variables SASS directement. Avec les 2 autres méthodes, vous pouvez toujours utiliser Bootstrap / Foundation compilés en CSS, puis écraser les styles que vous voulez, ou bien ajouter SASS à votre build seulement pour Bootstrap.
Comment choisir votre méthodologie ?
Comment choisir votre méthodologie ?
Le choix le plus raisonnable en équipe avec des développeurs qui ne sont pas particulièrements experts du CSS : CSS-in-CSS (SASS + PostCSS)
Comment choisir votre méthodologie ?
Le choix le plus raisonnable en équipe avec des développeurs qui ne sont pas particulièrements experts du CSS : CSS-in-CSS (SASS + PostCSS)
Pour un petit projet rapide : CSS-in-HTML (Basscss, Tachyons, ZeroCSS)
Comment choisir votre méthodologie ?
Le choix le plus raisonnable en équipe avec des développeurs qui ne sont pas particulièrements experts du CSS : CSS-in-CSS (SASS + PostCSS)
Pour un petit projet rapide : CSS-in-HTML (Basscss, Tachyons, ZeroCSS)
Pour un projet au sein d'une équipe à l'aise en JS, particulièrement avec React : Essayez CSS-in-JS (territoire encore vierge, sans best-practices établies ni librairie dominante).
Merci !
JS-STAR Paris | 28/09/2016 | @verekia