Container query

Alors voilà, ici même sur ce blog et quand c’est affiché sur un écran assez grand, comme sur un laptop, les images possédant une légende et pouvant être affichées en grand (avec un clic dessus) sont affichées sans légende visible.

Celle-ci ne l’est qu’au survol — sauf si l’appareil utilisé ne permet pas le survol car dans ce cas la légende est affichée en dessous de l’image, comme sur petit écran.

Ça fonctionne très bien et c’est en œuvre depuis des années ici-même, regardez et survolez l’image avec votre souris préférée :

Grande marée à Saint-Guénolé
Jour de grande marée aux rochers à Saint-Guénolé, mars 2024

Là où ça pose problème c’est lorsque l’image n’est pas suffisamment grande, je parle de celle affichée par défaut pas celle affichée lorsqu’on clique dessus, et que la légende au survol vient recouvrir la totalité d’icelle, il n’est plus alors possible de cliquer sur l’image pour afficher l’originale. Saynul n’est-ce pas ?

Voyez plutôt sur cet exemple :

© Julien Malland alias Seth
© Julien Malland alias Seth, mars 2022, rue Buot dans le 13e arrondissement de Paris, mars 2024

Pas moyen de trouver un pixel ou deux pour cliquer et agrandir l’image ! Ou alors en visant super bien vers le bas, mais bof bof, spa pratique du tout !

Je me suis donc dit que ça ne pouvait durer et que dans ce cas il serait opportun de traiter l’affichage de la légende de la même manière que sur mobile ou sur les appareils ne permettant pas le survol.

J’ai donc bricolé un peu de CSS, à base de container query, c’est tout nouveau ça vient de sortir, et à ce qu’il me semble ça devrait me permettre de résoudre le problème énoncé de la manière suivante : Si le conteneur de l’image (un élément figure) a une hauteur inférieure à disons 100 pixels alors il faut traiter la légende de l’image comme si elle était affichée sur mobile (ou sur un appareil sans survol possible).

Voilà le code que j’ai imaginé :

:root {
  --glass-lightness: 0%;
  --glass-text: white;
}
figure {
  position: relative;
  display: block;
  container-name: my-figure;
  container-type: size;
}
figure figcaption {
  font-size: 0.75em;
  position: absolute;
  width: fit-content;
  top: 0;
  padding: 1em;
  transition: 0.6s ease;
  opacity: 0;
  --glass-lightness: 0%;
  --glass-text: white;
  color: var(--glass-text);
  background: hsl(0 0% var(--glass-lightness) / 66%);
  backdrop-filter: blur(40px);
}
figure:hover figcaption {
  opacity: 1;
}
@media (any-hover: none) {
  figure figcaption {
    opacity: 1;
    position: relative;
    width: 100%;
  }
}
@container my-figure (max-height: 100px) {
  figure figcaption {
    opacity: 1;
    position: relative;
    width: 100%;
  }
}

Eh bien moi qui pensais avoir tout bien compris à cette nouvelle possibilité de CSS, ça ne fonctionne pas ! D’ailleurs j’ai même un petit codepen pour illustrer et jouer avec.

Vous savez ce que j’ai fait de travers ?

PS : J’ai demandé à Ahmad Shadeed qui est justement en train d’écrire un article sur cet aspect s’il savait ce que j’avais foiré, mais je n’ai pas encore eu de réponse.


Finalement j’ai ajouté quelques lignes de javascript et ça fera le job puisqu’il n’y a pas de solution évidente pour régler ce problème :


// Cope with figure img smallest than figcaption (avoid full overlay) const figures = document.querySelectorAll('#content figure'); figures?.forEach((figure) => { const img = figure.querySelector('img'); const figcaption = figure.querySelector('figcaption'); if (!(img && figcaption && figcaption.offsetHeight <= img.offsetHeight + 44)) { return; } figcaption.style.position = 'relative'; figcaption.style.opacity = 1; figcaption.style.width = '100%'; });

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/16022

Haut de page