En route pour des composants HTML réutilisables

Par Niels Matthijs

Il y a quelques semaines, je suis retombé sur un vieil article que j’avais écrit pour Smashing Magazine, «  Quand un mot en dit plus que mille  ». Et si je défends toujours les principes de développement HTML que je citais à l’époque, je reconnais qu’il y manquait une chose importante : des exemples pratiques.

Bien entendu, la théorie derrière un code HTML élaboré à partir de composants est intéressante en elle-même mais, sans exemples, c’est plutôt abrupt et abstrait. Non pas que cela suffise à rebuter les passionnés du HTML – au contraire – mais il n’y a rien de mieux qu’un bon exemple pour clarifier les moindres détails d’un concept.

C’est donc ce que j’ai entrepris de faire dans cet article. Dans le précédent, j’avais présenté un assortiment de types de contenus qu’on retrouve fréquemment sur différents sites (comme des produits, des articles et des vidéos). Cette fois, je vais m’en tenir à quatre manières différentes de présenter un seul type de contenu : l’article (ou l’article d’actualité). C’est un type de contenu particulièrement courant et simple que beaucoup de personnes connaissent et auront à développer à différents moments dans leur carrière. Comme source d’inspiration concrète, je ferai référence au site internet du Boston Globe (un de mes préférés en terme de développement front-end).

Avant de commencer j’aimerais souligner un point important : le sujet de cet article ne concerne pas seulement le HTML obtenu mais la méthodologie pour écrire du HTML. Vous avez peut-être des points de vue différents sur le nommage des classes, les structures et l’ordonnancement du code source que je vais suggérer tout au long de l’article, mais ce n’est pas vraiment le sujet de l’article (même si je suis sûr que cela pourrait donner lieu à pas mal de discussions intéressantes).

La différence avec les autres méthodologies populaires basées sur des composants

L’utilisation de composants HTML n’est pas vraiment une nouveauté. Il y a quelques mois, Smashing Magazine a publié des articles sur BEM, OOCSS et SMACSS. Bien que je n’aie pas suffisamment d’informations pour juger BEM, les deux autres méthodologies sont clairement opposées à celle que je m’apprête à proposer ici.

Des méthodologies comme OOCSS et SMACSS sont nées de la frustration générée par CSS, mais ces méthodologies tentent de rendre le développement CSS plus simple en altérant le code HTML. Je pense que ce n’est pas du tout la voie à suivre (et si vous regardez la présentation initiale de Nicole Sullivan, vous verrez qu’elle propose une version anticipée des mixins comme meilleure alternative). Écrire du HTML ne consiste pas qu’à fournir les points d’attaches nécessaires pour implémenter le design : aborder les choses du point de vue des CSS diminue la qualité d’ensemble du HTML que vous écrivez. Le problème ne se limite pas à fournir le bon balisage pour CSS et JavaScript : le vrai défi est de s’assurer que chaque élément au sein d’un site web est identifiable. Si vous y parvenez, alors vous aurez couvert les besoins pour CSS, JavaScript et n’importe quelle autre technologie de script sans avoir à vous soucier des spécificités du projet.

La méthodologie que je vais vous présenter ici a été conçue dans une optique de réutilisabilité et de robustesse du code. Elle est largement indépendante des spécifications de chaque projet particulier et reste fidèle à la philosophie de pureté que le développement HTML doit respecter. Cela se traduit par de petits morceaux distincts de HTML qui sont aussi polyvalents que réutilisables.

Première étape : réunir toutes les vues et instances d’un même composant

Procédons par étape  : premièrement, nous devons définir les pré requis de notre type de contenu. Pour faire cela, nous devons en principe prendre connaissance de toutes les maquettes du projet, lister et regrouper toutes les vues et différentes instances de chaque type de contenu. Pour que notre exemple reste aussi simple que possible, j’ai sélectionné quatre vues représentatives que j’ai trouvées sur le site web du Boston Globe.

Les actualités du Boston Globe

J’ai rapidement jeté un coup d’œil sous le capot et trouvé les marqueurs suivants dans le code HTML :

