28112 sujets

CSS et mise en forme, CSS3

Bonjour,

Dans le très bon livre de Raphaël sur les Flexbox, on trouve un exemple de galerie d'images.

Mon problème est un peu plus compliqué car mes images sont légendées par quelques mots.

L'objectif est d'atteindre la disposition simple et fluide de ce site, mais avec si possible un code plus simple.

Ici chaque image / Legende est comprise dans un <ul> en display inline-block.
Sont imposées la largeur de <ul> et la hauteur du <li> contenant l'image, tout le reste est libre, notamment la longueur de la légende qui peut prendre plusieurs lignes sans nuire à l'alignement.

je me demande s'il est possible d'obtenir le même résultat en Flexbox avec un code plus simple.

<ul id="galerie">
<li><a><img src"image_1.jpg" /></a><a>Légende pour image 1</a></li>
<li><a><img src"image_2.jpg" /></a><a>Légende pour image 2</a></li>
etc...
</ul>

Je ne suis pas spécialiste de Flexbox mais j'en utilise quelques-unes, bref je connais les bases mais je cale devant ce problème.
Modérateur
Integrator a écrit :
Quel intérêt/avantage de le faire dans un &lt;ul&gt; ?

C'est une liste d'image

@boteha_2


<ul id="galerie">
	<li>
		<a>
			<figure>
				<img src="image.jpg" alt="" />
				<figcaption>Légende associée</figcaption>
			</figure>
		</a>
	</li>
	<li>
		<a>
			<figure>
				<img src="image.jpg" alt="" />
				<figcaption>Légende associée</figcaption>
			</figure>
		</a>
	</li>
</ul>

- l'élément <figure>
- l'attribut alt n'est obligatoire mais recommandé.... Je dirai la même chose pour le href....

Je te laisse nous envoyer ton code css
Smiley cligne
Modifié par niuxe (29 Sep 2018 - 12:12)
Bonjour,

Merci de vos réponses.

Je ne connaissais pas l'élément figure.

Je vais creuser de ce côté.
Bonjour,

figure est intéressant et sémantique mais je ne pense pas qu'il puisse m'aider car pour obtenir l'effet voulu il faut pour l'image un container indépendant de celui la légende.

Avec ul :

<ul><li><a href="lien"><img src="im.gif" alt="Mini DIN 6 broches Femelle" width="55" height="50" /></a></li>
<li><a href="lien">Mini DIN 6 broches Femelle</a></li></ul>

ul {display: inline-block}
// Je donne une largeur à l'ul et une hauteur à li:first-child
ul {width: 250px}
li:first-child {heigth: 200px}
// Je centre l'image dans son container
li img {margin: auto}


Avec figure, je ne peux plus avoir l'équivalent de li:first-child {heigth: 200px}.
Si je donne une hauteur à figure, cette hauteur va concerner aussi <figcaption>Légende associée</figcaption>, or cet élément doit être de hauteur variable selon la longueur du texte.

Ou peut-être si ce code est possible :

<li>
<figure>
<a href="lien"><img src="image.jpg" alt="Mini DIN 6 broches Femelle" width="55" height="50" /><a>
<figcaption><a href="lien">Mini DIN 6 broches Femelle</a></figcaption>
</figure>
</li>

li {display: inline-block}
// Je donne une largeur à li et une hauteur à figure > a que je passe en display block
li {width: 250px}
figure > a {display:  block; heigth: 200px}
// Je centre l'image dans son container
a img {margin: auto}


Je ne sais pas si ce code est correct et pertinent.
Je vais essayer.
je me demande si ce ne serait plus simple en flexbox.
Modifié par boteha_2 (30 Sep 2018 - 14:59)
Bonjour,

Pour info il est possible de s'en sortir avec le code html de base, sans figure.

Niveau css c'est un peu compliqué mais fiable.

<ul id=gallerie>
<li>
<a href="lien"><img src="image.jpg" alt="Mini DIN 6 broches Femelle" width="55" height="50" /><a>
<a href="lien">Mini DIN 6 broches Femelle</a>
</li>
<li>
<a href="lien_2"><img src="image_2.jpg" alt=" DIN 12 broches Femelle" width="75" height="70" /><a>
<a href="lien_2"> DIN 12 broches Femelle</a>
</li>
etc...
</ul>

li {display: inline-block; text-align: center; vertical-align: top; text-indent: 0}
// Ne pas oublier de mettre text-indent à 0 car la plupart des navigateurs appliquent un text-indent à inline-block
li {width: 200px}
// Choisissez votre largeur
a {display: block}
li a:first-child {height: 100px; position: relative}
// Choisissez la hauteur du container de l'image
img {position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto}
// pour centrer l'image


