CSS Guidelines – Le bon plan – Pourquoi ces guidelines ?



CSS Guidelines – Le bon plan – Pourquoi ces guidelines ?

0 0


presentation-trello-css-guidelines

A quick presentation about Trello's CSS Guidelines

On Github bastientanesie / presentation-trello-css-guidelines

J'ai testé pour vous

CSS Guidelines

Enfin une solution CSS pratique ?

@BastienTanésie / Wixiweb

Le bon plan

Pourquoi ces guidelines ? Les guidelines Tools Components Javascript Mixins Utilities File structure Retour d'expérience

Pourquoi ces guidelines ?

  • Les CSS, c'est le bordel depuis le début
  • !important et inline, on en parle ?
  • Mélange classes et ids
  • CSS vs. JS
  • « Cette classe est encore utilisée ? »

Tools

Bob le Bricoleur à la rescousse du CSS

Tools

Use only imports, variables, and mixins (and only for vender-prefixed features) from CSS preprocessors
  • Lisibilité et simplicité du code
  • Vanilla CSS autant que faire se peut
  • Pas de fonctionnalités avancées des pré-processeurs Nesting abusif, boucles, etc.

Components

Moins de spécificité, c'est la clé du succès

Components

Use the .component-descendant-descendant pattern for components
  • Évite les cascades de règles
  • Améliore la maintenabilité
  • Utiliser des namespaces

Components

Pas de "sélecteur déscendant" :

.global-header {}

.global-header .logo {}

.global-header .logo img {}

Utilisation du namespacing :

.global-header {}

    .global-header-logo {}
    
        .global-header-logo-image {}

Components

Spécificité la plus basse possible,évite les !important et le style inline

  • Tous les sélecteurs doivent être des classes aucun ID ou élément
  • Pas d'underscores ni de camelCase ou autre joyeuseté
  • Minuscules, séparés par des tirets
  • Indentation en fonction de la descendance
  • États et pseudo-classes sur la même colonne

Components

— Modifiers —

Components : Modifiers

Use the .component-descendant.mod-modifier pattern for modifier classes

Besoin de transformer un élément dans un style particulier.

Exemple: un message en mode "erreur" ou "succès".

La base est commune (un bloc de message), mais change visuellement selon le but :Alerter, valider, informer, etc.

Components : Modifiers

<div class="alert-message mod-succes">Message de succès</div>
<div class="alert-message mod-error">Message d'erreur</div>
.alert-message {}
.alert-message.mod-success {}
.alert-message.mod-error {}

Components : Modifiers

Ne JAMAIS déclarer un modifier seul !

Un modifier est toujours rattaché à un composant.

Permet l'utilisation d'un modifier de même nom sur plusieurs composants.

Exemple : .mod-success sur un message et un bouton

Components : Modifiers

Si besoin d'écraser le style d'un déscendant,utiliser exceptionnelement le nesting.

.global-header-nav-item.mod-sign-up {
    background: hsl(120, 70%, 40%);
    color: #fff;
    
    .global-header-nav-item-text {
        font-weight: bold;
    }
}

Components

— States —

Pas forcément unis

Components : States

Use the .component-descendant.is-state pattern for state.Manipulate .is- classes in JavaScript (but not presentation classes).

Gestion des états spécifiques des composants.

Exemple: .is-loading, .is-disabled, .is-hidden, etc.

Séparation des états et de la présentation.

Components : States

Exemple du logo de Trello en mode "chargement" :

.global-header-logo-image {
    background: url("logo.png");
    height: 40px;
    width: 200px;
}

.global-header-logo-image.is-loading {
    background: url("logo-loading.gif");
}

En BEM : .global-header-logo-image--is-loading

  • — Dev : Tiens, cet élément a une classe .is-loading pour le status "en chargement", à toi de jouer !
  • — Designer : Cool, merci ! J'vais me débrouiller avec ça :)

Components : States

Chaque composant définit ses propres états

Jamais de .is- sans composant ciblé !

Donc.is-hidden { display: none; } =« Permit denied »

Components

— Media Queries —

Fini le casse-tête des break-points

Components : Media Queries

Use media query variables in your component.

Regrouper toutes les Media Queries dans un seul fichier.

