web-dev-qa-db-fra.com

CSS Grid: Comment faire pour qu'une colonne couvre toute la largeur lorsqu'une deuxième colonne n'est pas là?

Je sais qu'il y a des questions similaires, mais cela demande précisément comment procéder à l'aide de CSS Grid Layout.

Nous avons donc cette configuration de base de la grille:

HTML (avec barre latérale):

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>

  <div class="sidebar">
    <p>sidebar</p>
  </div>

</div>

CSS:

.grid {
  display: grid;
  grid-template-columns: 1fr 200px;
}

Pour créer une mise en page qui ressemble à ceci:

| content               | sidebar |

Si la page n'a pas de barre latérale, c.-à-d. le html ressemble à ceci mais avec le même CSS:

HTML (pas de barre latérale):

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>

</div>

La mise en page ressemble à ceci (les tirets représentent un espace vide)

| content               | ------- |

Je sais pourquoi, la colonne de grille est toujours définie dans la règle grid-template-columns.

Je me demande simplement comment indiquer à la grille que s'il n'y a pas de contenu, remplissez l'espace restant de la même manière que flex-grow fonctionne pour flexbox.

Le résultat souhaité ressemblera à ceci si aucune barre latérale n'est présente.

| content                         |
6
Daniel Tonon

Je pense connaître la réponse définitive à cette question maintenant. Le problème avec les réponses jusqu'à présent est qu'elles n'expliquent pas comment gérer une barre latérale qui se trouve à gauche du contenu principal (principalement parce que je ne l'avais pas demandé dans la question initiale).

<div class="grid">

  <nav>
    <p>navigation</p>
  </nav>

  <main>
    <p>content</p>
  </main>

  <aside>
    <p>sidebar</p>
  </aside>

</div>

Vous pouvez utiliser ce CSS:

.grid {
  display: grid;
  grid-template-columns: fit-content(200px) 1fr fit-content(200px);
}

nav, aside {
  width: 100%;
}

/* ensures that the content will always be placed in the correct column */
nav { grid-column: 1; }
main { grid-column: 2; }
aside { grid-column: 3; }

C'est également un bon cas d'utilisation pour les zones de grille.

.grid {
  display: grid;
  grid-template-columns: fit-content(200px) 1fr fit-content(200px);
  grid-template-areas: "nav content sidebar";
}

nav, aside {
  width: 100%;
}

/* ensures that the content will always be placed in the correct column */
nav { grid-area: nav; }
main { grid-area: content; }
aside { grid-area: sidebar; }

Une version compatible avec IE ressemblerait à ceci:

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: auto 1fr auto;
  grid-template-columns: auto 1fr auto;
}

nav, aside {
  width: 100%; /* Ensures that if the content exists, it takes up max-width */
  max-width: 200px; /* Prevents the content exceeding 200px in width */
}

/* ensures that the content will always be placed in the correct column */
nav {
  -ms-grid-column: 1;
  grid-column: 1;
}

main {
  -ms-grid-column: 2;
  grid-column: 2;
}

aside {
  -ms-grid-column: 3;
  grid-column: 3;
}
0
Daniel Tonon

Ne définissez pas les colonnes explicitement avec grid-template-columns.

Créez les colonnes implicit à la place, puis utilisez grid-auto-columns pour définir leur largeur.

Cela permettra à la première colonne (.content) de consommer tout l'espace de la ligne lorsque la deuxième colonne (.sidebar) n'existe pas.

.grid {
  display: grid;
  grid-auto-columns: 1fr 200px;
}

.content {
  grid-column: 1;
}

.sidebar {
  grid-column: 2;
}

.grid > * {
  border: 1px dashed red; /* demo only */
}
<p>With side bar:</p>

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>
  
  <div class="sidebar">
    <p>sidebar</p>
  </div>

</div>

<p>No side bar:</p>

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>
  
</div>
4
Michael_B

Vous pouvez vous rapprocher en utilisant des mots clés de dimensionnement du contenu, par exemple:

.grid {
  display: grid;
  grid-template-columns: 1fr fit-content(200px);
}

.sidebar {
  width: 100%;
}

Le mot clé fit-content regardera la taille du contenu et agira comme max-content jusqu'à ce qu'il atteigne la valeur transmise.

En réalité, vous n’auriez probablement pas besoin de coller une taille dans la barre latérale, car le contenu dicterait probablement une taille d’au moins 200 pixels (par exemple), mais vous pouvez jouer avec cela.

4
Rachel Andrew