web-dev-qa-db-fra.com

Galerie d'images responsive utilisant CSS flexbox ou grid-layout

Je travaille sur un widget Galerie d'images où l'utilisateur peut définir la largeur, la hauteur et la marge des vignettes (entre les vignettes) et le widget présentera toutes les colonnes de l'image dans une grille de Nice dans laquelle chaque image a la même largeur et la même hauteur. 

Je me demande si css-flexbox ou css-grid rend cela possible sans qu'il soit nécessaire de définir des lignes et des colonnes dans le code et sans recourir à des points d'arrêt/requêtes média.

Thumbnail-Les images sont enveloppées dans une ancre, ainsi un élément de la galerie (ou un élément de la grille) ressemblera à quelque chose comme ceci:

<a href="#" class="gallery-item">
    <img src="myimage" width="300" height="200" />
</a>

Les éléments de la galerie doivent remplir entièrement le div de conteneur, ce qui signifie qu’il ne doit pas y avoir de décalage entre la dernière vignette d’une rangée et le bord droit de la div de conteneur (sauf si nous n’avons pas assez d’éléments pour remplir la ligne, c-à-d lorsque 3 éléments dans une rangée, mais nous n’avons que 8 éléments, la 3ème rangée ne comportera que 2 éléments et un espace à droite aussi large qu’un élément).

Les éléments de la galerie ne peuvent jamais être plus larges que la largeur de vignette définie par l'utilisateur, car nous ne voulons pas dégrader la qualité des vignettes. Supposons une largeur de 300 pixels pour cet exemple. La marge entre les éléments de la galerie est fixée et définie par l'utilisateur. S'il ne reste plus assez d'éléments pour remplir une ligne, il suffit simplement de les aligner, par exemple:

 enter image description here

Je ne veux pas définir de points d'arrêt dans CSS ni ajouter de code HTML pour les constructions ligne/colonne. Je veux que le navigateur place simplement autant d'objets de la galerie côte à côte que nécessaire dans le conteneur. S'il y a un espace à droite (c.-à-d. 3 miniatures * 300px width = 900px, mais le conteneur a une largeur de 1000px), le navigateur doit redimensionner les éléments de la grille, de sorte qu'un autre élément de la galerie s'intègre et supprime ainsi l'espace. Je dois pouvoir définir une marge autour de chaque élément de la galerie.

Vous pouvez voir le comportement réactif souhaité (lorsque vous modifiez la largeur du navigateur) dans ce gif: 

 Desired responsive behaviour

Ce que vous voyez dans le gif se fait sans flexbox mais nécessite une tonne de CSS que j'espérais éviter avec flexbox. J'ai fait quelques recherches sur la flexbox, mais je n'ai pas encore réussi à bien comprendre.

Merci pour tous les conseils!

5
zıəs uɐɟəʇs

L'utilisation de flex devrait suffire à votre tâche. Soyez conscient du support partiel dans IE11: http://caniuse.com/#feat=flexbox .

Mettez ces styles sur votre conteneur:

.gallery {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  justify-content: space-between;
}

Styles pour les wrappers:

.gallery a {
  flex-grow: 1;
  flex-basis: 125px;
  max-width: 300px;
  margin: 5px;
}

Styles pour les images:

.gallery img {
  height: 100%;
  width: 100%;
}

L'espace entre les images peut être simplement défini à l'aide de margin. Afin de préserver le rapport des images, vous pouvez utiliser, par exemple, des liens (<a>) comme wrappers pour des images (<img>).

En outre, pour éviter d’agrandir les images, vous pouvez appliquer les attributs flex-grow, flex-basis et max-width aux ancres. Il y avait aussi un problème d’agrandissement des images dans la dernière ligne - le hack utilisé consiste à mettre n - 1 (où n est également nombre d'images) éléments vides à l'intérieur du conteneur.

Si vous définissez width et height sur 100% sur les images, cela leur permet de croître automatiquement jusqu'à la largeur définie par l'attribut max-width, tout en conservant les proportions.

Veuillez vérifier l’exemple de travail: FIDDLE

11
luke

Si cela ne vous dérange pas d'utiliser des points d'arrêt multimédias, utilisez new CSS Grid Layout . N'oubliez pas de le préfixer pour la prise en charge d'IE10 +.

La grille:

.gallery {
    display: grid;
    grid-gap: 5px;
}

Images sensibles:

.gallery img {
    width: 100%;
}

Points d'arrêt des médias (valeurs extraites de Bootstrap 4)

@media (max-width: 575.98px) {
    .gallery {
        grid-template-columns: repeat(1, 1fr);
    }
}
@media (max-width: 768.98px) and (min-width: 576px) {
    .gallery {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (max-width: 991.98px) and (min-width: 768px) {
    .gallery {
        grid-template-columns: repeat(3, 1fr); 
    }
}
@media (max-width: 1199.98px) and (min-width: 992px) {
    .gallery {
        grid-template-columns: repeat(4, 1fr); 
    }
}
@media (min-width: 1200px) {
    .gallery {
        grid-template-columns: repeat(5, 1fr); 
    }
}

jsFiddle

1
midzer