Pour être honnête, je trouve cela assez compliqué. Si pour une raison quelconque vous vouliez isoler tous les articles de votre page ou de votre site web (que ce soit pour la CSS, des statistiques ou une autre raison), vous devriez contourner quelques ambiguïtés. Nous pouvons à coup sûr faire mieux.

Deuxième étape : définir la racine

<article class="recit">
   …
</article>

Et voilà ! Ce n’était pas trop difficile, n’est-ce pas ? Nous avons sélectionné l’élément article et lui avons affecté un nom de classe unique, que nous allons utiliser comme identifiant de base pour tous les articles. De cette manière, nous nous assurons que nous pouvons cibler tous les types d’articles en utilisant le même identifiant.

Comme vous pouvez le voir sur les exemples du Boston Globe, chaque vue nécessite d’être stylée de manière unique. En la reliant exclusivement au contexte des différents types d’articles c’est très loin d’être flexible, alors ajoutons une classe spécifique pour chaque vue :

La raison qui nous pousse à ajouter des classes spécifiques à l’élément racine lui-même (plutôt que, par exemple, à une liste qui le contient) est la flexibilité. Si demain, on vous demande de construire une liste composite qui mélange des articles présentés à la fois sous forme de liste et sous forme de résumé, vous serez capable de le faire sans le moindre effort.

Troisième étape : définir des unités logiques internes

Maintenant que nous nous avons évacué ce problème, il est temps de nous pencher sur ce qu’il y a dans chaque composant article. Plutôt que d’écrire du HTML pour chaque vue séparément, nous allons commencer à examiner l’ensemble des vues, en listant tous les éléments (c’est-à-dire les unités logiques) que nous y trouvons. Pour chaque élément, nous allons définir le HTML correspondant. Pensez que ces unités logiques pourraient probablement réapparaître dans différents contextes et qu’elles sont habituellement des composants elles-mêmes, il y a donc de grandes chances pour que vous ayez déjà écrit des petits bouts de HTML pour celles-ci ailleurs dans votre projet.

Titre

Il y a toujours un titre. Le titre résume tous les contenus qui vont suivre, c’est donc une des parties les plus importantes de votre type de contenu (hormis le contenu lui-même, bien sûr). Toutes les vues répertoriées précédemment contiennent un titre, mais dans le cas où vous tomberiez sur une vue qui n’affiche pas un titre, insérez-le quand même dans le code HTML et masquez-le avec CSS, si nécessaire. De cette manière, vous allez toujours «  entrer  » votre type de contenu en sachant à quoi il fait référence. Et pour ce qui est du code, c’est relativement simple :

<h1>Titre d’actualité</h1>

Vignette

La seconde chose que nous voyons est une vignette image. Les vignettes images ne font pas vraiment partie du contenu, bien que dans de nombreux cas une vignette n’est rien de plus qu’une version redimensionnée (par le navigateur) de l’image initiale dans le contenu de l’article. Ce n’est pas forcément obligatoire, parce que la fonction d’une vignette est principalement d’être un repère visuel qui attire l’attention du visiteur sur l’article. Bien souvent, elle n’a même pas de lien logique avec l’article lui-même, donc considérons-la comme un élément autonome.

Encore une fois, le code est très simple. Nous avons juste ajouté un conteneur autour de l’élément img afin de pouvoir facilement ajouter une légende si nécessaire.

<div class="image vignette"><img src="…" alt="…" /></div>

Métadonnées

La plupart des types de contenu possèdent des métadonnées. Les métadonnées ne font pas vraiment partie du contenu lui-même, mais elles fournissent des renseignements supplémentaires sur le contenu inclus au sein des types de contenu. Dans les vues précédentes, nous trouvons plusieurs types de métadonnées : un auteur, une date de publication, un indicateur de section et une mention « Initialement publié dans [ressource] ».

