web-dev-qa-db-fra.com

Comment faire en sorte que les éléments CSS Grid occupent l'espace restant?

J'ai une carte construite avec CSS Grid layout. Il peut y avoir une image à gauche, du texte en haut à droite et peut-être un bouton ou un lien en bas à droite.

Dans le code ci-dessous, comment faire en sorte que la zone verte occupe le plus de place possible et que la zone bleue occupe le moins de place possible?

Le vert doit repousser le plus possible la zone bleue.

https://jsfiddle.net/9nxpvs5m/

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas:
    "one two"
    "one three"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.two {
  background: green;
  grid-area: two;
}

.three {
  background: blue;
  grid-area: three;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="two">
    Two
  </div>
  <div class="three">
    Three
  </div>
</div>

13
Jens Törnell

Ajouter grid-template-rows: 1fr min-content; à votre .grid vous donnera exactement ce que vous cherchez :).

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 1fr min-content;
  grid-template-areas:
    "one two"
    "one three"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.two {
  background: green;
  grid-area: two;
}

.three {
  background: blue;
  grid-area: three;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="two">
    Two
  </div>
  <div class="three">
    Three
  </div>
</div>

Jens édite: Pour un meilleur support du navigateur, utilisez plutôt: grid-template-rows: 1fr auto;, du moins dans ce cas précis.

10
Kevin Powell

Une grille est une série de lignes et de colonnes se croisant.

Vous souhaitez que les deux éléments de la deuxième colonne ajustent automatiquement la hauteur de leurs lignes en fonction de la hauteur de leur contenu.

Ce n'est pas comme ça qu'une grille fonctionne. Ces modifications de la hauteur des lignes dans la deuxième colonne affectent également la première colonne.

Si vous devez utiliser CSS Grid, ce que je ferais est de donner au conteneur, par exemple, 12 lignes, puis de disposer d'éléments sur plusieurs lignes si nécessaire.

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

.one {
  grid-row: 1 / -1;
  background: red;
}

.two {
  grid-row: span 10;
  background: lightgreen;
}

.three {
  grid-row: span 2;
  background: aqua;
}

.grid > div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

Sinon, vous pouvez essayer une solution flexbox.

.grid {
  display: flex;
  flex-flow: column wrap;
  height: 200px;
}

.one {
  flex: 0 0 100%;
  width: 30%;
  background: red;
}

.two {
  flex: 1 0 1px;
  width: 70%;
  background: lightgreen;
}

.three {
  background: aqua;
}

.grid>div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

2
Michael_B

Lorsque vous utilisez grid et que vous avez utilisé une zone de modèle de grille et que, par hasard, vous avez donné une largeur à une zone donnée, une grille d'espacement vous reste automatiquement content ou max-content, de sorte qu'il ajuste sa position automatiquement.

0
dean filigreti

Ce n’est certainement pas la solution la plus élégante et probablement pas la meilleure pratique, mais vous pouvez toujours ajouter plus de lignes de

"one two"

avant la partie où vous avez

"one three"

donc ça finit par ressembler

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas:
    "one two"
    "one two"
    "one two"
    "one three"
}

Encore une fois, je suis presque sûr que ce n’est qu’un moyen de contourner le problème et de trouver de meilleures solutions ... Mais cela fonctionne, pour être juste.

0
gymnast66x

Je suis nouveau dans la grille, alors excuses-moi si c'est loin du but.

Une approche possible pourrait être de regrouper two et three ensemble et d’utiliser flexbox?

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas: "one two"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.wrap {
  grid-area: two;
  display: flex;
  flex-direction: column;
}

.two {
  background: green;
  flex: 1;
}

.three {
  background: blue;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="wrap">

    <div class="two">
      Two
    </div>
    <div class="three">
      Three
    </div>
  </div>
</div>

0
sol