On Github bastientanesie / presentation-trello-css-guidelines
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 {}
					Spécificité la plus basse possible,évite les !important et le style inline
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.
<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 {}
					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
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;
    }
}
					Gestion des états spécifiques des composants.
Exemple: .is-loading, .is-disabled, .is-hidden, etc.
Séparation des états et de la présentation.
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
Chaque composant définit ses propres états
Jamais de .is- sans composant ciblé !
Donc.is-hidden { display: none; } =« Permit denied »
Regrouper toutes les Media Queries dans un seul fichier.
Chaque Media Query (ou break-point) est stockée dans une variable.
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";
					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 {}
}
					On peut améliorer les perfs en regroupant/compressant toutes les Media Queries
avec css-mqpacker par exemple
npm install css-mqpacker --save-dev
Un composant dans un autre : compo-ception !
La règle
Un composant ne doit rien connaître des autres
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;
}
				    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>
				    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 !
Séparation de la logique (JS) et de la présentation (CSS).
Rappel : ne jamais utiliser d'ID en JS
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
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();
}
					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
@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
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
L'ordre des classes a son importance
component mod util state js
Comme si j'avais vraiment de l'expérience…
Sources