Bootstrap

La grille Bootstrap

Bootstrap est le framework le plus utilisé pour créer des sites/applications responsives. Il intègre un système de grille qui permet de créer simplement et efficacement des layouts de pages web mobile first. Par défaut, cette grille est structurée en 12 colonnes, ce qui lui permet de diviser facilement la page en 2, 3, 4 ou 6 parties. On définit ainsi la taille de chaque colonne sur une échelle de 1 à 12. On utilise donc col-*-12 pour prendre toute la largeur (100%) du conteneur, col-*-6 pour la moitié (50%), etc.

La grille Bootstrap utilise des media query range pour adapter la structure d’une page en fonction de la résolution de l’écran sur laquelle elle est affichée. La permutation se fait selon 4 configurations, par défaut les valeurs sont :

  • xs les écrans très petits (eXtra Small pour les smartphones) d’une résolution inférieure à 768px
  • sm les petits écrans (SMall pour les tablettes) d’une résolution entre 768px et 992px
  • md les écrans moyens (MeDium pour les écrans d’ordinateur un peu ancien) d’une résolution entre 992px et 1200px
  • lg les grands écrans (LarGe pour les écrans d’ordinateur récent) d’une résolution supérieure à 1200px

Pour l’utiliser il faut ainsi ajouter des classes CSS spécifiques à vos balises HTML. Par exemple, un composant ReactJS avec le code suivant (utilisant JSX), possèdera :

  • 1 colonne (12 divisé par 12) occupant toute la largeur de l’écran avec les blocs les uns en dessous des autres sur les smartphones et tablettes
  • 3 colonnes (12 divisé par 4) occupant chacune un tiers de l’écran avec les blocs les uns à côté des autres sur les écrans moyens et les grands écrans.
<div className="row">
    <div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
    <div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
    <div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
</div>

Limites de la grille Boostrap

La grille Bootstrap est une solution facile à mettre en place pour créer un layout de page, mais le fait qu’elle se base sur les media query est un problème lorsque l’on souhaite développer un widget réutilisable qui puisse être intégré dans n’importe quel container.

En effet si je crée un widget responsive pour une page web avec une structure similaire à l’exemple précédent.

<div className="row">
    <div className="col-xs-6 col-md-3">
        <div className="glyphicon glyphicon-camera"></div>
        <div>Pictures</div>
    </div>
    <div className="col-xs-6 col-md-3">
        <div className="glyphicon glyphicon-facetime-video"></div>
        <div>Videos</div>
    </div>
    <div className="col-xs-6 col-md-3">
        <div className="glyphicon glyphicon-headphones"></div>
        <div>Music</div>
    </div>
    <div className="col-xs-6 col-md-3">
        <div className="glyphicon glyphicon-book"></div>
        <div>Books</div>
    </div>
</div>

Jusque-là tout va bien, mais que se passe-t-il si quelqu’un décide d’importer mon widget dans la barre latérale d’une autre page ?

Et ça … c’est moche ! Le problème vient ici du fait que les éléments sont disposés en fonction de la largeur totale de la page/écran et non en fonction de la place disponible (largeur du conteneur du widget). Dans le cas présent, le layout mobile conviendrait et il serait simple de surcharger les styles pour corriger cette page, mais en tant que développeur, on préfèrerait créer des composants qui s’adaptent eux-même à l’espace qu’on leur alloue.

React Responsive Widget

Présentation

Le module react-responsive-widget est un composant ReactJS simple, également disponible sur npm, il permet à votre widget de s’organiser en fonction de la taille du bloc dans lequel il se trouve.

Il utilise une grille similaire à celle proposée par bootstrap 3.3.7, mais pour éviter les conflits avec Bootstrap, toutes les classes sont préfixées avec app-*.

Les permutations entre les différents layouts de votre composant responsive se font désormais sur la largeur du conteneur de la manière suivante :

  • xs d’une largeur inférieure à 768px (par défaut)
  • sm d’une largeur entre 768px et 992px (par défaut)
  • md d’une largeur entre 992px et 1200px (par défaut)
  • lg d’une largeur supérieure à 1200px (par défaut)

Installation

Pour l’installer avec npm :

$ npm install --save react-responsive-widget

Si vous utilisez un bundler qui supporte ES6 vous pouvez l’importer de la manière suivante :

import ResponsiveContainer from 'react-responsive-widget'

Vous pouvez désormais utiliser le composant et créer une grille responsive pour votre widget.

import React from "react";
import ResponsiveContainer from "react-responsive-widget";

export default class App extends React.Component {
    render() {
        return (
            <ResponsiveContainer>
                <div className="app-row">
                    <div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
                    <div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
                    <div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
                </div>
            </ResponsiveContainer>
        )
    }
}

Exemple

Revenons au cas qui posait problème avec la grille bootstrap et modifions le pour utiliser notre ResponsiveContainer.

<ResponsiveContainer>
    <div className="app-row">
        <div className="app-col-xs-6 app-col-md-3">
            <div className="glyphicon glyphicon-camera"></div>
            <div>Pictures</div>
        </div>
        <div className="app-col-xs-6 app-col-md-3">
            <div className="glyphicon glyphicon-facetime-video"></div>
            <div>Videos</div>
        </div>
        <div className="app-col-xs-6 app-col-md-3">
            <div className="glyphicon glyphicon-headphones"></div>
            <div>Music</div>
        </div>
        <div className="app-col-xs-6 app-col-md-3">
            <div className="glyphicon glyphicon-book"></div>
            <div>Books</div>
        </div>
    </div>
</ResponsiveContainer>

Notre widget se comporte toujours comme prévu en pleine largeur sur desktop et sur mobile et s’adapte correctement si on l’intègre dans un espace restreint.

Customisation

Il est possible de choisir les largeurs auxquelles les permutations s’effectuent de la manière suivante :

<ResponsiveContainer sm="800" md="1000" lg="1400">
    ...
</ResponsiveContainer>

Cette définition donnera le comportement suivant :

  • xs d’une largeur inférieure à 800px
  • sm d’une largeur entre 800px et 1000px
  • md d’une largeur entre 1000px et 1400px
  • lg d’une largeur supérieure à 1400px

Comment ça marche ?

Comme il n’est pas possible d’utiliser des media query css pour changer les styles en fonction de la taille du composant, react-responsive-widget utilise une approche différente de Bootstrap.
Le ResponsiveContainer surveille les événements de redimensionnement du container, il modifie la classe de ce dernier en fonction de sa largeur. Par exemple si le composant a une taille inférieure à 768px (xs), le container aura la classe app-xs. S’il dépasse 768px de largeur (sur un écran plus grand ou après resize) on aura app-sm.

En XS :

En SM :

Exemple d’utilisation :

Nous avons utiliser ce composant pour créer plusieurs widgets et formulaires, dont un permettant aux utilisateurs d’obtenir un « tarif express » :

Grace à une syntaxe simple et connue par la plupart des développeurs, nous pouvons donc créer rapidement des widgets proposant une plus grande variété d’intégration.