CSS et design continu
Pourquoi un site responsif sans media queries?
Je n’aime pas le mode plein écran. Les écrans sont horizontaux, le contenu des sites web est vertical, c’est stupide d’élargir sa fenêtre au maximum et d’avoir de l’espace vide sur les deux tiers. Je suis du genre à ajuster et réajuster la taille de mes fenêtres au cours de la journée. Pour cette raison, je n’aime pas les sites qui basculent de la mise en page « bureau » à la mise en page « mobile » dès que la fenêtre fait moins de 1400 pixels de large. En particulier, je n’aime pas le fait de basculer brutalement d’un mode à l’autre, en changeant complètement la mise en page.
Je préfère garder la même structure entre le design « large » et le design « étroit ». Les éléments restent à la même place; les marges se réduisent ou s’agrandissent, le texte revient à la ligne plus souvent, mais la mise en page reste la même. C’est ce qu’on a fait pour le redesign de notre site.
Selon la largeur du viewport, trois propriétés de mise en page sont modifiées:
- les espaces latéraux internes, à l’intérieur du fond blanc;
- les marges verticales, entre les paragraphes;
- l’interligne des en-têtes.
Comment ça marche?
Pas de breakpoints, mais une zone de transition.
Les breakpoints sont habituellement une notion importante du design responsif: à quelle largeur bascule-t-on d’un design à l’autre?
@media (width > 1200px) {
/* CSS rules for desktop wide screens */
}
Au lieu de deux jeux de règles distinctes, on a mis en place un seul design avec un changement graduel entre les deux extrêmes.
- En-dessous de 800px de largeur, on considère que l’écran est « étroit »,
- Au-delà de 1000px, il est large.
- Entre les deux, on interpole. Autrement dit, à 900px, les marges sont à mi-chemin entre la taille « étroite » et « large ».
Par simple interpolation, on va calculer une valeur entre O
et 1
, que j’appelle --lerp-px
2 dans le code. À partir de ce ratio, on va pouvoir écrire les propriétés css qu’on veut faire varier. Par exemple, pour le padding latéral (remplissage, en français selon MDN.):
body {
padding-inline: calc(16px + 80 * var(--lerp-px));
}
Il vaut donc:
16px
en dessous de800px
36px
à850x
(--lerp-px
vaut 0.25)56px
à900px
(--lerp-px
vaut 0.5)76px
à850x
(--lerp-px
vaut 0.75)96px
au-dessus de1000px
.
C’est aussi simple que ça. On peut faire la même chose pour les marges verticales:
main article + article {
margin-block-start: calc(16px + 48*var(--lerp-px));
}
Et l’interligne des titres:
h1, h2, h3 {
line-height: calc(1.3em + 10*var(--lerp-px));
}
Comment est calculé --lerp-px
?
On se base sur la largeur de la fenêtre, autrement dit le viewport, autrement dit 100vw
3:
:root {
--clamped-width: clamp(800px, 100vw, 1000px);
--lerp-px: calc((var(--clamped-width) - 800px) / (1000 - 800));
}
Ça a l’air simple comme ça, mais ça a été un peu pénible à débugguer! J’ai écrit un mini script pour observer en direct les variables CSS qui utilise ResizeObserver
sur un div dont la taille dépend de la variable à débugguer. Il est chargé sur cette page, vous pouvez ouvrir la console, taper observeCssVariable("--clamped-width")
ou observeCssVariable("--lerp-px")
, et jouer avec la largeur de la fenêtre.
Une dernière remarque technique: pourquoi --lerp-px
et pas --lerp
tout court?
Puisqu’elle est calculée à partir de <length>
4 css, 100vw
et 800px
, la valeur est elle-même une <length>
css, et pas un <number>
5. Il n’y pas de moyen simple de convertir une <length>
ou une <dimension>
en <number>
sans unité. J’ai le sentiment que la spec indique que calc(1px/1px)
devrait donner un <number>
, mais ce n’est pas ce que j’obtiens.
Je suis preneur d’explications! Peut-être qu’il y aurait une solution en utilisant les @property
. J’ai déjà passé beaucoup de temps à ces quelques pixels, ça devra attendre.
C’est tout pour le moment, merci d’avoir lu jusque là! N’hésitez pas à nous dire ce que vous en pensez, par mail, sur Mastodon ou sur le dépot.
-
Je précise que les énormes marges blanches de la mise en page « mobile » ne sont pas dues à mon bloqueur de pub. La bannière grise sur la mise en page « bureau », oui. ↩︎
-
Wikipedia: “In computer graphics jargon Linear Interpolation is sometimes called a lerp.” ↩︎
-
https://developer.mozilla.org/en-US/docs/Web/CSS/length#relative_length_units_based_on_viewport ↩︎