La possibilité d'enfin utiliser CSS à son plein potentiel (mise en forme de texte mais aussi et surtout positionnement) a conduit à un principe de design permettant de s'adapter à tous les écrans : l'elastic design. Cet article de A list apart de 2004 décrit bien le principe : Elastic Design · An A List Apart Article.
Avec la généralisation des smartphone et tablettes, la donne a brutalement changé, la diversité d'équipements pouvant utiliser les sites et applications devenant immense !
Grace aux Media Queries en CSS, un nouveau principe est apparu, dérivé de l'elastic design : le responsive design. L'idée est alors, suivant la dimension de l'écran, d'adapter le positionnement et même carrément l'affichage des éléments.
Un autre système de conception est apparu en 2011, proposé par Luke Wroblewski dans son livre "Mobile First". Comme son nom l'indique, l'idée est de concevoir d'abord à destination des mobiles, puis d'enrichir successivement. Les avantages de la méthode sont bien décrits dans la conclusion de l'ouvrage :
Starting with this personal and portable device in mind first allows us to:
- Take advantage of the enormous growth in mobile internet usage and find new ways for people to use our websites and applications.
- Embrace mobile constraints to focus and prioritize the services we’re designing and building.
- Use mobile capabilities to innovate the complete customer experience.
- Take what we know about designing for the Web and start thinking differently about mobile organization, actions, inputs, and layout.
Mais évidemment, aucune méthode n'est idéale : comme on l'image bien, la situation
de base est que les utilisateurs auront des besoins et usages différents suivant le
matériel qu'ils utilisent... en plus des "simples" contraintes techniques !
Je vous recommande la lecture de ce billet chez Alsacreations qui décrit bien les
différentes solutions (site dédié, application, site commun) : C'est quoi le Responsive Web Design ?.
Sur la GepapiR, il n'y a que quelques pages de contenu, aussi la réponse s'est plutôt orientée vers une adaptation aux différentes résolutions ! Cet article décrit ce qui a été mis en place.
Par défaut les navigateurs sur mobile vont initialiser un zoom afin d'afficher la page dans son entier, au plus près de ce que l'on aurait sur un écran plus grand. L'utilisateur est alors obligé d'utiliser massivement le zoom manuel...
Une balise meta viewport permet d'Ă©viter ce comportement !.
Voir le document de recommandation du W3C : Mobile Web Application Best Practices - Use Meta Viewport Element To Identify Desired Screen Size
Ou cet article sur le très bon quirksmode.org : Meta viewport.
Sur la GepapiR j'utilise :
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Les dimensions en CSS peuvent s'exprimer en différentes unités : voir la liste dans la recommandation !
Afin de s'adapter au paramétrage des navigateurs, les dimensions de texte et marges
sont définies avec l'unité em
. Cependant, utiliser cette unité poserait
problème pour les marges horizontales : en effet celles-ci sont plus liées à la dimension
du viewport (la zone qu'affiche le navigateur) que aux paramètres de police ! Aussi,
ces marges là sont définies sur la GepapiR en utilisant l'unité %
, et
s'adaptent donc en fonction de la largeur disponible.
Exemples d'adaptation des marges horizontales dans les captures ci-dessous :
Un très bon article à lire sur les unités CSS et leurs effets : Font sizing with rem - Snook.ca.
Sur la GepapiR, je n'utilise pas l'unité rem
car la structure des pages
est simple et fait que les problèmes d'imbrication décrits dans l'article sont absents.
Trois différentes largeurs d'écran sont gérées pour le menu de navigation, via des media queries, comme montré ci-dessous. Pour chacun d'elle on adapte la position et la taille du texte autour des icones. La longueur variable du border-radius est gérée par une dimension en unité "%".
@media screen and (max-width: 700px)
{
nav a
{
margin: 0 0.5em;
padding: 0.2em;
}
}
@media screen and (max-width: 590px)
{
nav ul
{
margin: 0;
padding : 0.1em;
font-size: 0.85em;
}
nav a
{
margin: 0 0.1em;
padding: 1em 0.05em;
}
}
A noter : on utilise max-width
(largeur du viewport) plutĂ´t que max-device-width
(largeur physique de l'écran) à dessein : ces modifications sont aussi intéressantes si l'on redimensionne la fenêtre d'un navigateur sur grand écran !
Généralement c'est plutôt l'inverse... A ce sujet lire : Faut arrêter avec les Media Queries ! – HTeuMeuLeu
On va simplement afficher une partie des séparateurs si le viewport est moins large que l'image :
@media screen and (max-width: 645px)
{
hr.sep
{
width: 98%;
}
}
Plusieurs images sont assez larges et dépassent du viewport sur des écrans à taille réduite !
Une solution serait d'utiliser l'attribut HTML 5 srcset
. Le
support est correct Ă ce jour (septembre 2024 : Chrome 34+, Fx 38+, Safari 8+ -
lien CanIUse), mais ça nécessiterai de
créer de nouvelles images... Un avantage pour renvoyer des images plus légères,
mais les images concernées sont peu nombreuses, relativement peu lourdes et bien
cachées.
L'idée a donc été d'appliquer un width
en % sur media query. Mais
comme chaque image a une taille différente, la mise en place est compliquée :
Ă©criture d'un code quasi identique mais variant sur les dimensions de chaque image,
et Ă©parpillement entre la balise IMG et le code CSS qu'il faut penser Ă Ă©crire et
Ă Ă©ventuellement mettre Ă jour.
Pour y remédier j'ai écris un simple JavaScript chargé au démarrage, et qui va modifier des images marquées dans la page :
style
dans le head
width: 98%;
sur max-device-width
Les images à modifier sont identifiées par un attribut data-responsive-img
.
Les attributs data-* sont un ajout de HTML 5. Pour en savoir plus :
Le script est lancé en onDomReady, en utilisant la librairie de tubalmartin.
Le code :
function writeCSSRespImg()
{
var elements = document.getElementsByTagName("img"),
image,
width,
height,
cssClassName,
cssClasses,
cssCode,
style,
maxWidth;
for (i = 0; i <= elements.length - 1; i++) {
image = elements[i];
if (image.hasAttribute("data-responsive-img")) {
// RĂ©cup width / height
width = parseInt(image.getAttribute("width"));
height = parseInt(image.getAttribute("height"));
// Ajoute classe
cssClassName = "responsive-img-" + i;
cssClasses = image.className;
if (cssClasses != "") {
cssClasses += " ";
} else {
cssClasses = "";
}
cssClasses += cssClassName;
image.className = cssClasses;
// Ecriture du CSS
cssCode = "";
style = document.createElement("style");
maxWidth = width + 5;
cssCode = "\nimg." + cssClassName + "\n\
{\n\
width: " + width + "px;\n\
height: " + height + "px;\n\
}\n\
@media screen and (max-device-width: " + maxWidth + "px)\n\
{\n\
img." + cssClassName + "\n\
{\n\
width: 98%;\n\
height: auto;\n\
}\n\
}\n";
style.appendChild(document.createTextNode(cssCode));
document.head.appendChild(style);
// Suppression des attributs du tag img
image.removeAttribute("width");
image.removeAttribute("height");
}
}
}
onDomReady(writeCSSRespImg);
Création le 13/08/2014
Dernière mise à jour le 06/09/2024
Un oubli, une erreur, une suggestion ? Rendez-vous sur le dépôt GitHub !