Je ne coche pas résolu, j'attends suggestions pour le même résultat en flexbox, si possible.
Modérateur
Voilà la réponse avec flex. Cela fit, je t'encourage à lire la doc de Raphaël sur le sujet.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body, ul, li, figure{
            padding: 0;
            margin: 0;
        }
        a{
            display: block;
        }
        #galerie{
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-start; /*space-between ? */
            list-style: none;
        }
        #galerie li{
            width: calc(25% - 3px);
            margin-right: 3px;
        }

        #galerie li figure img{
            display: block;
            width: 100%;
        }
        #galerie li figure figcaption{
            text-align: center;
        }
    </style>
</head>
<body>
    <ul id="galerie">
    	<li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
    	<li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a>
    			<figure>
    				<img src="https://picsum.photos/300?random" alt="" />
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
    </ul>
</body>
</html>
Modérateur
En version inline block. Si tu veux centrer tes images, tu les entours d'une span qui sera en position relative et les images en absolute. Tu utiliseras transform aussi pour avoir un résultat convaincant. Overflow hidden te sera peut être utile.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    body, ul, li{
        padding: 0;
        margin: 0;
    }
    ul{
        list-style: none;
        font-size: 0; /*evite cette bidouille de text indent...*/
    }
    li {display: inline-block; text-align: center; vertical-align: top;width: 25% ; font-size: 16px;}
    a {display: block}
    img {display: block;width: 100%;}
    </style>
</head>
<body>
    <ul id=gallerie>
        <li>
            <a href="lien"><img src="https://picsum.photos/300?random" alt="Mini DIN 6 broches Femelle" /><a>
            <a href="lien">Mini DIN 6 broches Femelle</a>
        </li>
        <li>
            <a href="lien_2"><img src="https://picsum.photos/300?random" alt=" DIN 12 broches Femelle" /><a>
            <a href="lien_2"> DIN 12 broches Femelle</a>
        </li>
    </ul>
