Comment coder une interface responsive réussie (tutoriel) ?

Nous vous présentions il y a quelques temps le responsive webdesign, ses principes et enjeux pour vos projets web. Voici aujourd’hui quelques explications techniques pour mener à bien ce type de développement. Le responsive web design se veut « agnostique » : c’est à dire qui peut s’adapter aux composants avec lesquels il interagit. Pour se faire nous concevons une interface s’adaptant aux différentes résolutions d’écran, à l’aide des Media Queries.

Les Media Queries

Depuis le CSS2.1, nos feuilles de style profitent de la règle css @media, qui définit les différents types de medias ciblés par un ensemble de règles. Cependant, plusieurs types de media étaient mal implémentés ou même ignorés par la plupart des navigateurs et appareils. Les @media étaient donc principalement utilisées pour adapter les styles des informations d’un site pour l’impression. Le but étant d’avoir des styles simples.

@media print {
 /* Règles spécifiques aux médias */
}

Avec le CSS3, la W3C a créé les Media Queries, améliorant l’utilisation des types de media. Non seulement les requêtes media nous permettent de cibler un type d’appareil (écran, imprimante, tablette, smartphone, etc.), mais également d’inspecter les propriétés physiques de l’appareil en question. Comme par exemple la taille de l’écran.

Les différents types de média

Media Type Description
all Utilisé pour tous les supports
speech Destiné aux synthétiseurs vocaux
braille Destiné aux appareils braille à retour tactile
embossed Utilisé pour les appareils à impression braille
handheld Destiné aux petits appareils ou appareils portatifs
print Valable pour les imprimantes
projection Utilisé pour les projections, avec des projecteurs par exemple
screen Destiné principalement aux écrans d’ordinateurs
tty Destiné aux médias utilisant une grille de caractères fixe, comme les télétypes ou terminaux
tv Destiné aux appareils de type télévision

La Query est composée de deux éléments : le type media (ici, « all »), et la requête en elle même. La requête contient la caractéristique à inspecter (« max-width »), suivit de la valeur cible (« 480px »).

@media all and (max-width : 480px) {}

Vous avez deux possibilités pour utiliser les Media Queries. Elles peuvent être utilisées soit en chargeant une feuille de style différente en fonction d’une règle… :

<link rel="stylesheet" href="css/style.css" xmlns="http://www.w3.org/1999/html"/>
<link rel="stylesheet" media="all and (max-width: 480px)" href="css/small-res.css"/>

…soit en écrivant les règles directement dans le fichier .css habituel :

@media all and (max-width: 480px) {
 /* Propriétés CSS */
}

Dans les deux cas le résultat est le même. Si la largeur du navigateur dépasse 480px, les propriétés CSS ne seront pas appliquées. Vous pouvez également combiner les règles à l’aide de ces mots clés : • only : « uniquement » • and : « et » • not : « non » Voici quelques exemples pour vous aider à mieux comprendre :

/* Pour tout type d'écran, dont la largeur de périphérique ne dépasse pas 480px. Utilisé pour cibler les navigateurs de smartphones. */
@media all and (max-device-width: 480px) {}
/* Pour tout type d'écran dont la largeur est comprise entre 768px et 1024px */
@media all and (min-width: 768px) and (max-width: 1024px) {}
/* Pour tout type d'écran orienté horizontalement */
@media all and (orientation: paysage) {}
/* Pour les projecteurs */
@media projection {}

Démonstration

Tout au long du tutoriel, vous pouvez suivre le résultat sur la page suivante, en redimensionnant la fenêtre de votre navigateur.

1. Ici, nous enlevons l’image du slider à partir d’une résolution inferieure à 1024px. Nous passons également le bloc « aside » en dessous de l’article :

@media all and (max-width: 1024px) {
 .slider img { display: none; }
 .main-content { margin-top: 0; }
 article { margin-top: 20px; }
 article, aside { width: auto; margin-bottom: 1%; }
 aside { padding: 2%; }
 aside img { margin: auto; }
}

Résultat

2. Entre 767px et 900px, nous passons à trois images par ligne au lieu de quatre :

@media all and (min-width: 767px) and (max-width: 900px) {
 .img-block img { max-width: 30%; }
 .img-block img:first-child { margin-left: 2%; }
}

Résultat :

3. Cette Media Query nous permet de changer notre menu avec un autre plus adapté aux petits écrans. Nous avons également choisi de passer d’un alignement de texte justifié à un texte centré, ainsi que de trois photos à deux photos par ligne :

@media all and (max-width: 767px) {
 header > h1, nav li { float: none !important; }
 nav { float: none !important; }
 nav li { width: 100%; }
 nav a { display: block; padding: 20px; background-color: #f7fafa; margin-bottom: 2px; }
 nav a:hover, nav a:focus, nav a:active { background: #eee; }
 nav.is-closed ul { max-height: 0; overflow: hidden; }
 nav ul { line-height: normal !important; padding: 0;
 /* translate with hardware acceleration */
 -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-transition: max-height .4s; transition: max-height .4s; }
 /* Removing Firefox's dotted outline on button */
 #toggle-nav::-moz-focus-inner { border: 0; }
 /* Global styling nav button */
 #toggle-nav { display: block; position: absolute; top: 1rem; right: 1rem; z-index: 1; height: 2.1rem; width: 2.2rem; background-color: transparent; background-image: -webkit-gradient(linear, left top, right top, from(#333), to(#333)), -webkit-gradient(linear, left top, right top, from(#333), to(#333)), -webkit-gradient(linear, left top, right top, from(#333), to(#333)); background-image: -webkit-linear-gradient(left, #333, #333), -webkit-linear-gradient(left, #333, #333), -webkit-linear-gradient(left, #333, #333); background-image: linear-gradient(to right, #828587, #333), linear-gradient(to right, #828587, #333), linear-gradient(to right, #828587, #333); background-position: center top, center, center bottom; background-repeat: no-repeat; -webkit-background-size: 3.5rem .9rem; background-size: 2.5rem .6rem; padding: 0; outline: 0; border: 0; cursor: pointer; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-transition: .2s; transition: .2s; }
 /* Theming opened nav button */
 #toggle-nav.is-closed { -webkit-transform: rotate(180deg) translateZ(0); transform: rotate(180deg) translateZ(0); background-position: center, center, center; }
 article { text-align: center; }
 article img { float: none; max-width: 80% !important; }
 aside { text-align: center; }
 aside h3 { float: none !important; }
 aside img { float: none !important; max-width: 28%; }
 .img-block img { max-width: 47%; }
 .img-block { text-align: center; }
 .img-block img:nth-child(2) { margin: auto; }
 .visible-mobile { display: block; }
}

Résultat :

4. Enfin, avec la requête suivante nous demandons de passer de deux à une photo seulement par ligne :

@media all and (max-width: 480px) {
 .img-block img { max-width: 90%; margin: 5px auto 0 !important; }
}

Résultat :

Prêts à adapter simplement vos futures réalisations ?