22
votes

Comment faire en sorte que les éléments de la dernière ligne utilisent l'espace restant dans CSS Grid?

Existe-t-il un moyen de forcer tous les éléments de la dernière ligne, d'une grille, à remplir la ligne, quel que soit leur nombre?

Je ne connais pas le nombre d'éléments qui seront dans la grille donc je ne peux pas les cibler directement. J'ai essayé d'utiliser le grid-auto-flow: dense , mais cela n'aide pas vraiment.

Voici ma question visualisée: entrez la description de l'image ici :

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>  
</div>
 
div {
  margin:20px auto;
  width: 400px;
  background: #d8d8d8;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(3, 1fr);
}
span {
  height: 50px;
  background: blue;
}


5 commentaires

@ IvanS95 Oh désolé! Mon mauvais :) Ensuite, il doit utiliser les tables correctement 😀


@Ahtisham Je ne recommanderais pas non plus les tables utilisateur, cette mise en page particulière pourrait être mieux réalisée avec Flexbox car OP peut faire en sorte que le dernier élément utilise l'espace restant


@ IvanS95 Qu'en est-il de la création de deux div. Et en gardant la largeur du premier div fixe et plus tard dynamique. ☺️


@Ahtisham qui pourrait être encore plus de travail que d'utiliser simplement flexbox


Je vous recommande d'utiliser flexbox.


4 Réponses :


6
votes

Je ne pense pas que CSS Grid soit la meilleure option pour la mise en page que vous essayez de créer, du moins pas si elle va être dynamique et que vous ne savez pas vraiment combien d'éléments seront sur le conteneur tout le temps. Flexbox est en fait mieux pour les mises en page unidimensionnelles; il peut être un peu plus difficile de tout garder exactement de la même taille et d'utiliser tout l'espace disponible exactement comme vous en avez besoin, mais à la fin, ce type de boîtier est conçu pour Flexbox.

Et bien sûr, vous pouvez utiliser une largeur de 100% en utilisant également quelques calculs sur CSS.

CSS Grid peut être préférable de garder les lignes ET les colonnes alignées, mais c'est un cas différent.

<div class="container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item">6</div>
  <div class="flex-item">7</div>
</div>
.container {
  display: flex;
  flex-wrap: wrap;
  box-sizing: border-box;
}

.flex-item {
  width: 30%;
  border: 1px solid #000;
  flex-grow: 1;
  min-height: 120px;
  box-sizing: border-box;
  margin: 0 5px 10px;
  justify-content: space-between;
  text-align: center;
}


2 commentaires

Merci pour votre réponse. J'utilise la Flexbox pour le secours. Une (et non la seule) raison pour laquelle je me penche sur les grilles est d'utiliser "gap" et d'autres fonctionnalités qui vont avec. Par exemple, même si l'écart peut être simulé par la marge, mais puisque nous ne connaissons pas le nombre d'éléments dans la dernière ligne, se débarrasser des espaces latéraux (sur le côté du conteneur) nécessitera du code supplémentaire.


@Ogdila pas de problème! C'est malheureux, il semble que ce n'est pas possible pour le moment; En fait, je viens de trouver cette autre question avec le même problème et il semble que CSS Grid ne soit pas en mesure de réaliser ce stackoverflow.com/q/53394402/8437694



0
votes

Ce n'est pas possible dans la version actuelle (niveau 1) de CSS Grid . Cependant, ce n'est pas trop compliqué avec flexbox.

Vous avez écrit dans un commentaire:

J'utilise la Flexbox pour le secours. Une (et non la seule) raison pour laquelle je me penche sur les grilles est d'utiliser "gap" et d'autres fonctionnalités qui vont avec. Par exemple, même si l'écart peut être simulé par la marge, mais puisque nous ne connaissons pas le nombre d'éléments dans la dernière ligne, se débarrasser des espaces latéraux (sur le côté du conteneur) nécessitera du code supplémentaire.

Vous avez raison: la fonction d' grip-gap de CSS Grid est assez pratique. Cependant, vous pouvez également émuler le comportement en utilisant des marges - sans trop de complexité - dans flexbox.

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
  <span></span>
</div>

<div>
  <span></span>
</div>
div {
  display: flex;
  flex-wrap: wrap;
  padding: 0px 0px 5px 5px;
  margin: 20px auto;
  width: 400px;
  background: #d8d8d8;

  }
span {
  flex: 1 0 30%;
  height: 50px;
  margin-top: 5px;
  margin-right: 5px;
  background: blue;
}


0 commentaires

2
votes

Ceci est totalement possible avec la grille CSS en combinant les règles CSS nth-child et nth-last-of-type. La seule mise en garde est que le nombre de colonnes doit être connu à l'avance.

<div class="grid">
  <div>text</div>
  <div>TEXT</div>
  <div>text</div>
  <div>text</div>
  <div>TEXT</div>
  <div>text</div>
  <div>text</div>
  <div>TEXT</div>
</div>
.grid {
    display: grid;
    grid-template-columns: auto auto auto;
    justify-items: start;
    grid-gap: 10px;
}

.grid div {
  border: 1px solid #ccc;
  width: 100%;
}