C’est un peu plus délicat de trouver la bonne syntaxe pour une métadonnée. Si vous suivez la spécification HTML5 à la lettre, vous êtes censés utiliser une liste de définitions. Une métadonnée n’est rien d’autre qu’une liste de paires libéllé-valeur ce qui correspond exactement à ce que les auteurs de la spécification avaient en tête quand ils ont étendu la palette sémantique de la liste de définitions en HTML5. Mais puisque la syntaxe pour les listes de définition manque d’un conteneur pour les éléments de liste, ce n’est pas très robuste, et dans de nombreux cas, il s’avère vraiment difficile de les styler (même si ce n’est pas impossible). Vous pouvez rendre votre code invalide en entourant d’une div chaque paire « dd-dt » (afin de profiter des bénéfices sémantiques de l’élément), mais je préfère habituellement rendre mon code valide, quitte à sacrifier la sémantique de quelques balises au passage.

<div class="meta">
    <div class="auteur">
        <span class="dt">label:</span><span class="dd">valeur</span>
    </div>
    <div class="date-publication">
        <span class="dt">label:</span><span class="dd">valeur</span>
    </div>
    <div class="rubrique">
        <span class="dt">label:</span><span class="dd">valeur</span>
    </div>
    <div class="publie-dans">
        <span class="dt">label:</span><span class="dd">valeur</span>
    </div>
</div>

Extrait

Un extrait est un court résumé ou une introduction à votre type de contenu. Dans de nombreux cas, mais pas toujours, il est identique au texte d’introduction lui-même. Si l’extrait est semblable au texte introductif, vous pouvez considérer que c’est une partie du contenu actuel ; si c’est une copie adaptée, elle devrait être balisée séparément.

Comme pour le HTML, vous pourriez utiliser une balise de paragraphe avec une classe qui lui serait attachée, mais vous limiteriez ensuite les extraits à se rapporter à un paragraphe simple. Si l’on considère les exemples du Boston Globe, tout va bien, mais si vous voulez que votre code soit transférable à d’autres projets, il est sans doute plus sage de rester ouvert à d’autres options. Cela donne le code HTML suivant :

<div class="extrait">
    <p> … </p>
</div>

Liens d’actions

Dans la vue détaillée d’un article, nous voyons une liste d’actions relatives à l’article lui-même. Typiquement, les listes comme celles-ci incluent les actions d’impression et d’envoi par mail et, bien sûr, les options de partage sur les réseaux sociaux. Au lieu de les relier à la source ou à des classes numérotées, nous allons donner à chacune une classe unique de telle manière que nous puissions procéder à des variations si besoin.

<div class="actions">
   <ul>
      <li class="recommander">…</li>
      …
      <li class="imprimer">…</li>
   </ul>
</div>

Vous remarquerez que la liste d’actions est placée au-dessus du contenu, faisant d’elle une candidate parfaite pour être insérée à l’intérieur d’un élément header. Bien que je fasse cette concession au design, ces liens devraient se trouver dans l’élément footer de votre type de contenu. Ce sont des actions qui ne deviennent pertinentes qu’une fois qu’on connaît le contexte. Vous ne voudriez pas (ou au moins ne devriez pas) partager un article simplement basé sur le titre ; la connaissance du contenu est cruciale pour vous décider dans votre action. Les plus joueurs en CSS pourraient laisser de la place dans l’en-tête et y positionner la liste à partir du pied de page, mais cela rendrait l’implémentation CSS plus fragile.

Le véritable contenu

Finalement, nous en arrivons au point essentiel, l’article en lui-même. Ce qui se trouve à l’intérieur d’un article dépend souvent de la liberté que vous avez donné à votre éditeur de contenu. Soit vous lui avez donné un ensemble figé de modèles pour travailler, soit vous avez juste mis un éditeur WYSIWYG dans le CMS en gardant l’espoir que tout se passe au mieux. Une chose que vous devez faire cependant c’est englober la section de contenu, ne serait-ce que pour avertir que ce qui suit est du contenu généré par l’utilisateur.

<div class="contenu">
    …
</div>

Sujets apparentés

Finalement, nous trouvons une petite liste de sujets apparentés. La chose la plus importante à souligner ici est que cet exemple unique a exactement la même apparence que la liste des sujets apparentés que nous avons tenté d’établir auparavant, ainsi il n’y a réellement aucune raison de différencier le code HTML des deux exemples.

