Bootstrap est une régression pour un développement Front-end de qualité

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 « Bibliothèque » 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 bel et bien de la mise en œuvre technique qui permet d'atteindre cette finalité. Pour être concis avant de développer : l'utilisation faites de 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 leur genre, leur nom, leur id ou leur classe) 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 de structure sémantique (que ce soit pour les moteurs de recherche mais également pour les développeurs ; qu'ils s'y connaissent ou non en design).

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="column-sm-4 text-left" et le second l'attribut class="column-sm-8 text-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 ligne mais dans un fichier CSS séparé.

Note : le texte sera toujours à gauche pour la première partie et toujours à droite pour la seconde quelque soit le contexte dans lequel ces portions de HTML se retrouverons.

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é. Cela, en plus d'être un problème SEO, pose un problème de maintenance.

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 (à noter que <i> et <b> n'ont pas été remplacées comme on le pense trop souvent).

Il y a donc une volonté du W3C de séparer la structure et le rendu.

On continue avec le HTML5

Toujours dans ce soucis de structure sémantique, les balises en elles-mêmes se voient rajoutées du sens et c'est pour cela que <header>, <footer>, <section>, <article>, <aside>, <figure>, etc. 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 :

  • Obligation d'imbriquer des éléments pour qu'ils fonctionnent tels que Bootstrap l'a prévu.
  • Multiplication du nombre de classes dans l'attribut class.
  • Duplication de contenu pour afficher / masquer simplement en fonction de la taille du périphérique.

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. Heureusement le transfert gzip allège ce soucis, encore faut t-il qu'il y ai un maximum de redondance en terme de naming dans les classes utilisée par Bootstrap (ce qui est le cas dans un habillage orienté composant).

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... (idem pour le support « Right to Left »).

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 sans distinguer l'un de l'autre. Vous me direz que l'outil est simple d'utilisation tel qu'il est abordé dans la documentation, mais une utilisation propre de celui ci n'est pas si compliquée.

Maintenance de code et changement de design

La structure étant intimement liée au framework Bootstrap et aux visuels 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-end soit touché par du changement de design).

Ne pas rendre service aux développeurs 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 rendus— 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ée 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, en ajoutant une complexité à la maintenance et en masquant tant bien que mal le phénomène de FOUC.

Pourquoi utiliser Bootstrap alors ?

À utiliser pour :

  • Développer des « Proof of Concept » ou remplacer la création PSD / XD par une création temps réel de façon rapide. C'est donc un outil formidable pour remplacer Photoshop dans l'ère Post PSD.
  • Faire des sites à la pelle et avec de très petits budgets où le résultat en performance et en qualité reste un problème, mais où l'argent fourni pour la réalisation manque (discutable tout de même).
  • Habiller un back-office personnalisé (ou une application web) qui n'a pas fait l'objet d'une création et que l'on espère « user friendly » rapidement et simplement (une création purement fonctionnelle sans problèmes de performances à grande échelle ou de soucis de SEO).
  • Créer des tutos autours de framework dont l'habillage HTML / CSS n'est pas le centre du sujet pour obtenir un résultat descend visuellement.
  • Permettre aux rédacteurs de contenu web de faire de la mise en forme en exploitant certains modèles forts utiles qui n'ont donc ici pas vocation à faire partie de la structure même de la page. Au préalable il serait intéressant de vider toutes balises inutiles de Bootstrap, ou de se créer ses propres modèles.

À ne pas utiliser pour :

  • Des petits sites, car cela augmente bien souvent de 90% le poids du site, il vaut donc mieux ne pas le faire et perdre un peu de temps pour un gain en performance maintenance et sémantique.
  • De grosses structures, car cela leurs font perdre la flexibilité du changement d'UI sans impacter le back-end, impose la formation de toutes les ressources front-end travaillant sur le projet à Bootstrap et il résulte de la construction même des pages un impact SEO non négligeable dû au poids du HTML, sa sémantique limitée et plus globalement au temps de chargement des pages. D'un point de vu conception et maintenance, cela empêche toute possibilité d'architecture orientée composant réutilisables que ce soit dans le HTML ou dans la CSS.

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 :

<header class="clr">
    <nav class="left hidden boxsizing w50">
        Le menu
    </nav>
</nav>

en ceci

<header class="header">
    <nav class="header--nav">
        Le menu
    </nav>
</header>
/* Fichier partiel type Bootstrap uniquement avec ce dont on à besoin. */
.header {
    .clr;
}
.header--nav {
    .left;
    .hidden;
    .boxsizing;
    .w50;
}

le tour serait joué.

C'est exactement ce que permettent des approches comme Stylus 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.

Bonne utilisation de Bootstrap and cie.###

Best Practice Vous devriez parvenir à une utilisation de Bootstrap vidé de tous les problèmes précédemment cités en vu de maintenir un site orienté composant en lisant les article « Bootstrap, lisibilité, propreté, performance, optimisation ; c'est possible ! » et « Conventions HTML et CSS orientés composants ».

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 car leurs créations ne sont pas « compliant » Bootstrap.

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

Exemple rapide sur CodePen

Site de Nicolas Hoffmann

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

Template pour documentation JSDoc

C. Q. F. D.

Lire dans une autre langue