Chaque Media Query (ou break-point) est stockée dans une variable.

Components : Media Queries

Déclaration des variables

@highdensity:  ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
               ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
               ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
               ~"only screen and (min-device-pixel-ratio: 1.5)";

@small:        ~"only screen and (max-width: 750px)";
@medium:       ~"only screen and (min-width: 751px) and (max-width: 900px)";
@large:        ~"only screen and (min-width: 901px) and (max-width: 1280px)";
@extra-large:  ~"only screen and (min-width: 1281px)";

@print:        ~"print";

Components : Media Queries

Utilisation des Media Queries dans les composants

/* Input */
@media @large { 
    .component-nav {}
}

/* Output */
@media only screen and (min-width: 901px) and (max-width: 1280px) {
    .component-nav {}
}

Components : Media Queries

On peut améliorer les perfs en regroupant/compressant toutes les Media Queries

avec css-mqpacker par exemple

npm install css-mqpacker --save-dev

Components

— Keeping It Encapsulated —

Spoiler : on ne parlera même pas de café…

Components : Encapsulate

Un composant dans un autre : compo-ception !

La règle

Un composant ne doit rien connaître des autres

Components : Encapsulate

Exemple : une liste et un bouton

Besoin : modifier la taille et la position du bouton

Ce qu'il ne faut pas faire

<div class="member-list">
    <div class="member-list-item">
        <p class="member-list-item-name">Pat</p>
        <a href="#" class="member-list-item-button button">Add</a>
    </div>
</div>
// components/member-list.less
.member-list-item-button {
    float: right;
    padding: 6px 10px;
}

Components : Encapsulate

Ce qu'il faut faire :

<div class="member-list">
    <div class="member-list-item">
        <p class="member-list-item-name">Gumby</p>
        <div class="member-list-item-action"><!-- conteneur pour la positon -->
            <a href="#" class="button mod-small">Add</a><!-- modifier pour la taille -->
        </div>
    </div>
</div>

Components : Encapsulate

Beaucoup de composants, c'est normal

Ne pas hésiter à éclater les gros composants en plusieurs plus petits

Beaucoup de modifiers et/ou de déscendants ? Il est temps de splitter !

Javascript

On ne mélange pas les torchons et les serviettes

Javascript

Separate style and behavior concerns by using .js- prefixed classes for behavior.

Séparation de la logique (JS) et de la présentation (CSS).

Rappel : ne jamais utiliser d'ID en JS

Javascript

Utiliser des noms de classes clairs, qui ont du sens :

.js-open-content-menu au lieu de .js-menu

Ne jamais avoir un .js- dans un fichier CSS

Mixins

Mixins

Prefix mixins with .m- and only use them sparingly for shared styles.

Pour des styles partagés entre plusieurs composants

Pour les vendor-prefixes, on peut utiliser autoprefixer à la place

// mixins.less
.m-list-divider () {
    border-bottom: 1px solid @light-gray-300;
}
// component.less
.component-descendent {
    .m-list-divider();
}

Utilities

Utilities

Prefix utility classes with .u-.

clearfix, alignement vertical, styles de texte, etc.

.u-truncate-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

Tout ça dans un seul et même fichier.

Pas de .u-float-left, directement dans le composant

File structure

Mais comment qu'on organise tout ça ?

File structure

@charset "UTF-8"
@import "normalize.css"
// Variables
@import "media-queries.less"
@import "colors.less"
@import "other-variables-like-fonts.less"
// Mixins
@import "mixins.less"
// Utils
@import "utils.less"
// Components
@import "component-1.less"
@import "component-2.less"
@import "component-3.less"
@import "component-4.less" // and so forth

File structure

Si c'est bien fait, pas besoin d'organiser les composants

Comprennez : l'ordre des composants n'a pas d'importance

En sortie : un seul fichier CSS

Facile à compresser avec un task-runner à la mode

Bonus

L'ordre des classes a son importance

component mod util state js

Retour d'expérience

Comme si j'avais vraiment de l'expérience…

— The End —

Merci

Sources

J'ai testé pour vous CSS Guidelines Enfin une solution CSS pratique ? @BastienTanésie / Wixiweb