Sass blitz in richie

Analyse

  • La base CSS actuellement en vigueur repose sur Bootstrap4;
  • L’intégration fournie dans les templates utilisent la nomenclature BEM;
  • Les feuilles de styles sont rédigées en Sass;

Bootstrap4

Bootstrap depuis sa version 4 fournit maintenant ses sources avec le format Sass.

Comme la majorité des frameworks CSS son optique de base était de prototyper rapidement des interfaces.

Historiquement il a été conçu pour harmoniser et faciliter la mise en forme des nombreuses interfaces et sites suivant le styleguide de Twitter.

BEM

BEM est une méthodologie, son but étant d’éviter les conflits et l’héritage impromptu en spécialisant chaque classe dans ce qui est appelé un bloc (block).

Extend

@extend est une directive Sass qui permet d’étendre un sélécteur existant depuis un autre sélécteur.

On introduit un extend depuis un sélécteur B pour hériter des propriétés d’un sélécteur A, le sélécteur B peut ensuite ajouter ses propres propriétés supplémentaires.

Son but initial était de factoriser les règles CSS pour éviter de se répéter et diminuer la taille finale d’une feuille CSS.

Problématiques

richie et BEM

L’usage actuel de BEM dans richie va au delà des spécifications de base, car on y spécialise toujours les classes par type de contenu au lieu de spécialiser simplement par composant.

Par exemple, alors que l’on pourrait avoir un composant .button qui serait partagé par tout les contenus, dans richie il y aura un bloc .article-list__button pour une liste d’articles d’un blog, .article-detail__button pour les articles d’un blog, un bloc .page-detail__button pour une page CMS, etc..

En suivant la méthodologie BEM un bouton avec un élément d’icône nécessiterait une classe .button__icon et pour une variante du bouton en rouge une classe .button--red.

Avec richie cela nécessite les classes .article-list__button__icon, .article-detail__button__icon et .page-detail__button__icon pour l’icône. Et pour la variante rouge les classes .article-list__button--red, .article-detail__button--red et .page-detail__button--red.

BEM, Bootstrap4 et extend

On ne peut pas mélanger l’usage des classes des composants Bootstrap4 et la méthodologie BEM car ce serait improductif voire pénalisant.

Bootstrap4 est basé sur la méthodologie Object Oriented ce qui fait qu’il produit des noms de classes par composant et qu’il utilise des classes descendantes et de modificateurs en cascade.

Pour convenir à BEM, l’approche convenant le mieux aurait été d’hériter des composants de Bootstrap4 par des mixins dans les classes de blocs, éléments et modificateurs.

Mais Bootstrap n’est couvert qu’à 20% en mixin, concrètement leur système de grille est le seul couvert correctement.

Il faut alors se tourner vers l’héritage via la directive extend mais cette technique pose alors d’autres soucis :

  • Elle provoque l’héritage de l’intégralité des règles de son ancêtre donc aussi ses descendants et ses modificateurs. Et ceci pour chaque règle qui va en hériter, tout cela peut accumuler un nombre de sélécteur significatif;
  • On ne peut étendre qu’un sélécteur simple, on ne peut pas étendre un sélécteur qui spécifie un descendants ou un modificateur tel que .button .icon;
  • De fait comme Bootstrap ne spécialise pas ses noms de classes, un nom de classe d’un descendant ou modificateur d’un composant peut être réutilisé plusieurs fois dans différents composants. Il est donc impossible d’étendre les règles des descendants et modificateur d’un composant précis (ce sera toujours le dernier existant qui sera utilisé);
  • On devra alors recopier les propriétés des éléments ou de modificateurs pour chaque bloc BEM qui veut hériter d’un composant précis de Bootstrap.

Exemple Sass

// Un exemple de composant de bouton
.button{
    border: 2px solid black;

    .icon{
        font-family: icomoon;
    }

    .red{
        background: red;
    }

    .bigger{
        font-size: 3rem;
        border: 4px solid black;
    }
}

// Exemples d'héritage avec BEM et la spécialisation par contenu
// de richie
.org-detail__badge{
    @extend .button;
    font-size: 0.5em;
}

.course-detail__badge{
    @extend .button;
}

.subject-detail__badge{
    @extend .button;
}

.person-detail__badge{
    @extend .button;

    // Ceci est impossible
    // &__icon{
    //  @extend .button .icon;
    // }
    &__icon{
        /* Il faut reproduire ici la règle de l'élément '.icon' */
    }
}

Exemple CSS

.button, .person-detail__badge,
.subject-detail__badge,
.course-detail__badge,
.org-detail__badge {
    border: 2px solid black;
}
.button .icon,
.person-detail__badge .icon,
.subject-detail__badge .icon,
.course-detail__badge .icon,
.org-detail__badge .icon {
    font-family: icomoon;
}
.button .red,
.person-detail__badge .red,
.subject-detail__badge .red,
.course-detail__badge .red,
.org-detail__badge .red {
    background: red;
}
.button .bigger, .person-detail__badge .bigger, .subject-detail__badge .bigger, .course-detail__badge .bigger, .org-detail__badge .bigger {
    font-size: 3rem;
    border: 4px solid black;
}

.org-detail__badge {
    font-size: 0.5em;
}

Exploitation de richie

Les templates de richie étant rédigés avec la méthodologie BEM et sa spécialisation par contenu, un utilisateur ne peut appliquer simplement un des thèmes Bootstrap car ils contiennent rarement des mixins adéquates, surchargent à leur manière des composants Bootstrap et rajoutent parfois leur propres blocs, éléments et modificateurs.

Récupérer les variables du thème ne suffira que pour les quelques thèmes très basiques ce qui limite drastiquement les possibilités de différenciations entre les sites fonctionnant avec richie.

Composants Bootstrap4

Les composants qui nécessite du Javascript tel que l’accordéon, les alertes, dropdown, etc.. requiert tous au moins jQuery.

Ce dernier pourrait poser soucis dans le cadre de richie et de son frontend avec react, si cela s’avère alors beaucoup de composants Bootstrap seront inutilisables.

Conclusion

  • Si l’on reste sur l’usage actuel il faudra abandonner l’emploi de nombreux composants de Bootstrap, il faudra aussi recopier quelques fois du code de Bootstrap pour certains éléments et modificateurs de composants.
  • Le CSS produit pourrait être plus conséquent et moins performant qu’il ne le devrait;
  • La modification cosmétique de richie par les utilisateurs pourrait être compliqué;