Publié par
Il y a 4 semaines · 7 minutes · Front

CSS : .container, la classe à abattre

Il n’y pas si longtemps, un comparse développeur m’a interrogé sur l’utilité d’une classe html/css*1 présente dans ma codebase :

<div class="container">
...
</div>

Un bureau d’investigation de haute volée (composé de moi-même) débuta alors une folle enquête sur ce mystérieux .container, son parcours et ses motivations …

.container, qui est-il ? D’où vient-il ?

Quand j’ai commencé à faire de l’intégration html/css, il y avait cette classe, container, un peu partout. En général, elle englobait tout le contenu du site, de cette manière :

<html>
    <head><!-- ... --></head>
    <body>
        <div class="container">
            <!-- Et là, bim, bam, boum, on met tout son contenu !!! -->
        </div>
    </body>
</html>

Pour faire simple, elle centrait le contenu de la page et c’était visiblement une pratique normée dans le monde du css, car tout le monde utilisait cette classe.

Et selon les projets, on pouvait trouver des variantes, comme les classes wrapper, section*2, ou encore l’id content, et parfois, une combinaison de tout ça, en général avec un nesting, soyons francs, assez aléatoire, mais ça ressemblait grosso modo à cette satanée maquette qu’il nous fallait intégrer, alors tout allait bien.

.container, où est-il ? Que fait-il ?

Aujourd’hui, si on google rapidement « css container », on tombe sur différents frameworks css qui intègrent une classe container. Bien que je ne conseille pas l’utilisation des frameworks CSS, à moins de n’avoir aucune maquette à respecter, ils restent de bons moyens pour jauger l’état de l’art en CSS. Regardons donc un peu plus en détails les implémentations de .container mises en place dans certains frameworks*3 :

  • Bootstrap : http://getbootstrap.com/css/#overview-container
    .container {
        /* On ajoute une marge sur les cotés de l'écran */
        padding-right: 15px;
        padding-left: 15px;
    
        /* Et on centre */
        margin-right: auto;
        margin-left: auto;
    }
    
    /* Sur les grands écrans, on limite la largeur du contenu */
    @media (min-width: 1200px){
        .container {
            width: 1170px;
        }
    }
    
  • Materialize : http://materializecss.com/grid.html
    .container {
        /* On centre */
        margin: 0 auto;
    
        /* On limite la largeur pour les grands écrans */
        max-width: 1280px;
    
        /* On gère la présence d'une marge */
        width: 90%;
    }
    
    /*
    * Comme la dite marge est exprimée en pourcentage,
    * on l'augmente sur les devices moins larges.
    */
    @media only screen and (min-width: 993px){
        .container {
            width: 85%;
        }
    }
    
  • Skeleton : http://getskeleton.com/
    .container {
        /* On limite la largeur */
        width: 100%;
        max-width: 960px;
    
        /* On centre */
        margin: 0 auto;
    
        /* Et on ajoute une marge (sur les petits écrans seulement) */
        padding: 0 20px;
    
        /*
        * Le "box-sizing: border-box;" permet de ne pas impacter la width avec le padding
        * La largeur max réelle du contenu est donc de 920px =&gt; 960 - (2 x 20)
        */
        box-sizing: border-box;
    }
    
    /* Sur les écrans plus larges, la marge est gérée en pourcentage */
    @media (min-width: 400px) {
        .container {
            width: 85%;
            padding: 0;
        }
    }
    
  • W3.CSS : https://www.w3schools.com/w3css/w3css_containers.asp
    /*
    * W3.CSS se rapproche plus de la charte graphique de w3 school,
    * là où les précédents frameworks se veulent plus agnostiques
    */
    
    /* Ici, le container sert simplement à gérer un padding */
    .w3-container {
        padding: 0.01em 16px;
    }
    

Hormis pour ce dernier exemple, on distingue donc deux utilités à notre classe container, centrer le contenu et y ajouter une marge horizontale.

 .container, pourquoi fait-il ça ?

Pour que votre contenu reste lisible. Explications. Une page web est composée d’éléments qui peuvent être :

  • Textuels (ou images liées) et/ou interactifs ;
  • Décoratifs (image de background, bandeau de couleur, etc.).

Si pour ces derniers, on peut souhaiter qu’ils s’étendent sur toute la largeur de l’écran, pour le contenu texte/interactif, il est important d’avoir :

  • Une marge de confort afin d’éviter que votre contenu ne soit collé aux bords de l’écran (notamment sur les devices mobiles). Cela permet de conserver une lisibilité de votre texte. En général, cette marge se situe entre 15 et 20 pixels ;
  • Une largeur utile, qui correspond à la largeur d’écran au delà de laquelle il devient inutile (voir contre-productif) d’étaler son contenu sur toute la largeur disponible, au risque de sortir du champ de vision de l’internaute des éléments qu’il est censé voir. Souvent, cette largeur utile est centrée.