<section class="liste-articles">
    <div class="principal">
      <article class="article"> … </article>
    </div>
</section>

Quatrième étape : définir des conteneurs structurels

Les éléments listés ci-dessus constituent non seulement une suite logique d’éléments mais aussi une structure hiérarchique logique. Certains éléments précèdent le contenu lui-même et devraient être séparés du contenu principal. D’autres éléments sont des ajouts ou des informations supplémentaires et devraient être placés après le contenu. Pour réaliser cela, nous mettons en place une structure entête, corps, pied de page typique :

<article class="article">
   <header> … </header>
   <div class="principal"> … </div>
   <footer> … </footer>
<article>

Le conteneur principal n’apparaît pas forcément nécessaire à première vue mais, en tant qu’unité logique, il mérite son propre conteneur.

Cinquième étape : assembler le tout

Maintenant que tous les bouts de code HTML sont prêts, il est temps de tout rassembler pour créer un composant maître :

<article class="recit">
   <header>
      <h1>Titre d’article</h1>
      <div class="image vignette"><img src="…" alt="…" /></div>
      <div class="meta">
         <div class="auteur">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
         <div class="date-publication">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
         <div class="rubrique">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
         <div class="publie-dans">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
      </div>
      <div class="extrait">
         <p> … </p>
      </div>
      <div class="actions">
         <ul>
            <li class="recommander">…</li>
            …
            <li class="imprimer">…</li>
         </ul>
      </div>
   </header>
   <div class="principal">
      <div class="contenu"> … </div>
      <aside>
         <section class="liste-articles">
            <div class="principal">
               <article class="recit">…</article>
            </div>
         </section>
      </aside>
   </div>
   <footer> (utilisé pour les liens lire la suite, liens vers les commentaires, etc.) </footer>
<article>

Sixième étape : ajout des microdonnées

Bien que le code HTML soit maintenant flexible et suffisamment descriptif pour que d’autres scripts puissent extraire ou pointer n’importe quelle structure dont ils ont besoin, notre composant manque toujours d’un vocabulaire commun. Bien sûr nous avons ajouté une classe .recit à notre élément racine, mais si nous utilisions .actualite, .article ou .information  ? Ils ne sont toujours pas très sémantiques.

Eh bien HTML5 met à notre disposition les microdonnées, une partie de la spécification HTML5 qui nous permet d’ajouter un vocabulaire global à notre code HTML. Vous pouvez créer votre propre vocabulaire si vous le désirez, mais si vous jetez un coup d’œil au site Schema.org vous vous apercevrez qu’il en existe plein pour les objets les plus courants.

La propriété itemscope doit être placée sur l’élément racine, de même qu’itemtype (qui spécifie une URL pour le vocabulaire — ici le site de Schema.org). Après il suffit de parcourir les propriétés des vocabulaires disponibles, et de les ajouter à votre code en utilisant itemprop. Nous obtenons alors le composant HTML suivant :

<article class="recit" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">
   <meta content="fr" itemprop="inLanguage" />
   <header>
      <h1 itemprop="headline">Titre d’actualité</h1>
      <div class="image vignette"><img src="…" alt="…" itemprop="image"/></div>
      <div class="meta">
         <div class="auteur">
            <span class="dt">label:</span><span class="dd" itemprop="author">valeur</span>
         </div>
         <div class="date-publication">
            <span class="dt">label:</span><span class="dd" itemprop="datePublished">valeur</span>
         </div>
         <div class="rubrique">
            <span class="dt">label:</span><span class="dd" itemprop="articleSection">valeur</span>
         </div>
         <div class="publie-dans">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
      </div>
      <div class="extrait" itemprop="description">
         <p> … </p>
      </div>
      <div class="actions">
         <ul>
            <li class="recommander">…</li>
            …
            <li class="imprimer">…</li>
         </ul>
      </div>
   </header>
   <div class="principal">
      <div class="contenu" itemprop="articleBody"> … </div>
      <aside>
         <section class="liste-articles">
            <div class="principal">
               <article class="recit" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">…</article>
            </div>
         </section>
      </aside>
   </div>
   <footer> (utilisé pour les liens annexes, liens vers les commentaires, etc.) </footer>
