web-dev-qa-db-fra.com

Comment créer une grille 3x3 via CSS?

Étant donné 9 divs l'un après l'autre, je veux créer une grille 3X3 via CSS.

Comment je fais ça?

.cell {
  height: 50px;
  width: 50px;
  background-color: #999;
  display: inline-block;
}

.cell:nth-child(3n) {
  background-color: #F00;
  /* what property should I use to get a line break after this element? */
}

/* this doesn't work; at least not in safari */
.cell:nth-child(3n)::after {
  display: block;
}
<div class="grid">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>


Remarque: Je ne veux pas de solution float/clear. L'accent est mis sur CSS et non sur la restructuration HTML.

Si j'ajoute content: '\A'; white-space: pre; à ::after, la sortie s'avère être laide.

.cell {
  height: 50px;
  width: 50px;
  background-color: #999;
  display: inline-block;
}

.cell:nth-child(3n) {
  background-color: #F00;
  /* what property should I use to get a line break after this element? */
}

.cell:nth-child(3n)::after {
  display: inline;
  content: '\A';
  white-space: pre;
}
<div class="grid">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

Comment puis-je obtenir tous les div dans une mise en page 3X3 ligne-colonne?

16
user900360

Cette disposition est simple avec CSS flexbox. Aucune modification en HTML.

.grid {
  display: flex;                       /* establish flex container */
  flex-wrap: wrap;                     /* enable flex items to wrap */
  justify-content: space-around;
  
}
.cell {
  flex: 0 0 32%;                       /* don't grow, don't shrink, width */
  height: 50px;
  margin-bottom: 5px;
  background-color: #999;
}
.cell:nth-child(3n) {
  background-color: #F00;
}
<div class="grid">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>


Avantages de la flexbox:

  1. code minimal; très efficace
  2. le centrage, à la fois verticalement et horizontalement, est simple et facile
  3. Les colonnes de hauteur égale sont simples et faciles
  4. plusieurs options pour aligner les éléments flexibles
  5. c'est réactif
  6. contrairement aux tables flottantes et aux tables, qui offrent une capacité de disposition limitée car elles n'ont jamais été conçues pour la construction de bâtiments, la flexbox est une technique moderne (CSS3) avec un large éventail d'options.

Pour en savoir plus sur la flexbox, visitez:


Support du navigateur:

Flexbox est pris en charge par tous les principaux navigateurs, sauf IE <10 . Certaines versions de navigateur récentes, telles que Safari 8 et IE10, nécessitent le préfixe du vendeur . Pour ajouter rapidement des préfixes, utilisez Autoprefixer . Plus de détails dans cette réponse .

14
Michael_B

Maintenant que CSS Grid is équitablementtrès bien pris en charge , je pensais compléter la réponse par une solution plus moderne.

.grid {
  display: grid;
  grid-gap: 1px;
  grid-template-columns: repeat(3, 1fr);
}

div > div {
  padding: 10px;
  background-color: #ccc;
}
<div class="grid">
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>
  <div>item</div>  
</div>

9
Andy Hoffman

Outre Excellente réponse de @Michael_B à utiliser flexbox, vous pouvez utiliser

  • Tables CSS

    ou

  • float: left  

    tous les deux pour supporter les anciens navigateurs tels que IE 8/9, que flexbox ne supportera pas.

Remarque IE8 ne prend pas en charge nth-child mais prend en charge first/last-child

Option1 (Tableaux CSS): avec modifications du code HTML, encapsulant chaque 3 cellules dans une ligne.

.grid {
  display: table;
  border-spacing: 5px
}
.row {
  display: table-row
}
.cell {
  width: 50px;
  height: 50px;
  background: grey;
  display: table-cell;
}
.row div:last-child {
  background: red
}
<div class="grid">
  <div class="row">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
  <div class="row">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
  <div class="row">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
</div>


Mettre à jour

Option2 (float:left): sans modification du code HTML, en utilisant clear:left pour chaque élément (4ème) n.

.cell {
  width: 50px;
  height: 50px;
  background: grey;
  float: left;
  margin: 5px
}
.cell:first-child + div+ div,
.cell:first-child + div+ div + div + div + div,
.cell:first-child + div+ div + div + div + div + div + div + div {
  background: red
}
.cell:first-child + div+ div + div,
.cell:first-child + div+ div + div + div + div + div,
.cell:first-child + div+ div + div + div + div + div + div + div + div {
  clear: left
}
<div class="grid">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

7
dippas

Juste pour en ajouter un autre, vous pouvez également créer une grille 3x3 en utilisant un seul <div>. Plunker

HTML:

<div class="grid"></div>

CSS:

.grid {
  width: 50px; height: 50px;
  background-color: red;
  border-top: 50px solid red;
  border-bottom: 50px solid red;
  margin: 0 50px;
  position: relative;
  box-shadow: inset 0 4px 0 -2px white,
              inset 0 -4px 0 -2px white;
}
.grid::before {
  content: '';
  width: 50px; height: 50px;
  background-color: red;
  border-top: 50px solid red;
  border-bottom: 50px solid red;
  margin: 0;
  position: absolute; left: -52px; top: -50px;
  box-shadow: inset 0 4px 0 -2px white,
              inset 0 -4px 0 -2px white;
}
.grid::after {
  content: '';
  width: 50px; height: 50px;
  background-color: red;
  border-top: 50px solid red;
  border-bottom: 50px solid red;
  margin: 0;
  position: absolute; right: -52px; top: -50px;
  box-shadow: inset 0 4px 0 -2px white,
              inset 0 -4px 0 -2px white;
}
3
C14L

Je sais que la question demande une solution claire non flottante, mais après avoir essayé la solution flexbox, j’ai constaté qu’elle ne préservait pas la largeur de mes éléments. Cependant, dans le cas spécifique d’une grille 3x3 (par opposition à une grille de n rangées sur trois), une solution de type float clear plus concise et qui fonctionne bien. Voici au cas où d’autres trouveraient cette réponse en cherchant une solution comme je l’ai fait:

.cell {
  float: left;
  height: 100px;
  width: 100px;
  margin: 5px;
}
.cell:nth-child(4) {
  clear: left;
}
.cell:nth-child(7) {
  clear: left;
}
0
Bjornicus