</body>
</html>
Avec flexbox, j'aurais plus vu les choses comme ceci pour laisser le navigateur déterminer le nombre d'images par rangée selon la taille des images :
<style>
		body, ul, li, figure{ margin: 0; padding: 0; }
		#galerie {
			list-style: none;
			display: flex;
			flex-wrap: wrap;
			justify-content: start;
		}
		figure { margin: 0.3rem; padding: 0.3rem; background: #aaa; }
		figcaption { text-align:center; }
	</style>

Si on veut imposer un nombre d'images par rangée, il vaut mieux passer par "display: grid"
Quitte à définir grid-template-columns pour chaque type d'écran.

Merci pour le lien vers picsum.photos. Je ne connaissais pas Smiley decu
Modifié par bazooka07 (01 Oct 2018 - 21:34)
Bonjour,

Merci de vos réponses.

Je vais creuser celles en Flexbox, je reviens vers vous en fin de semaine.

Je vais regarder la doc de Raphaël, j'ai déjà lu son livre mais comme je ne pratique pas beaucoup les Flexbox je maîtrise mal et mémorise peu.

Pour l'emploi de display inline block, le code que j'ai donné fonctionne très bien.

Merci à niuxe pour ton travail mais ce que tu proposes ne correspond pas à exactement à l'effet recherché.

Tu donnes une largeur relative au li : width: 25%
L'idée est d'avoir un rendu fluide, donc largeur de 200 px, de façon à en afficher sur la même ligne autant que possible selon la taille de la fenêtre.
Tu mets img en display block et width 100 %. Non, l'image doit garder sa taille normale et être centrée horizontalement et verticalement, ce que je fais en position absolute.

Accessoirement mettre text-indent à 0 dans la déclaration du li en display inline-block n'est pas une bidouille car le comportement par défaut du navigateur est d'appliquer un text-indent (sauf erreur de ma part).
Modifié par boteha_2 (02 Oct 2018 - 15:27)
Essaie avec le style que j'ai donné pour conserver la taille des images quelque soit la largeur de l'écran.
Modérateur
bazooka07 a écrit :

Merci pour le lien vers picsum.photos. Je ne connaissais pas Smiley decu

Il y a beaucoup d'applications dans ce style.

Celui là, tu devrais aimer Smiley smile

placekitten

À une époque pour le texte j'utilisais ceci : jcvd ipsum

Par la suite, j'avais fait un générateur de texte aléatoire avec comme thème humour Chuck Norris.

bazooka07 a écrit :
Avec flexbox, j'aurais plus vu les choses comme ceci pour laisser le navigateur déterminer le nombre d'images par rangée selon la taille des images :
<style>
		body, ul, li, figure{ margin: 0; padding: 0; }
		#galerie {
			list-style: none;
			display: flex;
			flex-wrap: wrap;
			justify-content: start;
		}
		figure { margin: 0.3rem; padding: 0.3rem; background: #aaa; }
		figcaption { text-align:center; }
	</style>

Si on veut imposer un nombre d'images par rangée, il vaut mieux passer par "display: grid"
Quitte à définir grid-template-columns pour chaque type d'écran.

+1 hier soir la fatigue se faisait sentir. J'ai répondu rapidement au sujet. Après en revoyant mon code, il y a juste à fixer des valeurs ou pas. Que ce soit en inline-block, flex ou même float, c'est pas vraiment difficile à faire.
boteha_2 a écrit :

... l'image doit garder sa taille normale et être centrée horizontalement et verticalement, ce que je fais en position absolute.
...


niuxe a écrit :
Si tu veux centrer tes images, tu les entours d'une span qui sera en position relative et les images en absolute. Tu utiliseras transform aussi pour avoir un résultat convaincant. Overflow hidden te sera peut être utile.

Modifié par niuxe (02 Oct 2018 - 12:43)
Bonjour,

Merci de vos réponses.

Pour moi le seul inconvénient de la solution inline-block est de devoir utiliser position absolute pour centrer les images horizotalement ET verticalement dans leur container.

La solution en Flexbox évite-t-elle cette contrainte ?
Modérateur
boteha_2 a écrit :
Bonjour,

Merci de vos réponses.

Pour moi le seul inconvénient de la solution inline-block est de devoir utiliser position absolute pour centrer les images horizotalement ET verticalement dans leur container.

La solution en Flexbox évite-t-elle cette contrainte ?


Que tu utilises float left, display inline-block ou display flex, ça ne changera pas grand chose à ton souci. L'une des clef du css est d'un bien comprendre le comportement de chaque règle et s'imaginer le rendu avant de coder. Smiley cligne

Voilà une solution en full flex !


<ul id="galerie">
        <li>
    		<a href="#">
    			<figure>
    				<span>
                        <img src="https://baconmockup.com/200/100" alt="" />
                    </span>
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
        <li>
    		<a href="#">
    			<figure>
    				<span>
                        <img src="https://baconmockup.com/300/150" alt="" />
                    </span>
    				<figcaption>Légende associée</figcaption>
    			</figure>
    		</a>
    	</li>
    </ul>



body, ul, li, figure{ margin: 0; padding: 0; }
        #galerie {
            list-style: none;
            display: flex;
            flex-wrap: wrap;
            justify-content: start;
        }
        li{
            min-width: 400px;
        }
        figure { margin: 0.3rem; padding: 0.3rem; background: #aaa; display: flex;flex-direction: column;}
        figure span{
            display: flex;
            width: 100%;
            min-height: 200px;
        }
        figure span img{
            margin: auto;
        }
        figcaption { text-align:center; }

Modifié par niuxe (02 Oct 2018 - 18:05)
Bonjour,

niuxe a écrit :

Voilà une solution en full flex !


Merci pour ton code.
Je reste quand même sur ma solution en inline-block qui fonctionne sans bidouille avec une structure html simple.
Dans la version pour petit écran je passe tout en une seule colonne :

@media screen and (max-width: 768px)
{
li {display: block; text-align: left; width: auto}
a {display: table-cell; position: static; height: auto}
img {position: static; margin-right: 20px}
li a:last-child {vertical-align: middle}
}


Là l'emploi de Flexbox permettrait d'aller plus vite.

Encore merci pour cette discussion intéressante.
Bonjour,

Une petite amélioration.
Comme la hauteur du container de l'image est connue, je n'ai pas besoin de position absolute pour centrer l'image.
Il suffit que le line-height du container soit de même taille que la hauteur et que le img soit en vertical-align: middle, comme s'il s'agissait d'un texte.

li a:first-child {height: 100px; line-height: 100px}
li img {vertical-align: middle}


Vous savez tous cela mais perso je pataugeais un peu avec vertical-align: middle en pensant qu'il fallait l'appliquer au parent.

Je reviens plus tard sur une deuxième amélioration. Le sujet n'est pas clos.
Modifié par boteha_2 (21 Oct 2018 - 21:57)
Bonjour,

Avec la structure initiale :

<ul id=gallerie>
<li>
<a href="lien"><img src="image.jpg" alt="Mini DIN 6 broches Femelle" width="55" height="50" /><a>
<a href="lien">Mini DIN 6 broches Femelle</a>
</li>
<li>
<a href="lien_2"><img src="image_2.jpg" alt=" DIN 12 broches Femelle" width="75" height="70" /><a>
<a href="lien_2"> DIN 12 broches Femelle</a>
</li>
etc...
</ul>


<a> étant display block, il occupe tout l'espace, ce qui rend le pointeur actif hors des limites du texte et de l'image.
Cela peut être bien mais pas dans mon cas.
J'ai donc ajouté un container autour du <a> de l'image.

<li>
<span>
<a href="lien"><img src="image.jpg" alt="Mini DIN 6 broches Femelle" width="55" height="50" /><a>
</span>
<a href="lien">Mini DIN 6 broches Femelle</a>
</li>

span {display: block}


C'est le petit changement dont je voulais parler.