<article>

Septième étape : et pour terminer…

Maintenant que nous avons notre composant maître, il ne reste plus qu’à vérifier chaque vue et enlever les éléments inutiles du composant maître. Si cela se traduit par des restes de (= vides) conteneurs structurels, nous allons les supprimer aussi. Cela nous donne les bouts de code suivants :

Vue compacte

<article class="recit liste-reduite" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">
   <meta content="fr" itemprop="inLanguage" />
   <header>
      <h1 itemprop="headline">Titre d'actualité</h1>
   </header>
<article>

Vue d’une miniature

<article class="recit vignette" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">
   <meta content="fr" itemprop="inLanguage" />
   <header>
      <h1 itemprop="headline">Titre d'actualité</h1>
      <div class="image vignette"><img src="…" alt="…" itemprop="image"/></div>
      <div class="meta">
         <div class="rubrique">
            <span class="dt">label:</span><span class="dd" itemprop="articleSection">valeur</span>
         </div>
      </div>
   </header>
<article>

Vue compacte

<article class="recit resume" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">
   <meta content="fr" itemprop="inLanguage" />
   <header>
      <h1 itemprop="headline">Titre d'actualité</h1>
      <div class="image vignette"><img src="…" alt="…" itemprop="image"/></div>
      <div class="meta">
         <div class="auteur">
            <span class="dt">label:</span><span class="dd" itemprop="author">valeur</span>
         </div>
      </div>
      <div class="extrait" itemprop="description">
         <p> … </p>
      </div>
   </header>
   <div class="principal">
      <aside>
         <section class="liste-articles">
            <div class="principal">
               <article class="recit" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">…</article>
            </div>
         </section>
      </aside>
   </div>
<article>

Vue détaillée

<article class="recit detail" itemscope="itemscope" itemtype="http://schema.org/NewsArticle">
   <meta content="fr" itemprop="inLanguage" />
   <header>
      <h1 itemprop="headline">Titre d'actualité</h1>
      <div class="meta">
         <div class="auteur">
            <span class="dt">label:</span><span class="dd" itemprop="author">valeur</span>
         </div>
         <div class="date-publication">
            <span class="dt">label:</span><span class="dd" itemprop="datePublished">valeur</span>
         </div>
         <div class="rubrique">
            <span class="dt">label:</span><span class="dd" itemprop="articleSection">valeur</span>
         </div>
         <div class="publie-dans">
            <span class="dt">label:</span><span class="dd">valeur</span>
         </div>
      </div>
      <div class="actions">
         <ul>
            <li class="recommander">…</li>
            …
            <li class="imprimer">…</li>
         </ul>
      </div>
   </header>
   <div class="principal">
      <div class="contenu" itemprop="articleBody">…</div>
   </div>
<article>

Les composants HTML réutilisables font sens

Si vous regardez de très près les principes au cœur du HTML, vous verrez que HTML ne laisse que peu de place pour les variations. Le code HTML que nous écrivons est censé décrire nos contenus aussi précisément que possible, indépendamment du style, donc il n’y a vraiment aucune raison de créer différentes versions de structures pour un seul composant qui apparaît dans plusieurs contextes, pages ou même des projets. Un article d’actualité est un article d’actualité, et bien que les parties internes puissent varier, la structure de base, la sélection de balise et les conventions de nommage ne doivent pas en pâtir. Bien sûr, il y a toujours de la place pour la personnalité de l’auteur, y compris pour des préférences personnelles mineures, certains principes et l’expérience en général, mais un auteur devrait idéalement s’en tenir à une structure unique pour un seul composant.

Le HTML basé sur des composants a également d’importants avantages pratiques. Bien entendu, l’article d’actualité ci-dessus n’est qu’un exemple basique, mais nous pourrions faire de même avec tous les composants utilisés sur nos différents projets. Cela peut sembler beaucoup de travail à première vue, mais vous n’aurez besoin de le faire qu’une seule fois ; après ça, vous pourrez utiliser le temps que vous avez gagné sur la partie ingrate pour améliorer votre bibliothèque de composants. Désormais le HTML que j’écris pour un nouveau site web est issu de 80 à 85% de composants prêts à l’emploi, les 15 à 20% restants sont de petits ajustements spécifiques au projet ou de nouveaux composants (qui pourront toujours faire partie de la bibliothèque plus tard). Cela fait gagner énormément de temps lors du développement du HTML.

