27315 sujets

CSS et mise en forme, CSS3

Pages :
Bonjour à tous
la page https://tests.osirisnet.net/docu/centennial/centennial_slideshow.html?fr contient un carrousel d'image avec texte.
J'aimerais faire en sorte que l'image soit la plus grande possible sans excéder les dimensions de l'image originelle.
Actuellement le style de l'image est donnée par

figure.imgbox img {
	max-height:70vh;
	max-width:80vw;
	cursor:pointer;
}

Selon la taille originelle de l'image et la place que prend le texte au dessus, certaines images pourraient être plus hautes.
J'ai fais quelque essais en "flex" avec des images. La seule chose que j'ai déduite de ces essais, c'est que ça déformait les images, c'est pourquoi je les ai mises dans une <figure>

J'ai lu quelques articles sur le sujet, dont https://www.alsacreations.com/astuce/lire/1701-images-responsive-flexbox-bug-ratio.html
A ma grande honte je n'y ai rien compris, alors qu'en général je n'ai pas de problème avec ce qu'écrit Stéphanie W.

Avez vous une meilleur solution à me proposer (et une explication adaptée à mes faibles capacités intellectuelles) ?
Modérateur
Hello,

Je te propose d'essayer simplement :
figure.slide img {
	width: 100%;
	height: 70vh;
	object-fit: contain;
	border-radius: 0.5em;
}


Cela va faire en sorte que ton image avoir un placeholder (80vw de la largeur et 70vh pour ton cas) puis ensuite utiliser la propriété object-fit (équivalent à background-size pour une image qui vient de CSS mais pour une image HTML)

Smiley smile
Merci Yordi. Je ne connaissais pas cette propriété que je vais m’empresser d’utiliser
Mais ça demande que je connaisse la taille restante en hauteur, ce qui n’est pas le cas à cause du texte qui peut faire plusieurs lignes. 70vh est une bonne valeur expérimentale. J’aimerais bien comprendre comment faire mieux
J'ai fait ma modification, mais bien entendu ce n'est pas plus responsive que ce que je voulais obtenir.
Voir https://tests.osirisnet.net/monument/chaproug/@chaproug.html?fr
Sur un petit téléphone, on obtient
upload/1585321529-48769-slideshowv.png
ce qui est le contraire de ce que je veux obtenir.

Dans la version précédente de ce programme, les tailles sont calculées en JavaScript et j'obtiens
upload/1585321892-48769-slideshow-oldv.png
Il doit exister une façon de faire ça en CSS, mais je n'arrive pas à le réaliser.
Modifié par PapyJP (27 Mar 2020 - 16:14)
Salut Papy. Voici une de mes astuces de focus que je tente d'adapter à ton cas (le code dans son contexte : Github) :
.figure.slide div { /* @bugfix @affected All browsers Image en flex item n'a pas son ratio préservé si resize ; une div intermédiaire entre le conteneur .focus-off et l'image corrige ce problème */
    max-width 100% /* @bugfix @affected Firefox */
    margin auto /* pour flexitem */
}

.figure.slide img {
    vertical-align: middle;
    height: auto; /* C'est peut-être ça que tu cherches */
    max-height: 70vh;
    max-width: 100%;
}

Modifié par Olivier C (27 Mar 2020 - 17:22)
Merci de ta réponse, mais toute solution contenant max-height = quelque chose ne peut pas convenir.
J'ai mis 70vh au pif, parce que je n'avais pas trouvé de solution satisfaisante en CSS qui permette de donner à l'image une hauteur max qui ne déborde pas et donc tienne compte de ce qu'il y a au dessus. Ça va sur mon PC, mais pas sur un petit écran.
Sauf à calculer cette valeur en Javascript dynamiquement, et donc à lancer un programme sur les changements d'orientation de l'écran, mais c'est que que j'aimerais ne plus avoir à faire.
Normalement flex est fait pour ça, mais je n'arrive pas à trouver comment.
Si je mets une <div> intermédiaire, flex ne peut pas avoir d'effet sur la taille de l'image, mais seulement sur la taille de <div>. Il ne sert à rien de dire que l'image doit avoir une hauteur de 100% de celle de <div>, car en fait une hauteur obtenue pas flex n'est pas une hauteur sur laquelle on puisse baser quoi que ce soit.
Modifié par PapyJP (27 Mar 2020 - 22:57)
Ok. Pour le conteneur principal tu le passes en display flex et "flex-direction: column", sur le conteneur de l'image tu peux faire un "flex: 1 0 auto" (qui correspond grosso modo à un "flex-grow: 1"), ensuite il faut reprendre le code que j'ai donné plus haut.

Je ne peux pas tester là où je me trouve, mais ça devrait délivrer toute la place disponible pour le conteneur de l'image, en effet c'est la technique flex que l'on utilise pour mettre le footer d'un site en bas de page, même avec une page sans contenu.

Edit : rappel d'une solution flexbox pour le footer : CodePen
Modifié par Olivier C (27 Mar 2020 - 20:38)
En réalité je suis au boulot (infirmier avec le plan blanc pour le coronavirus tu parles !). Mais si j'arrive à m'accorder un petit moment de détente - au pire après mon poste - je me pencherais sur une solution avec un CodePen que je posterais ici.
Modifié par Olivier C (27 Mar 2020 - 19:58)
En attendant j'avais déjà réalisé une solution proche que j'avais oublié, sur CodePen justement : Gallery. Si tu resize la page dans tous les sens tu verras que ça marche.

