Intro
Je voulais améliorer mon SEO sauf que je peux pas m'empêcher de mettre une blague pourrie dans le titre qui va me propulser en page 30 des recherches. Sans compter que cette intro est déjà hors sujet.
Je vous expose la problématique: La plupart des sites web vous affichent une LISTE DE TRUCS.
Ben si! Un forum? Une liste des billets (des POSTS, quoi), un site e-commerce? Une liste d'articles. Un blog bizarre? Une double liste de "brèves" qui sont même pas brèves et d'articles qui s'étalent sur bien trop de sujets différents pour intéresser le seul lecteur qui était revenu plus de deux fois (par erreur).
Parfois, la LISTE DE TRUCS est beaucoup trop longue, surtout sur mobile.
Une solution optimale serait de construire une plus petite liste de trucs en envoyant moins de trucs depuis le serveur.
Bien évidemment c'est pas ça qu'on va faire. Non, nous on veut l'équivalent de coller du vieux tape marron pour masquer les X derniers éléments sélectivement selon la situation et pour ça, on va avoir DU FUN avec le CSS.
Je n'ai pas trouvé d'articles qui regroupent toutes ces solutions et certaines (y compris la meilleure selon moi) sont pratiquement introuvables. J'ai donc potentiellement le meilleur article en français sur la question, lequel demeurera bien entendu en page 80 des résultats Google, avec sa substance délicieusement émulsionnée dans mes moultes blagues à la noisette.
Pourquoi?
En réalité il faut que je refasse ce blog depuis des années, surtout pour tout moderniser et quitter le modèle strictement Single Page Web App pour lequel il me semble déceler un semi-subtil recul de popularité assorti d'un retour à déferrer les tâches de rendu au serveur. Comme avant quoi. J'ai envie de faire une blague sur PHPNuke mais je me retiens.
En attendant, la version mobile de mon blog, qui est la version que plus de 50% de gens utilisent (j'ai sorti de ce pourcentage de ma raie, c'est peut-être bien plus que ça) affiche une ribambelle de ces fameuses "brèves" en premier et il faut défiler quelques mètres pour voir qu'il y a aussi des articles.
Il en faudrait deux ou trois grand maximum. Par contre, sur grand écran c'est pas choquant (je trouve).
Il est possible de modifier la partie client pour demander moins d'articles au serveur uniquement si l'écran est petit — Ce qui impliquerait probablement une technique foireuse de détermination de taille d'écran de de media query actif pour décider du nombre d'éléments à charger. Je conseille pas et c'est en dire long quand vous allez voir à quel point la "méthode CSS" qui est l'objet de cet article est plus que légèrement effrayante.
Démonstration
Ce sera peut-être plus clair si je vous montre. C'est ce que je m'étais dit avant de me rendre compte que c'était plus compliqué de prévu puisqu'il faut que je prévoie un exemple qui fonctionne sur mobile où l'écran est minuscule et où on ne redimensionne que très rarement des éléments parce qu'un écran de mobile c'est vraiment juste bien pour défiler un réseau social à l'infini plutôt que de se lever [du lit | des WC] et c'est un peu l'essence du truc.
D'ailleurs j'ai déjà vaguement expliqué que ça me rendait triste.
Au diable la paresse, j'essaye tout de même de créer un genre d'iframe qui puisse être redimensionné grâve à ce "nouvel" attribut CSS resize que j'utilise jamais.
He bien mes amis, j'ai compris pourquoi je l'utilise jamais et qu'en fait personne ne l'utilise à part pour retirer la poignée de redimensionnement sur un élément textarea:
Pourtant la description sur MDN avait l'air prometteuse:
Si c'était un wiki je proposerais quelques menues corrections à la discrétion des juges de l'Internet:
Sur mobile c'est encore mieux, mon Chrome mobile il affiche un minuscule point noir dans le coin inférieur droit qui permet effectivement de redimensionner si et seulement si vous êtes un hamster.
Mais alors me dis-je, comment ils font les gens sur codepen.io ou jsfiddle.net? Ils fournissent une iframe et plusieurs panneaux redimensionnables comme si c'était un truc normal.
Quelle ne fut pas ma surprise lorsque j'ai tiré le rideau d'y retrouver mon bon vieil ami JavaScript. Oh ben ça alors dis moi!
OK donc je suis censé coder un bidule de redimensionnement pour mon exemple de truc CSS à la con (oui j'auto-dénigre cet article). Etant donné que je ne recule devant aucun sacrifice, je l'ai fait, mais c'est juste un groupe de boutons pour allonger ou raccourcir d'une certaine taille et voilà OKAY?
Vu qu'on vient de perdre deux heures sur une parenthèse de plus qui incite à ne pas UTILISER LA PLATEFORME, j'explique le topo à nouveau:
- J'ai une liste d'éléments (articles, vidéos, trucs à vendre, ...);
- Je veux que moins d'éléments apparaissent sur mobile;
- C'est tout en fait.
Cliquez sur les poignées vers l'intérieur pour voir la magie s'opérer. A moins que vous ayez un genre de mobile que j'ai vraiment pas testé. Il va être génial l'avenir du "tout petit écran", déjà qu'on a plus de place pour mettre l'avertissement sur les cookies, les 3-pubs-minimum à poser sur la page et le popup pour s'inscrire à la newsletter.
Evidemment sur mobile en mode vertical on ne voit que 3 éléments quoi qu'il arrive, mais vous pouvez peut-être tout de même tester la démo en passant en mode paysage.
Remarques préliminaires
Il y a plusieurs manières d'écrire les media queries qui sont dans les exemples ci-dessous, je fais au plus simple par soucis didactique (je mens, c'est just la FLEMME), ce ne sera pas nécessairement un pur "mobile first" et mes choix de points d'inflexions (appliquer ce media query entre X et Y pixels) sont un peu arbitraires.
Tous mes exemples ont pour but de:
- Montrer tous les 8 éléments sur "grand écran";
- Ne montrer que les 5 premier sur "moyen écran" (tablette - Fenêtre taille réduire);
- Ne montrer que les 3 premiers sur petit écran.
Etant donné que j'affiche tout les éléments sur "grand écran", je n'ai générallement pas besoin de media query pour cette taille. Il aurait été utile d'en ajouter un si on décide, par exemple, de ne montrer "que" 10 éléments sur "grand écrans". Pourquoi je mets des guillemets partout.
Méthode 1 — Classes de type "cache-moi sur petit écran"
Je sais pas si vous voyez qu'est-ce que je veux dire par là. La plupart des "frameworks" CSS ont des classes qui cachent un élément sur une certaine taille d'écran.
Pour Bootstrap par ex., on a .d-sm-none qui cache l'élément sur petit écran (mobile, quoi).
Je vais aussi citer Tailwind histoire d'avoir cité le truc le moins et le plus à la mode, où vous avez la classes .sm:hidden qui a le même résultat.
Pour cacher certains éléments sur mobile ou tablette ou quelque soient les autres tailles d'écran supportées, il suffit de leur coller une de ces classes.
Problème: Il faut sélectivement coller cette classe, on peut pas la mettre sur tous les éléments sinon on affiche plus rien du tout sur mobile, ce qui est moyen comme solution (bien que je puisse saisir comment on peut en arriver là).
Du coup il faut obligatoirement modifier le code du client (le JAVASCRIPT) ou du serveur et pas juste le CSS. Ceci dit, c'est de loin la solution la plus propre.
Je vous conseille d'utiliser les classes utilitaires de votre framework CSS de choix mais dans l'esprit du didactique démonstrationnel voici les code HTML et CSS qui iraient bien.
HTML:
<section>
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block hide-sm">4</div>
<div class="block hide-sm">5</div>
<div class="block hide-sm hide-md">6</div>
<div class="block hide-sm hide-md">7</div>
<div class="block hide-sm hide-md">8</div>
</section>
CSS:
section {
/* C'est juste pour avoir une liste verticale */
display: grid;
grid-template-columns: minmax(150px, 1fr);
row-gap: 2rem;
}
.block {
/* A styler pour être un beau BLOC */
padding: 1rem;
background-color: deeppink;
}
@media (max-width: 600px) {
.hide-sm {
display: none;
}
}
@media (min-width: 600px) and (max-width: 850px) {
.hide-md {
display: none;
}
}
J'espère que vous saisissez l'idée.
Méthode 2 — Sélecteur "nth"
Les sélecteurs de type "nth" sont plutôt rarement utilisés bien qu'il en existe plusieurs qui remplissent tout un tas de cas d'utilisation.
Comme pour beaucoup d'autres sélecteurs et propriétés légèrement obscures, une aura de magie noire s'en dégage et c'est pas très clair si c'est hyper malin ou hyper inutile ou les deux. C'est probablement les deux.
Il est effectivement possible de donner une formule magique à nth-child pour qu'il sélectionne tous les X éléments:
li:nth-child(3n) {
/*
Sélectionne tous les 3èmes éléments "li" pour un parent donné.
Oui ça sert un peu à rien.
*/
color: deeppink;
}
Bon et alors tant qu'on y est, nth-child est appelé une "pseudo-classe" (je l'appelle "pseudo sélecteur" mais j'ai sûrement tort) et s'utilise avec ":" devant un autre sélecteur qui est censé identifier un élément qui se répète dans un élément parent quelque part (par ex. li a du sens avec ul comme parent).
Si vous êtes déjà largués maintenant, c'est normal, c'est pour ça qu'on copie colle les CSS ou que tout le monde utilise Tailwind.
Là où ça devient très rigolo, c'est qu'on peut ajouter un offset à la formule magique, par ex:
tr:nth-child(2n+1) {
/*
Sélectionne toutes les lignes de tableau impaires dans un parent.
1, 3, 5, etc.
*/
background: deeppink;
}
Je suis au courant pour ce cas d'utilisation il y a un raccourci prévu sous la forme de:
tr:nth-child(odd) {
/*
Sélectionne toutes les lignes de tableau impaires dans un parent.
1, 3, 5, etc.
*/
background: deeppink;
}
Mais j'essayais juste de pas vous compliquer le truc. Oui, c'est raté.
Il se trouve que si j'utilise cette formule qui ne veut rien dire:
.mon-bloc:nth-child(1n+4) {
background: deeppink;
}
On ne sélectionne que les 4, 5, 6, 7, etc. enfants. Mais oui, c'est logique, 1n sélectionne tous les enfants (et est donc vraiment totalement inutile, comme mon chat) et on ajoute un offset de 4, pour commencer au 4ème enfant.
Du beau CSS facile à lire somme toute ma foi.
Il est donc possible de travailler de cette manière:
HTML:
<section>
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
</section>
CSS:
section {
/* C'est juste pour avoir une liste verticale */
display: grid;
grid-template-columns: minmax(150px, 1fr);
row-gap: 2rem;
}
.block {
/* A styler pour être un beau BLOC */
padding: 1rem;
background-color: deeppink;
}
@media (max-width: 600px) {
.block:nth-child(1n+4) {
display: none;
}
}
@media (min-width: 600px) and (max-width: 850px) {
.block:nth-child(1n+6) {
display: none;
}
}
Méthode 3 — Sélecteurs "nth" avec PLUS DE POIVRE
Je sais pas pourquoi quelqu'un un jour s'est dit que ce serait trop bien d'ajouter un sélecteur :not() qui inverse... Des trucs que tu mets dans sa parenthèse, parce que les CSS c'était un peu trop clair et facile à navigueur comme ça, un petit supplément de curry vert à la Gordon Platinum ce serait pas mal.
Peut-être que c'était juste pour ajouter un argument à la fameuse cause humanitaire du "HTML et CSS sont des langages de programmation".
Reste à voir si vous trouvez cette notation plus claire:
HTML:
<section>
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
</section>
CSS:
section {
/* C'est juste pour avoir une liste verticale */
display: grid;
grid-template-columns: minmax(150px, 1fr);
row-gap: 2rem;
}
.block {
/* A styler pour être un beau BLOC */
padding: 1rem;
background-color: deeppink;
}
@media (max-width: 600px) {
.block:not(:nth-child(-n+3)) {
display: none;
}
}
@media (min-width: 600px) and (max-width: 850px) {
.block:not(:nth-child(-n+5)) {
display: none;
}
}
Ouais donc la formule magique maintenant y a un gros "SIGNE MOINS" dedans et euh... Si on prend :nth-child(-n+3) ça voudrait dire, si tout se passe bien, qu'on sélectionne le 3ème élément et ceux d'avant.
Logique? Oui? **bruit de slip qui craque**
Et puis ben on veut cacher tout ce qui n'est pas le 3ème élément et ceux d'avant, d'où le fameux :not() qui va bien.
Me remerciez pas. Non vraiment, j'ai honte.
Méthode 4 — Le COMBINATEUR DE VOISIN DIRECT, dit aussi: méthode de merde
Après avoir vu la "méthode" précédente, on se dit que ça peut pas être pire, qu'il ne peut pas exister encore 15000 autres manières encore plus tordues d'avoir le même résultat.
C'est moche de voir son innocence se briser tel un neutron tout sec entrant dans un atome d'Uranium 235 et pourtant pas aussi moche que la technique que je vais vous présenter.
Il y a un COMBINATEUR (oui j'avais pas encore parlé de ceux-là) que, bien évidemment, personne n'utilise (je crois voir se dessiner un genre de tendance ici) qui permet de sélectionner un élément qui serait juste après un autre en tant que voisin direct.
Par exemple:
p + p {
color: deeppink;
}
Sélectionne tous les éléments "p" qui ont un élément "p" juste avant eux. Les deux ayant le même parent (on dit qu'ils sont frères/soeurs).
Oui c'est pas très clair un peu comme un qualia, vous devez le vivre/ressentir pour le comprendre. C'est comme si j'essayais de vous expliquer ce que ça sent la Cancoillotte vieillie en Tupperware ça va être compliqué sans ouvrir le dit Tupperware et forcer votre nez dedans. Comme pour les CSS quoi.
Je vais essayer d'expliquer un peu autrement pour la science: si je veux sélectionner tous les éléments (du même parent donné) avec la classe ".block" qui ont trois autres éléments avec la classe ".block" juste avant (relisez cette phrase deux ou trois fois sans cligner des yeux) je peux écrire cette beauté:
.block + .block + .block + .block {
display: none;
}
Les trois premiers ".block" de la liste n'ont pas trois éléments avec la classe ".block" juste avant. Donc ils sont pas sélectionnés. Cool, c'est ce que je voulais.
On en arrive à ceci pour le même résultat:
HTML:
<section>
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
</section>
CSS:
section {
/* C'est juste pour avoir une liste verticale */
display: grid;
grid-template-columns: minmax(150px, 1fr);
row-gap: 2rem;
}
.block {
/* A styler pour être un beau BLOC */
padding: 1rem;
background-color: deeppink;
}
@media (max-width: 600px) {
.block + .block + .block + .block {
display: none;
}
}
@media (min-width: 600px) and (max-width: 850px) {
.block + .block + .block + .block + .block + .block {
display: none;
}
}
On peut aller aussi loin qu'on veut dans ces mangifiques chaines de combinateurs "+". Je suis sûr que certains trouveront que cette technique est la plus claire et c'est pour ça qu'on utilise la démocratie représentative, parce que la plupart des gens sont bizarres.
Méthode 5 — Sélecteur-de-voisins-qui-a-du-sens
On dirait peut-être pas comme ça parce que le titre est pourri mais c'est pour moi la méthode qui a le plus de sens.
Il existe un sélecteur qui, lui, est parfois utilisé (je l'ai déjà vu en tous cas) et permet de sélectionner tous les éléments Y qui suivent un autre élément X ayant tous le même parent commun — C'est aussi un sélecteur de frères/soeur comme le maudit "+".
Et ça c'est bien pratique! Il suffit de chopper le Nème élément de la liste avec un sélecteur de type :nth-child, puis utiliser le sélecteur "~" pour sélectionner tous les éléments de la liste qui suivent celui-là.
Le tout appliqué pour notre exemple ci-dessous.
HTML:
<section>
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
</section>
CSS:
section {
/* C'est juste pour avoir une liste verticale */
display: grid;
grid-template-columns: minmax(150px, 1fr);
row-gap: 2rem;
}
.block {
/* A styler pour être un beau BLOC */
padding: 1rem;
background-color: deeppink;
}
@media (max-width: 600px) {
.block:nth-child(3) ~ .block {
display: none;
}
}
@media (min-width: 600px) and (max-width: 850px) {
.block:nth-child(5) ~ .block {
display: none;
}
}
Vous pourriez même utiliser une classe spéciale qui délimite l'endroit où vous souhaitez commencer à cacher les éléments, et répliquer la même technique.





Commentaires
Il faut JavaScript activé pour écrire des commentaires ici