.grid > *:nth-child(3n-1) {
  justify-self: center;
  text-align: center;
}

.grid > *:nth-child(3n) {
  justify-self: end;
  text-align: right;
}

.grid > *:nth-child(3n-1):nth-last-of-type(1) {
  border-color: red;
  grid-column: span 2;
}

.grid > *:nth-child(3n-2):nth-last-of-type(1) {
  border-color: red;
  grid-column: span 3;
}


7 commentaires

Merci pour votre réponse. Votre solution ne fonctionnerait que si nous savons que nous avons 3 colonnes dans chaque ligne, et si, disons, nous avons 6 colonnes, alors nous devons définir la durée 5 fois en ciblant le nième enfant (6n-5) et ainsi en avant.


Oui, comme indiqué, mais cela fonctionne parfaitement lorsque vous connaissez le nombre de colonnes, donc je pense que c'est une réponse à votre question.Vous pouvez également utiliser scss pour calculer ces entrées, si le nombre de colonnes varie, par exemple lorsque vous utilisez requêtes médiatiques.


Désolé pour le malentendu, encore une fois, merci pour le temps que vous avez mis et répondu à la question, mais ce n'est PAS la réponse :) Si vous s'il vous plaît lire le message original, je n'ai pas mentionné que nous connaissons le nombre de colonnes et si c'est ce que vous avez supposé, alors je peux dire que ce n'était PAS une valeur prédéfinie, nous ne connaissons PAS le nombre de colonnes. Pour être plus clair, il s'agit d'un modèle que nous créons sur une plate-forme de commerce électronique, nous avons utilisé Flex à la place (entre-temps) mais l'idée générale est que le CSS ne dépend pas du numéro de la colonne, du moins pas pour l'étendue de votre réponse.


Votre css montre "grid-template-columns: repeat (3, 1fr)" et votre demande est de savoir comment faire en sorte que les éléments remplissent l'espace restant, quel que soit le nombre d'items. J'ai répondu à cela. Si vous avez besoin de poser une autre question sur la façon de procéder dans un scénario où vous ne savez pas combien de colonnes il y a, veuillez le faire.


Je n'essaie vraiment pas de faire valoir des arguments, et je vous remercie vraiment pour la réponse, mais ce n'est pas la bonne réponse à ma question, désolé pour cela!


Ce n'est pas vraiment une réponse à la question, qui indique clairement dans le diagramme ci-joint "nous ne connaissons pas le nombre d'éléments". Donc, une réponse qui ne fonctionne que si vous savez à l'avance que la seule chose que OP ne saura pas à l'avance est, avec tout le respect que je vous dois, à peu près inutile pour OP.


confondre "éléments" avec "colonnes"



0
votes

J'ai trouvé la réponse à votre question, je l'ai reproduite ici: https://jsfiddle.net/nmcobalt/dg3mutwv/13/

Afin de rendre le css moins compliqué et de résoudre ce problème complexe, il est recommandé d'utiliser SCSS * au lieu du css brut.

Dans le fichier SCSS, vous devez utiliser le sélecteur css nth: last-child avec itération calculant les fils basés sur la fonction modulo et le facteur constant des 3 colonnes.

<div>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
</div>
<div>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
</div>

et le balisage html suivant; J'ai fait deux exemples différents (enveloppés par div) pour reproduire votre requête:

@mixin setLastChildFluid{
  @for $i from 1 through 10 {    
    $span: 3;
    @if $i % 3 == 0{
      $span: 1;
    } @else if $i % 3 == 1{
      $span: 3;
    } @else if $i % 3 == 2{
      $span: 2;
    } 
    @if $span == 2 {
      span:nth-child(#{$i - 1}){
        &:nth-last-child(2){
          grid-column-end:span 1;
          position:relative;
          bottom:0;
          width:calc(150% + 5px);
          left:0;    
        }
      }
      span:nth-child(#{$i}){
        &:nth-last-child(1){
          grid-column-start:2;
          position:relative;
          bottom:0;
          width:calc(150% + 5px);
          left:calc(50% + 5px);
        }
      }
      
    } @else {
      span:nth-child(#{$i}){
        &:last-child{
            grid-column-end:span #{$span};          
        }
      }
    }
    
  }
}
div {
  position:relative;
  margin:20px auto;
  width: 400px;
  background: #d8d8d8;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  
  @include setLastChildFluid;
}
span {
  height: 50px;
  background: blue;
  color:yellow;
}

Modifiez le nombre de divs afin de voir le résultat fluide.

* SASS est un langage de script de préprocesseur qui est interprété ou compilé en feuilles de style en cascade (CSS). En savoir plus ici: https://sass-lang.com/guide


3 commentaires

Vous savez qu'il a demandé des css et non des scss, non?


Oui je sais, mais avec scss c'est devenu beaucoup plus simple dans une chose très complexe. Vous pouvez toujours convertir scss en css avec l'outil en ligne.


Je dois admettre que c'est plus simple et complexe. Mais juste en disant qu'il n'a pas vraiment posé de questions sur scss, il pourrait ne pas savoir ce qu'est scss. Vous devriez au moins expliquer un peu scss pour le rendre plus pratique, puis recherchez simplement une réponse.