Mais je viens de me rendre compte : c'est voulu une balise figure inclue dans une autre balise figure pour ton code ? Je crois qu'il vaut mieux commencer par évaluer le html avant toute chose... Edit : Ah oui ce devait être une solution de contournement pour le flexbug.

Rappel d'une solution flexbox pour le footer : CodePen.
Modifié par Olivier C (27 Mar 2020 - 20:49)
Merci de ta réponse
En cherchant bien je devrais retrouver dans ce forum la discussion sur <figure> dans <figure> dont j’ai conclus que c’était préférable aux <div>
Ça fait des années que j’utilise cette technique que je pense sémantiquement logique. Je suis d’accord que ça se discute, mais doit y en avoir plusieurs milliers dans ce site.
Compte tenu de l’heure, je regarde demain car si je m’y mets maintenant je vais y passer la nuit, ce n’est plus de mon âge Smiley biggrin
Modifié par PapyJP (27 Mar 2020 - 22:55)
Bonjour Olivier
Ne disposant pas des outils que tu utilises (j'ai les miens) j'ai essayé de reconstruire le code en plain-HTML, plain-CSS et plain-JavaScript
Je n'ai pas obtenu de résultat satisfaisant.

Sur le fond, il me semble que flex ne peut pas répondre à mes besoins, car s'il permet de donner à un nœud toute la hauteur qui reste, ce n'est pas "réellement" une hauteur. il faut d'une façon ou d'une autre donner en dur la hauteur max ou min.

Je vais donc en revenir au calcul de hauteur par JavaScript.
Administrateur
Bonjour,

oui Flexbox en hauteur a quasi toujours cette limitation de devoir fixer une hauteur.
Ici dans ce contexte ça peut être 100vh pour le tout : bandeau de navigation, numérotation, légende éventuelle, image et l'image récupère la hauteur restante tout en ne créant jamais d'ascenseur vertical.
Si la difficulté est de ne pas déformer l'image, il y a effectivement l'astuce de déclarer à auto soit width soit height mais cela demande de savoir quelques petites choses sur l'image (je crois, genre portrait ou paysage).
Je n'ai pas ouvert les liens d'Olivier C, je limite ma conso de data...

Pour ce qui est de ne pas déformer les (éléments) images, il y a object-fit (pareil que background-size: contain ou cover pour les images de fond). Support Edge 16+ donc "pas IE11", et encore il y a un polyfill très efficace pour le cas d'utilisation simple qui est de loin le plus courant.
Modifié par Felipe (29 Mar 2020 - 13:40)
Merci Felipe
J'ai fait un fichier de test https://tests.osirisnet.net/monument/chaproug/@@chaproug.html?fr
Après pas mal d'essais, je n'arrive pas à le faire fonctionner, et je crois savoir pourquoi:
Voici la structure de la page:

<body>
  <main>
    <header>
       <h1>...</h1>
       <button></button>
       <button></button>
       <button></button>
    </header>
    <figure>
        <figcaption>...figcaption>
        <img...>
    </figure>
  </main>
<body>

Je définis <main> à 100vw/100vh
Si je mets le flex sur <main>, <img> n'est pas un enfant de <main>, donc il n'est pas concerné
Si je mets le flex sur <figure>, <img> est un enfant, mais comme je ne connais pas la hauteur de <figure>, ça ne va pas non plus.

J'en reste donc à ma dizaine de lignes de JavaScript qui marchent depuis longtemps, y compris sur IE11, qui calculent la hauteur de l'image et en prime me permettent de savoir si texte de <figcaption>fait plus d'une ligne, auquel cas je le mets en text-align:justify au lieu de center.
voir https://tests.osirisnet.net/monument/chaproug/@chaproug_slideshow.html?fr
En gros oui
Dans le détail, c'est difficile à dire.
Regarde https://tests.osirisnet.net/monument/chaproug/@chaproug_slideshow.html?fr
Il y a de nombreuses images, la façon de les ajuster dépend de chaque image, il n'est pas question de faire un code différent selon leur taille et leur orientation.
Dans ce fichier, les ajustements se font en JavaScript. J'aurais aimé profité de la refonte de cette partie du site pour faire ça en CSS, mais comme je n'ai pas trouvé comment faire, j'ai repris le code JavaScript de la précédente version
https://tests.osirisnet.net/monument/chaproug/chaproug_slideshow.php?fr
Modérateur
Tu peux faire le test dans le codepen en changeant l'url de l'image. Dans ce cas-ci, cette url (https://i.picsum.photos/id/266/1200/500.jpg) te donne une image de 1200*500. Tu le comprends, tu peux donc simplement changer l'url pour obtenir une image d'autre dimension.

De ma compréhension, cela correspond à ta demande. Le seul point bloquant que je vois est si tu as une image plus petite que la zone disponible, elle sera alors étirée (en gardant son ratio) ? Tu pourras avoir des images pixelisées si tu as des images de faibles qualités.
C'est trop loin de ce que je veux faire pour que je puisse juger si ça convient

J'ai mis le fichier de test ici

Comme j'utilise très peu cet CodePen, je ne sais pas comment ne voir que le résultat, ce qui me permettrait de faire des essais sur écrans de différentes tailles.
Modifié par PapyJP (30 Mar 2020 - 16:29)