? Bootstrap est une régression pour un développement Front-end de qualité (archive)

Source originale du contenu

Pourquoi je n'utilise pas Bootstrap ? Cela peut sembler une « évolution » de nos méthodes de travail Front-end, mais gare au loup et attention de ne pas tomber dans un travers que le W3C tente d'enrayer au fur et à mesure des évolutions HTML et CSS.

Commençons par le commencement. Qu'est-ce que Bootstrap ? Comme pleins d'autres « Librairie » ou « Framework » CSS dans la même veine, Bootstrap est un outil permettant d'augmenter la productivité des développeurs Front-end le maîtrisant, dans le but de fournir le plus rapidement possible un rendu visuel ergonomique et si possible responsive.

Mon problème ne vient pas tant de sa finalité qui est louable, mais belle et bien de la mise en œuvre technique qui permet d'atteindre cette finalité. Pour être concis avant de développer : Bootstrap est une régression pour un travail Front-end de qualité.

Je ne compte persuader personne, et à défaut de convaincre, je vais au moins vous expliquer mon point de vue.

Les deux approches possibles pour de l'intégration Front-end

L'approche Sémantique/Visuelle (ou celle du W3C)

Cette approche considère que dans un fichier HTML, les balises doivent avoir du sens et être complétées (que ce soit par leurs genres, leurs noms, leurs ids ou leurs classes) de manière sémantique de façon à donner du sens au document.

Exemple

Si j'ai deux éléments qui se suivent : le premier pourrait porter l'attribut class="main" et le second l'attribut class="aside".

L'attribut class est donc dans cette approche une extension de l'attribut id (mais en version multiple) et le HTML garde un unique rôle : le rôle sémantique.

L'approche « Tout en un » (ou celle de Bootstrap & cie)

Cette approche considère que dans un fichier HTML, les balises doivent représenter un visuel et être complétées de manière à laisser transparaître rapidement le résultat visuel.

Exemple

Si j'ai deux éléments qui se suivent : le premier pourrait porter l'attribut class="left" et le second l'attribut class="right".

L'attribut class est donc dans cette approche une extension de l'attribut style (mais une sorte de raccourci) où il n'est pas nécessaire de lister les directives CSS en inline mais dans un fichier CSS séparé.

Comparaison de code des deux approches

Pour les plus curieux, voici techniquement la différence entres les codes :

Sémantique et visuel séparé

HTML :

<header>
    <h1>Le titre</h1>
    <nav>
        <ul>
            <li>menu</li>
            <li>menu</li>
            <li>menu</li>
            <li>menu</li>
        </ul>
    </nav>
</header>
<section>
    <article>
        <p>Le contenu<br>
        Le contenu<br>
        Le contenu</p>
    </article>
    <aside>Les à cotés</aside>
</section>

CSS :

/* Entrer le padding dans le calcul interne */
h1,
nav,
article,
aside {
    box-sizing: border-box;
}

/* Mettre le titre en gras */
h1 {
    font-weight: bold;   
}

/* Centrer les textes du menu */
nav {
    text-align: center;
}

/* Retrait du comportement de liste standard */
nav ul {
    padding-left: 0;
}
nav li {
    list-style-type: none;
}

/* À partir d'une tablette */
@media (min-width: 768px) {

    /* Empêcher les écoulements de flottants */
    header:after,
    section:after {
        content: "";
        display: block;
        clear: both;
    }

    /* Flotter à gauche en 50% */
    h1,
    aside {
        float: left;
        width: 50%;
    }

    /* Flotter à droite en 50% */
    h1,
    article {
        float: right;
        width: 50%;
    }

    /* Remettre les menus en alignement standard */
    nav {
        text-align: left;
    }

    /* Mettre le menu en ligne */
    nav li {
        display: inline-block;
    }

    /* Placer le titre à droite */
    h1 {
        text-align: right;
    }

}

Rendu

  • menu
  • menu
  • menu
  • menu

Le contenu
Le contenu
Le contenu

Les à coté

Note : vous pouvez rétrécir votre fenêtre sur périphérique desktop pour voir le résultat mobile.

Framework CSS comme Bootstrap

HTML :

<header class="container">
    <div class="row">
        <h1 class="col-sm-6 col-sm-push-6 text-right-sm">
            <strong>Le titre</strong>
        </h1>
        <nav class="col-sm-6 col-sm-pull-6 text-center-xs text-left-sm">
            <div class="navbar-collapse collapse in">
                <ul class="nav navbar-nav">
                    <li>Menu</li>
                    <li>Menu</li>
                    <li>Menu</li>
                    <li>Menu</li>
                </ul>
            </div>
        </nav>
    </div>
</header>

<section class="container">
    <div class="row">
        <article class="col-sm-6 col-sm-push-6">
            <p>Le contenu<br>
               Le contenu<br>
               Le contenu</p>
        </article>
        <aside class="col-sm-6 col-sm-pull-6">Les à coté</aside>
    </div>
</section>

CSS :

<!-- État de boite noire, ça marche tel que la doc l'explique -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
/* Parce que Bootstrap ne réalise pas tout ce que 
l'on souhaite faire, on surcharge ensuite avec sa 
propre CSS en essayant de conserver 
la philosophie Bootstrap (pas simple) */

/* Comportement par défaut */,

.text-center-sm,
.text-center-md,
.text-center-lg,
.text-right-sm,
.text-right-md,
.text-right-lg { 
    text-align: inherit; 
}

/* Style par défaut */
.text-center-xs { 
    text-align: center; 
}
.text-right-xs { 
    text-align: right;
}

/* Style pour tablette */
@media (min-width: 768px) {
    .text-center-sm, 
    .text-center-xs { 
        text-align: center; 
    }
    .text-right-sm, 
    .text-right-xs { 
        text-align: right; 
    }
}

/* Style pour desktop */
@media (min-width: 992px) {
    .text-center-md, 
    .text-center-sm, 
    .text-center-xs { 
        text-align: center; 
    }
    .text-right-md, 
    .text-right-sm, 
    .text-right-xs { 
        text-align: right;
    }
}

/* Style pour grand desktop */
@media (min-width: 1200px) {
    .text-center-lg, 
    .text-center-md, 
    .text-center-sm, 
    .text-center-xs {
        text-align: center;
    }
    .text-right-lg, 
    .text-right-md, 
    .text-right-sm, 
    .text-right-xs {
        text-align: right;
    }
}

Note : une autre approche est de dupliquer un objet que Bootstrap ne saurait pas facilement afficher dans des états différents en fonction de la taille du périphérique afin de n'en afficher qu'un des deux à la fois. Ce qui créé du contenu dupliqué.

Rendu

menu menu menu menu

Le contenu
Le contenu
Le contenu

Les à coté

Note : vous pouvez rétrécir votre fenêtre sur périphérique desktop pour voir le résultat mobile.

Pourquoi l'approche sémantique est la meilleure (selon moi)

La raison historique ; de la séparation du fond et de la forme

Le W3C améliore les normes de structures HTML dans un but de séparation de la structure et du rendu. Voyons ça plus en détail :

D'abord HTML

Le HTML dans ses débuts embarquait des balises permettant de créer du fond (ou de structurer) tel que <div>, <span>, <table>, etc. et des balises permettant de créer de la forme (ou du rendu) tel que <font>, <i>, <b>, <center>, etc. Les deux étaient mélangés et c'est bien dans le fichier HTML, au travers de sa structure que l'on décidait qu'un texte devrait être rouge, centré et avoir une taille de 20 pixel.

Puis le xHTML

Une évolution logique a donc été de supprimer (ou déprécier) les balises porteuses d'un rendu visuel et de leur préférer un sens sémantique (tout en accordant une grande importance au CSS pour l'habillage). Ainsi un texte centré ou rouge se créé via une feuille CSS et on ne considère plus un texte important comme <b> (bold) mais plutôt ayant un sens <strong> (fort). C'est au développeur de choisir si finalement <strong> n'a pas plutôt un rendu italique et souligné via CSS.

Il y a donc une volonté du Web de séparer la structure et le rendu. Ce que je trouve assez logique.

On continue avec le HTML5

Toujours dans ce soucis de structure sémantique, les balises en elles-mêmes se voit rajoutée du sens et c'est pour cela que <header>, <footer>, <section>, <article>, <aside>, <figure>... font leur apparition.

Cela signifie que l'approche de Bootstrap prend le contre-pied de cette idée de séparation et instaure selon moi une approche plus liée qui n'est pas en accord avec la philosophie que je partage avec le W3C.

Les raisons techniques

La taille du fichier HTML généré

Ajouter des classes à outrance pour habiller visuellement sa structure HTML surcharge anormalement le DOM d'au moins trois manières :

Cela défère le poids de la CSS vers le HTML. Or, autant les fichiers CSS peuvent être mis en cache, autant la structure HTML peut difficilement l'être étant donné sa nature changeante en fonction du contrôleur qui la génère.

La surcharge CSS

Bootstrap n'est pas négligeable en taille. Cela impose un pré-chargement plus lourds au premier chargement de page (en supposant qu'ensuite le fichier soit mis en cache). De manière assez amusante, plus Bootstrap "supporte" des périphériques petits avec de faibles débits à l'utilisation (ajout de fichiers CSS et JS), plus il est lourd en poids...

La maîtrise de l'outil

L'avantage offert par Bootstrap est perdu dès l'instant ou l'outil est utilisé par des personnes ne le connaissant pas (rapidité d'intégration). Pire encore, cela expose l'intégration par de multiples personnes à mélanger l'approche Bootstrap à une approche sémantique.

Maintenance de code et changement de design

La structure étant intimement liée au Framework Bootstrap et au visuel soumis, le code HTML est bon à revoir dans son architecture pour un changement de design. La structure étant liée aux contrôleurs, car créée par eux, c'est le Back-end qui se retrouve impacté par un changement de design là ou seulement les CSS et les JS auraient du bouger (sans que le Back soit touché par du changement de design).

Ne pas rendre service au Front-end apprenant

L'approche « tout en un » masque le plus important : les mécanismes de fonctionnement des classes en elles-mêmes. Pourquoi -pour réaliser telles actions- elles utilisent ces attributs précisément ? Si cet état de boîte noire peut s'avérer intéressant pour des débutants et un gain de temps pour les experts : cela maintient l'écart entre les deux. Et, les seuls apprenant réellement à utiliser les nouveautés du CSS en comprenant les mécanismes sous-jacent sont ceux qui maintiennent Bootstrap (ou équivalent) ou ceux qui ne l'utilisent pas.

Un problème de SEO ou de performance ?

Dupliquer du contenu de manière identique dans le DOM dans le seul but de l'afficher à deux endroits différents de la grille Bootstrap créer du contenu dupliqué au sein d'une même page. Bien entendu, on peut éviter cela en laissant dans le DOM source le code destiné au mobile et en dupliquant en JavaScript celui-ci pour l'afficher sur desktop en sacrifiant un peu de ressource JavaScript et en masquant tant bien que mal le phénomène de FOUC.

Pourquoi utiliser Bootstrap alors ?

À utiliser pour :

À ne pas utiliser pour :

Semantic UI

Bonne idée : Pour ma part, quitte à devoir être HTML-driven et non pas Stylesheet-driven pour l'habillage CSS, autant utiliser des Framework tel que Semantic UI qui au moins garde la philosophie du composant qui explique ce qu'il fait et non ce à quoi il ressemble.

Voir le projet Semantic UI

Mélanger les deux approches pour en garder les avantages ?

Si l'on extrait les problèmes majeurs en considérant que nos ressources seront formées à utiliser Bootstrap nous nous retrouvons avec les deux points suivants.

La lourdeur de la librairie

Que ce soit pour Bootstrap ou pour une autre librairie, le premier chargement sera laborieux (avant que le fichier n'ai été téléchargé une fois et mis en cache). On peut palier à ce problème en utilisant une version du script hébergé sur des serveurs comme c'est le cas pour jQuery par exemple. Ainsi pour Bootstrap, on peut se faire servir par http://www.bootstrapcdn.com/. L'avantage est que tous les sites utilisant le chargement par CDN Bootsrap participe à mettre en cache pour vous le fichier. Cela signifie que ce n'est plus nécessairement votre première page ouverte qui ralentira le chargement du visiteur mais peut-être celle d'un autre site.

Remettre les classes « tout en un » de nouveau dans la CSS

Finalement, ce qu'il nous faudrait pour résoudre notre soucis et remettre la sémantique à l'ordre du jour, c'est d'adresser dans la feuille CSS (et non dans la page HTML elle-même) notre suite de classe. Si nous pouvions par exemple transformer ceci :

<div class="clr">
    <div class="left hidden boxsizing w50">
        Le logo
    </div>
</div>

en ceci

<div class="header">
    <div class="logo">
        Le logo
    </div>
</div>
/* Fichier complet type Bootstrap */

.header {
    .clr;
}
.logo {
    .left; 
    .hidden; 
    .boxsizing; 
    .w50;
}

le tour serait joué.

C'est exactement ce que permettent des approches comme SASS ou LESS. Elles permettent d'écrire de manière intuitive et non redondante des suites de sélecteurs CSS pour au final générer le fichier CSS qui va bien. Vous pouvez lire l'article « Utilisation optimisée de Framework CSS comme Bootstrap avec Less » pour comprendre comment cela fonctionne et de cette manière vous pourrez remplir vos classes HTML de manière sémantique tout en conservant vos habitudes d'intégration avec Bootstrap par exemple.

Mon retour rapide sur l'utilisation Bootstrap

Je trouve que les types de sites réalisés avec Bootstrap se ressemble tous et qu'il devient difficile de faire quelque chose s'en éloignant sans finalement perdre du temps. Bootstrap devient ici plus contraignant pour la patte créative également et on en vient parfois même à blâmer les agences de création digital car leurs créations ne sont pas « compliant » Bootstrap.

Pour exemple voici des variations de design pour un HTML identique en CSS-driven :

Site de Nicolas Hoffmann

et la même chose pour un HTML identique avec Bootstrap

Template pour documentation JSDoc

CQFD.