web-dev-qa-db-fra.com

Éléments flexibles de même largeur, même après emballage

Est-il possible de faire une solution CSS pure comme celle-ci:

  1. Les articles ont un min-width.
  2. Ils devraient croître dynamiquement pour remplir toute la largeur du conteneur, puis passer à de nouvelles lignes
  3. Tous les éléments de la liste doivent avoir la même largeur.

Voici à quoi cela ressemble maintenant:

enter image description here

Et voici à quoi je voudrais qu'il ressemble aussi (j'ai géré manuellement la largeur de ces éléments inférieurs juste pour montrer le résultat attendu):

enter image description here

.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  background: yellow;
  min-width: 100px;
  height: 20px;
  text-align: center;
  border: 1px solid red;
  flex-grow: 1;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

Voici une démonstration de violon .

29
Adam Szmyd

Actuellement, flexbox n'offre aucune solution propre pour aligner les éléments flexibles dans la dernière ligne ou colonne. Cela dépasse le cadre de la spécification actuelle.

Voici plus d'informations et diverses solutions que les gens ont utilisées pour contourner le problème:

Cependant, l'alignement de la dernière ligne n'est pas un problème avec une autre technologie CSS3, Disposition de la grille . En fait, c'est très simple avec cette méthode (et ne nécessite aucune modification du HTML):

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  grid-auto-rows: 20px;
  grid-gap: 5px;
}

.item {
  background: yellow;
  text-align: center;
  border: 1px solid red;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

démo jsFiddle

Le grid-template-columns La propriété définit la largeur des colonnes définies explicitement. La règle ci-dessus indique au conteneur de grille de créer autant de colonnes que possible (auto-fit), et la largeur de chaque colonne sera au minimum de 100 pixels et au maximum de 1fr, qui consomme l'espace restant (similaire à flex-grow: 1). Lorsqu'il n'y a plus d'espace sur la ligne, une nouvelle ligne est créée.

Le grid-auto-rows La propriété définit la hauteur des lignes créées automatiquement. Dans cette grille, chaque ligne mesure 20 pixels de haut.

Le grid-gap propriété est un raccourci pour grid-column-gap et grid-row-gap. Cette règle définit un intervalle de 10 pixels entre éléments de la grille. Elle ne s'applique pas à la zone entre les articles et le conteneur.

Notez que les paramètres ci-dessus sont tous au niveau du conteneur. Contrairement aux éléments flexibles, nous pouvons supprimer les responsabilités concernant la hauteur, la largeur et la marge (dans une certaine mesure) des éléments de la grille.


Prise en charge du navigateur pour la grille CSS

  • Chrome - prise en charge complète à partir du 8 mars 2017 (version 57)
  • Firefox - prise en charge complète à partir du 6 mars 2017 (version 52)
  • Safari - prise en charge complète à partir du 26 mars 2017 (version 10.1)
  • Edge - prise en charge complète à partir du 16 octobre 2017 (version 16)
  • IE11 - pas de support pour les spécifications actuelles; prend en charge la version obsolète

Voici l'image complète: http://caniuse.com/#search=grid


Fonction de superposition de grille cool dans Firefox: Dans les outils de développement Firefox, lorsque vous inspectez le conteneur de la grille, il y a un petit icône de grille dans la déclaration CSS. Au clic, il affiche un aperçu de votre grille sur la page.

enter image description here

Plus de détails ici: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts

30
Michael_B

Non, il n'y a pas de solution CSS pure. Flexbox essaie toujours de remplir toute la largeur du conteneur avec des éléments pouvant être agrandis. Donc, vous devrez insérer des éléments cachés qui rempliront l'espace vide tout en étant invisible pour l'utilisateur.

Essaye ça:

.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  background: yellow;
  min-width: 100px;
  height: 20px;
  text-align: center;
  border: 1px solid red;
  flex-grow: 1;
}

.item-hidden {
  min-width: 100px;
  flex-grow: 1;
  border: 1px solid transparent;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
</div>

Un problème similaire a été discuté ici: Flex-box: Aligner la dernière ligne sur la grille

À l'avenir, vous pourrez utiliser plusieurs pseudo-éléments :: after, vous n'aurez donc pas besoin d'insérer des éléments supplémentaires dans HTML.

8
Ondra Koupil