Du coup la classe container répond effectivement à ces deux besoins. Toutefois, elle peut parfaitement être remplacée, et par quelque chose de mieux qui plus est !

.container, pourquoi doit-il disparaître ?

Car il manque d’expressivité. Sémantiquement parlant, le terme container apporte à peu prés autant d’informations qu’une classe foobar. Quasiment tous les tags HTML sont destinés à contenir quelque chose.

Étant donné qu’on sait maintenant ce que faisait .container, et pourquoi il le faisait, on peut sereinement le remplacer par deux classes :

  • .margin-constraint afin de gérer notre marge de confort ;
  • .useful-width afin de gérer notre largeur utile.

Une implémentation CSS ?

Partons sur une largeur utile de 800px et des marges de confort de 20px. Cela nous donne :

<!DOCTYPE html>
<html>
<head></head>
<body>
    <div class="full-width">
    Ici, on aura des éléments purement décoratifs qui peuvent s'étaler sur toute la largeur de l'écran (une image, ou encore un bandeau de
    couleur...)
 
        <div class="margin-constraint">
        Ici on peut par exemple placer des éléments qui doivent s'étaler sur toute la largeur,
        mais ne doivent pas être juste au bord de l'écran (certaines décorations, éventuellement certains éléments de menu...)
             
            <div class="useful-width">
            Notre contenu textuel ira généralement ici. Il restera sur une largeur agréable à la lecture
            et gardera un espace par rapport au bord de l'écran.
            </div>
        </div>
    </div>
</body>
</html>
.margin-constraint{
    /*On indique tout simplement une marge*/
    margin-left: 20px;
    margin-right: 20px;
}
 
.useful-width{
    /*On règle ensuite la largeur utile puis on centre*/
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
}
 
.margin-constraint, .useful-width{
    /*Si vous utilisez uniquement des div, cette dernière règle css n'est même pas nécessaire*/
    display: block;
    width: auto;
}

Au final, niveau css, on gagne en simplicité comparé aux implémentations de container précédemment évoquées :

  • Pas de media query;
  • On utilise des propriétés qui sont sémantiquement plus proches de ce que l’on souhaite réaliser ;
  • Si on travaille avec une maquette, on peut directement utiliser les valeurs déduites de cette dernière, plutôt que de devoir faire un calcul du type (largeur utile – 2 * marge de confort) ou utiliser un pourcentage un peu approximatif (voir les exemples en début d’article).

Le principal désavantage de cette technique est qu’elle nécessite l’utilisation de 2 balises html imbriquées (.margin-constraint > .useful-width). Mais avec une petite règle css en plus, vous pourrez également utiliser les deux classes sur une même balise. Voyez le résultat ici : https://codepen.io/alexistessier/pen/XRLoxv.

À noter : Une autre approche courante consiste à définir une max-width puis à appliquer un padding afin de gérer la marge. Je ne suis pas fan de cette façon de faire car elle implique de forcer le box-sizing (propriété assez obscure et globalement assez mal comprise) de l’élément si on veut s’assurer que le padding soit ou non inclus dans la largeur finale de l’élément. Autant que possible, je préfère utiliser des propriétés simples à appréhender.

Pour conclure

Au delà de vous exhorter à éliminer méthodiquement tout .container que vous pourriez trouver dans vos CSS, le but de cet article était surtout de revenir à des fondamentaux et d’essayer de se souvenir quelles problématiques résolvent les frameworks CSS lorsqu’ils mettent une classe tel que container à notre disposition.

Tchao’

Notes de bas de page

  • *1 : En réalité, il s’agissait d’un helper en stylus, un préprocesseur css qu’il est bien pour styler des choses.
  • *2 : Mais ça c’était avant le tag section de HTML5.
  • *3 : Les css présentées dans cet article sont des versions simplifiées de ce que vous pourrez trouver si vous allez voir vous même dans le code source des frameworks css concernés.

Une réflexion au sujet de « CSS : .container, la classe à abattre »

  1. Publié par Nod, Il y a 4 semaines

    Je ne suis pas tellement d’accord avec toi. Les media queries ne sont pas obligatoire quand tu peux utiliser max-width et pour moi c’est compliquer les choses que de devoir rajouter 2 div alors qu’une seule est suffisante.

    Merci pour ton article

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *