web-dev-qa-db-fra.com

Comment créer une vue grille/mosaïque?

Par exemple, j'ai une classe .article et je veux voir cette classe comme une vue de grille. Alors j'ai appliqué ce style:

.article{
  width:100px;
  height:100px;
  background:#333;
  float:left;
  margin:5px;
}

Ce style donnera l’aspect .article en mosaïque/grille. Cela fonctionne bien avec une hauteur fixe. Mais si je veux régler la hauteur sur auto (automatiquement étirer en fonction des données qu’elle contient), la grille a un aspect désagréable. 

enter image description here

Et je veux faire la vue comme ça:

enter image description here

113
Ariona Rian

Ce type de structure s’appelle Maçonnerie. La maçonnerie est une autre disposition de la grille, mais elle remplira les espaces blancs causés par la différence de hauteur des éléments.

jQuery Masonry est l’un des plug-ins jQuery permettant de créer un modèle de maçonnerie.

Vous pouvez également utiliser CSS3 column s. Mais pour l'instant, le plugin basé sur jQuery est le meilleur choix car il y a un problème de compatibilité avec la colonne CSS3.

75
bookcasey

Vous pouvez utiliser flexbox.

  1. Placez vos éléments dans un conteneur flex de colonne multiligne

    #flex-container {
      display: flex;
      flex-flow: column wrap;
    }
    
  2. Réorganisez les éléments afin que l'ordre DOM soit respecté horizontalement et non verticalement. Par exemple, si vous voulez 3 colonnes,

    #flex-container > :nth-child(3n + 1) { order: 1; } /* 1st column */
    #flex-container > :nth-child(3n + 2) { order: 2; } /* 2nd column */
    #flex-container > :nth-child(3n + 3) { order: 3; } /* 3rd column */
    
  3. Forcer un saut de colonne avant le premier élément de chaque colonne:

    #flex-container > :nth-child(-n + 3) {
      page-break-before: always; /* CSS 2.1 syntax */
      break-before: always;  /* New syntax */
    }
    

    Malheureusement, tous les navigateurs ne prennent pas encore en charge les sauts de ligne dans flexbox. Cela fonctionne sur Firefox, cependant.

#flex-container {
  display: flex;
  flex-flow: column wrap;
}

#flex-container > :nth-child(3n + 1) { order: 1; } /* 1st column */
#flex-container > :nth-child(3n + 2) { order: 2; } /* 2nd column */
#flex-container > :nth-child(3n + 3) { order: 3; } /* 3rd column */

#flex-container > :nth-child(-n + 3) {
  page-break-before: always; /* CSS 2.1 syntax */
  break-before: always;  /* New syntax */
}

/* The following is optional */
#flex-container > div {
  background: #666;
  color: #fff;
  margin: 3px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 36px;
}
#flex-container > :nth-child(1) { height: 100px; }
#flex-container > :nth-child(2) { height: 50px; }
#flex-container > :nth-child(3) { height: 75px; }
#flex-container > :nth-child(4) { height: 50px; }
#flex-container > :nth-child(5) { height: 100px; }
#flex-container > :nth-child(6) { height: 50px; }
#flex-container > :nth-child(7) { height: 100px; }
#flex-container > :nth-child(8) { height: 75px; }
#flex-container > :nth-child(9) { height: 125px; }
<div id="flex-container">
  <div>1</div><div>2</div><div>3</div>
  <div>4</div><div>5</div><div>6</div>
  <div>7</div><div>8</div><div>9</div>
</div>

25
Oriol

Maintenant que CSS3 est largement disponible et compatible via les principaux navigateurs, il est temps de passer à une solution pure équipée de l'outil d'extraits de SO:


Pour créer une mise en page maçonnerie à l'aide de CSS3, le column-count ainsi que le column-gap suffiraient. Mais j'ai aussi utilisé media-queries pour le rendre réactif.

Avant de vous plonger dans l'implémentation, veuillez considérer qu'il serait beaucoup plus sûr d'ajouter une solution de secours jQuery Masonry pour rendre votre code compatible avec le navigateur hérité, spécialement IE8-:

<!--[if lte IE 9]>
    <script src="/path/to/js/masonry.pkgd.min.js"></script>
<![endif]-->

Et c'est parti:

.masonry-brick {
    color: #FFF;
    background-color: #FF00D8;
    display: inline-block;
    padding: 5px;
    width: 100%;
    margin: 1em 0; /* for separating masonry-bricks vertically*/
}

@media only screen and (min-width: 480px) {
    .masonry-container {
        -moz-column-count: 3;
        -webkit-column-count: 3;
        column-count: 3;
    }
}

@media only screen and (min-width: 768px) {
    .masonry-container {
        -moz-column-count: 4;
        -webkit-column-count: 4;
        column-count: 4;
    }
}

@media only screen and (min-width: 960px) {
    .masonry-container {
        -moz-column-count: 5;
        -webkit-column-count: 5;
        column-count: 5;
    }
}
<div class="masonry-container">
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
   <div class="masonry-brick">Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 Masonry pure CSS3 </div>
</div>

9
Behrad Khodayar

La meilleure option pour résoudre ce problème avec css uniquement consiste à utiliser la propriété css column-count.

 .content-box {
   border: 10px solid #000000;
   column-count: 3;
 }

Vérifiez ceci pour plus d’informations: https://developer.mozilla.org/en/docs/Web/CSS/column-count

4

Avec le CSS Grid Module vous pouvez créer une présentation très similaire.

Démo CodePen

1) Définir trois colonnes de grille de largeur fixe

ul {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  ...
}

2) Assurez-vous que les articles de grande hauteur couvrent 2 rangées

li:nth-child(1),
li:nth-child(3),
li:nth-child(5),
li:nth-child(8),
li:nth-child(9),
li:nth-child(10),
li:nth-child(12)
{
  grid-row: span 2;
}

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-gap: 1rem;
  justify-content: center;
  align-items: center;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 85vh;
  margin: 4vh auto;
  border: 5px solid green;
  padding: 1rem;
  overflow: auto;
  counter-reset: item;
}
li {
  position: relative;
}
li:after {
  content: counter(item);
  counter-increment: item;
  position: absolute;
  padding: 0.3rem;
  background: salmon;
  color: white;
  left:0;
  top:0;
}
img {
  outline: 5px solid salmon;
}
li:nth-child(1),
li:nth-child(3),
li:nth-child(5),
li:nth-child(8),
li:nth-child(9),
li:nth-child(10),
li:nth-child(12)
{
  grid-row: span 2;
}
<ul>
  <li><img src="http://lorempixel.com/150/150/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/50/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/140/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/80/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/220/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/120/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/70/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/200/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/230/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/240/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/130/animals" alt="" /></li>
  <li><img src="http://lorempixel.com/150/160/animals" alt="" /></li>
</ul>

Démo Codepen

Les problèmes:

1
Danield

Vous pouvez utiliser display: grid

par exemple:

Ceci est une grille avec 7 colonnes et vos lignes ont une taille automatique.

.myGrid{
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
      grid-auto-rows: auto;
      grid-gap: 10px;
      justify-items: center;
}

Pour plus de détails, accédez au lien suivant: https://css-tricks.com/snippets/css/complete-guide-grid/

1
vrbsm

et si vous voulez aller encore plus loin que la maçonnerie, utilisez isotope http://isotope.metafizzy.co/ c'est la version avancée de la maçonnerie (développée par le même auteur). Elle n'est pas du pur CSS, elle utilise l'aide de Javascript mais il est très populaire, vous trouverez donc beaucoup de docs

si vous trouvez cela très compliqué, de nombreux plugins premium fondent déjà leur développement sur l'isotope, par exemple les Media Box http://codecanyon.net/item/media-boxes-responsive-jquery-grid/5683020

1
user1978456

Il existe un exemple basé sur une grille.

.grid-layout {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  grid-gap: 10px;
  grid-auto-rows: minmax(100px, auto);
  grid-auto-flow: dense;
  padding: 10px;
}

.grid-layout .item {
  padding: 15px;
  color: #fff;
  background-color: #444;
}

.span-2 {
  grid-column-end: span 2;
  grid-row-end: span 2;
}

.span-3 {
  grid-column-end: span 3;
  grid-row-end: span 4;
}
<div class="grid-layout">
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item span-3">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item span-2">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item span-3">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item span-2">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
    <div class="item">content</div>
</div>

basé sur ce codede Rachel Andrew F.T.W

0
Vladimir Ishenko