C’est aussi un énorme avantage pour les personnes qui préfèrent concevoir dans le navigateur. Un des inconvénients majeurs de la conception dans le navigateur, c’est que le code HTML est généralement le cadet de vos soucis. Vous vous dites peut-être que vous pourrez toujours le nettoyer plus tard, mais si vous êtes honnête avec vous-même, vous savez que la probabilité que vous preniez le temps de parfaire un aspect de votre travail qui est la plupart du temps invisible pour le client est proche de zéro. En utilisant votre propre bibliothèque de composants, vous n’aurez plus besoin de vous préoccuper du HTML. Si vous avez besoin d’un composant, vous n’avez qu’à vous servir, en sachant que dès le départ votre HTML est de qualité, vous pouvez vous concentrer sur la conception et les CSS.

L’avantage le plus important du HTML basé sur des composants est la qualité de service que vous allez offrir à vos clients. Plutôt que de livrer des modèles spécifiques — des styles — à un projet, vous pouvez leur offrir une structure de composants HTML robustes. De cette manière vous laissez la possibilité à vos clients de déployer ces composants sur différents sites web. Encore une fois, cela va grandement accélérer le développement HTML (et l’implémentation dans le back-end) pour les futurs projets — projets qui peuvent maintenant démarrer dès que les gabarits sont terminés, sans avoir à attendre les éléments graphiques du design. On pourrait même pousser le bouchon plus loin et utiliser les composants HTML dans les wireframes (rattachés à un CSS en marque blanche). Les possibilités sont infinies. Par la même occasion, cette méthodologie amène un niveau de cohérence et de prévisibilité sans précédent dans le code de l’ensemble des sites du client, deux choses qui font souvent défaut ces jours-ci.

Le futur de HTML

Pour moi, un code HTML basé sur des composants réutilisables est la voie à suivre, et il est temps pour nous de passer ce cap dans notre développement HTML. Partez des composants que vous avez déjà construits, faites-vous une bibliothèque avec quelques bouts de code réutilisable et continuez à partir de là. Bien entendu, il y aura toujours besoin d’un certain niveau de personnalisation, mais je suis convaincu que les bouts de code de HTML ci-dessus peuvent être utilisés dans 90% des cas pour les différents types d’articles qu’on trouve sur le web. Les métadonnées changeront parfois un peu, la présentation nécessitera de modifier l’ordre des balises mais lles bases sont là pour créer tout ce dont vous aurez besoin en moins de cinq minutes. Il s’agit ici d’appliquer le principe de duplication (DRY) non plus à l’échelle d’un seul projet mais de plusieurs, et même d’un client à l’autre.

Au final, des méthodologies comme OOCSS et SMACSS vont à l’encontre de cet idéal, car elle sont liées aux styles visuels et empêchent la réutilisation correcte des composants sur différents sites web. Par conséquent elles vont aussi ralentir le cycle de développement car le design devient alors une dépendance de plus. Pour le moment, cela veut dire qu’il va falloir vous reposer sur des pré-processeurs CSS si vous voulez une CSS maintenable, néanmoins, à terme, tout le monde trouvera largement son compte en adoptant la méthodologie décrite ci-dessus. Je suis intéressé par vos retours sur ce point.

Fiche technique

À propos de l'auteur

Pour s’aider à supporter l’insoutenable pression que représente son blog, Niels vit dans le luxe. Le reste du temps, il travaille pour Internet Architects où il s’investit pour rendre le Web plus accessible et plus agréable.

Articles similaires

Voici la liste des dix articles les plus récents en rapport avec cet article :

HTML

Intégration

Workflow

© 2001-2016 Pompage Magazine et les auteurs originaux - Hébergé chez Nursit.com ! - RSS / ATOM - About this site