Aller au contenu principal
Partagez cet article :

Les sous-grilles en CSS

Introduction

Ajoutée dans le deuxième module de CSS grid layout, la valeur subgrid s'avère être une fonctionnalité très pratique dans une mise en page moderne.

En effet, lorsqu'on déclare une disposition en grille, seuls les enfants directs du conteneur de grille deviennent des parties de la mise en page de la grille CSS. Cependant, les éléments à l'intérieur (petits-enfants) des enfants n'héritent pas de la disposition de la grille. La valeur subgrid peut faire en sorte qu'un élément hérite des colonnes et/ou des lignes de son parent.

Il subsite néanmoins un avantage au fait que les éléments à l'intérieur des enfants n'héritent pas des grilles du conteneur. Ainsi, est-il possible de mettre en place un autre module de mise en page, tel que flexbox, ou encore de déclarer une grille indépendante avec des règles d'alignement différentes. C'est d'ailleurs la raison pour laquelle le W3c a hésité à implanter la valeur subgrid dans le premier module du Grid layout.

Cependant, vous serez sans doute confronté à certaines situations qui nécessiteront de créer une sous-grille. Nous allons voir dans cet article les différents cas de figure où les sous-grilles peuvent considérablement nous aider.


Fonctionnement des grilles

Commençons par une simple disposition en grilles et une seconde avec les sous-grilles afin que vous puissiez comprendre l'intérêt de la valeur subgrid :

Ce n'est pas évident à constater à première vue, mais si vous faîtes un effort d'attention, vous remarquez alors que les colonnes des éléments à l'intérieur de l'élément enfant 7 s'adaptent à la grille de l'élément parent grâce à la valeur subgrid, ce qui n'est pas le cas sans celle-ci.

Voici un graphique qui pourra peut-être vous aider à y voir encore plus clair :

exemple grille grid CSS exemple grille subgrid CSS

Voici quelques exemples de ce que peut faire la valeur subgrid :

- Les pistes de la grille imbriquée s'alignent avec celles du parent. (l'exemple qu'on vient juste de voir)

- Il est possible de cibler la ligne de fin de la grille explicite comme dans l'exemple ci-dessous :

exemple grille explicite subgrid CSS

Ce qui donne ceci en terme de code :



<div class="grid">

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

<div class="subgrid">

<div class="subgrid-item">1</div>
<div class="subgrid-item">2</div>
<div class="subgrid-item">3</div>
<div class="subgrid-item">4</div>
<div class="subgrid-item">5</div>
<div class="subgrid-item">6</div>
<div class="subgrid-item">7</div>
<div class="subgrid-item">8</div>
  
</div>

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


</div>





.grid {

display: grid;
grid-template-columns: repeat(4,1fr);
grid-auto-rows: minmax(100px, auto);
max-width: 800px;
gap: 10px;
padding: 10px;

}

.grid-item {
  background-color: #6753ea;
  padding: 10px;
}

.subgrid {

  grid-column: 2 / -1; /* on vise la ligne de fin*/
  display: grid;
  grid-template-columns: subgrid;
  row-gap: 10px;
  
}

.subgrid-item {

  background-color: rgba(103, 83, 234, 0.6);
  padding: 10px;
  color: #fff;

}




- Héritage des lignes de grille nommées de la grille parent (il en est de même pour les zones de grille nommées) :

exemple héritage lignes nommées subgrid CSS

Ce qui donne ceci en terme de code :




<div class="grid">

<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
	
<div class="subgrid">
<div></div>
</div>



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


</div>





.grid {
  display: grid;
  grid-template-columns: [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e]; /*on nomme les lignes de grille*/
  grid-auto-rows: minmax(100px, auto);
  max-width: 800px;
  gap: 10px;
  padding: 10px;

}
		
.grid > div {

 background-color: rgba(103, 83, 234, 0.6);
 padding: 10px;
  
}
		
		
.subgrid {
  
grid-column: b / e;
display: grid;
gap: 10px;
grid-template-columns: subgrid;

}
		
		
.subgrid >div {
 
background-color: #6753ea;
grid-column: c / e;
grid-row: 1;

}




- On peut ajouter des noms de ligne à la sous-grille :




.subgrid {
  display: grid;
  grid-template-columns: subgrid [line1] [line2] [line3];
}	



- La sous-grille peut avoir des gouttières (propriété gap) de tailles différentes par rapport à son parent. En effet, les espaces s'héritent. Mais il est tout à fait possible de changer la taille de l'espace dans la sous-grille.

Partant de ce postulat, nous allons maintenant voir des exemples qui vont nécessiter l'utilisation des sous-grilles.


Cas d'utilisation

Colonnes avec titres alignés

Premier cas d'utilisation. L'objectif ici est de permettre aux titres d'être alignés dans les sous-grilles.

Un premier exemple avec des cartes. Vous pouvez constater que les titres occupent la même place et sont donc alignés.

Voici un graphique pour les navigateurs non compatibles :

exemple colonnes avec titres alignés subgrid CSS

Deuxième exemple avec des listes de liens pour un footer par exemple :

exemple liste liens subgrid CSS

On peut s'amuser également à reproduire un tweet en quelques minutes, très facilement.

exemple carte twitter subgrid CSS


<div class="grid">

<div class="carte-tweet"> 

<svg class=avatar viewBox="0 0 122.88 110.44">...</svg>

<div class="nom-tweet">John Smith</div>
<div class="arobase">@johndoe</div>
<svg class="twitter-logo" viewBox="0 0 32 32">...</svg>

<div class=texte-tweet>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ac nisi dapibus, congue ex quis, commodo lorem. Nunc volutpat est non sapien varius consequat. </p>
</div>

<div class=date-tweet>16:15 PM - 09 Jan 2022</div>

<span>
<svg width="22" height="22" viewBox="0 0 217.762 217.762">
</svg>625</span>	

<span>
<svg width="22" height="22" viewBox="0 0 21 21">
</svg>245
</span>

<span>
<svg width="22" height="22" viewBox="0 0 51.997 51.997">
</svg>1K
</span>

</div>
	
</div>	





.grid {

margin:auto;
display: grid;
grid-template-columns: repeat(6,1fr);
gap: .5rem;
max-width:500px;

}


.date-tweet{

grid-column:span 6;
margin:1rem 0

}

.carte-tweet{
	
display: grid;
grid-column: 1/-1;
grid-template-columns: subgrid;
align-items: center;
	
}

.avatar {
	
grid-row: 1 / 3;
grid-column:1/ 2;
width: 48px;
aspect-ratio:1;
border-radius: 50%;
background:#6753ea

}

	
.twitter-logo{

width: 24px;
aspect-ratio:1;
justify-self:center;
grid-column:6;
grid-row:span 2

}

.carte-tweet span {

justify-self:center; 
display:grid;
grid-auto-flow: column; 
gap:.5rem

}	
	
.header__text {
 
font-size: 1.5em;
margin: 0;

}

.carte-tweet {

background-color: #fff;
border-radius: 10px;
padding: 10px;
box-shadow: 20px 20px 20px -20px rgba(0,0,0,0.75);
border: 1px solid rgba(0,0,0,0.25);

}
	
.carte-tweet p{

margin-top:1rem;


}

.texte-tweet{

grid-column:span 6

}
	

.nom-tweet {

grid-column: 2 / 6;
font-size: 1em;
margin: 0;
font-weight: 700;

}
	
.arobase{

grid-column: 2 / 6;
grid-row: 2

}	


Galerie de photos (style comic)

Galerie de photos style comic css subgrid


<div class="galerie">

<div class="grid-1"><img src="image.jpg"></div>
<div class="grid-2"><img src="image.jpg"></div>

<div class="subgrid">
<div class="grid-3"><img src="image.jpg"></div>
</div>

<div class="grid-4"><img src="image.jpg"></div>

</div>




*{box-sizing: border-box}
	
img{

width: 100%;
height: 100%;
object-fit: cover

}



.galerie {   
	
max-width: 37.5rem;
padding: 1rem;
margin: 5rem auto;
background-color: #fff;
box-shadow: 2px 4px 16px rgba(0, 0, 0, 0.2);
--grid-gap: 1rem;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, auto);
gap: var(--grid-gap);
	
}


.grid-3 {
  
grid-row: 1;
grid-column:1/span 2;

}

.subgrid {

display: grid;
grid-column: span 2;
grid-template-columns: subgrid;

}
.subgrid::after {

  content: " ";
  outline: var(--grid-gap) solid white;
  grid-row: 1;
  grid-column: 1;
  
}

.grid-4 {

  grid-column: span 2;
  
}


Formulaire

Formulaire subgrid CSS


<form>

<div class=form>
<div>
<label for=name>Nom :</label>
<input id=name name=name>
</div>

<div>
<label for=email>Email:</label>
<input id=email name=email type=email>
</div>
	
<div>
<label for=tel>Téléphone:</label>
<input id=tel name=tel type=tel>
</div>
	
</div>

</form>




*{box-sizing: border-box}
	
.form {
	
display: grid;
grid-template-columns: min-content minmax(30ch,1fr);
gap: 1rem;
	
}

.form div {
	
grid-column: span 2;
display: grid;
grid-template-columns: subgrid;
	
  }


Contenu pleine largeur

Contenu pleine largeur subgrid CSS


<main class="article-body">

<div class="header contenu">
<img src="image.jpg" alt>
<h2 class="contenu-centre">Lorem ipsum </h2>
</div>

<p>...</p>
<p>...</p>
        
<div class="contenu">
<img class="gauche" src="image.jpg" alt>
<h3 class="contenu-gauche">Lorem ipsum</h3>
<p class="contenu-gauche">...</p>
	
</div>
    
<p>...</p>

<div class="contenu">
<img class="droite" src="image.jpg" alt>
<h3 class="contenu-droite">Lorem ipsum</h3>
<p class="contenu-droite">...</p>
</div>

	
<p>...</p>
<p>...</p>

</main>




*,
*::before,
*::after{

box-sizing: border-box

}
	
img{width:100%;height:100%;object-fit: cover;}	

.article-body {
 
display: grid;
grid-template-columns: [fullWidth-start] 1rem 
[left-start] 1fr 
[article-start right-start] minmax(20ch, 80ch) 
[article-end left-end] 1fr 
[right-end] 1rem [fullWidth-end];
	
}
	
.article-body > * {
	
grid-column: article;
	
}

.contenu {

display: grid;
grid-template-columns: subgrid;
grid-column: fullWidth;
background-color: #6753ea;

    }
	
	
.header img{
	
grid-column:fullWidth;
grid-row:1/-1;
max-height:80vh;
	
	} 

.header h2{
	
font-size:3rem;
font-size:clamp(2rem, 1.975rem + 0.125vw, 2.125rem); 
grid-row:1/-1;
place-self:center
	
	}

.header:after {
	
grid-area: 1/1/-1/-1;
content: "";
z-index:1;
background-color: rgba(0, 0, 0, 0.2);
background-image: linear-gradient(to top,rgba(0, 0, 0, 0.2) 0%,rgba(0, 0, 0, 0) 50%,80%,rgba(0, 0, 0, 0.2) 100%);
	
}	
	
	
.contenu-centre {
	
grid-column: article;
	
}
	
.contenu-droite {
	
grid-column: right;
text-align: right;
	
    }
    
.contenu-gauche {
	
grid-column: left;
	
    }
	
.gauche{
	
grid-column:4/6;
grid-row:1/3
	
}	

.droite{
	
grid-row:1/3;
grid-column:1/3
	
	}	

h3 {
    font-size: 2rem;font-size:clamp(1.75rem, 1.725rem + 0.125vw, 1.875rem);
}
	
main p {
 
   font-size:1.115rem;font-size:clamp(1rem, 0.975rem + 0.125vw, 1.125rem)
}



Container queries

exemple container queries et subgrid CSS


<div class="grid">

<div class="subgrid">
<img src="image.jpg" alt>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed placerat mollis vestibulum. Suspendisse pharetra faucibus fringilla. Nullam in blandit tellus, eu pharetra eros. </div>
</div>
</div>





*{

box-sizing: border-box

}
	
	

.grid {
	
max-width: 800px;
width:100%;
margin:2rem auto;
display: grid;
gap: 10px;
grid-template-columns: repeat(4,1fr);
grid-template-rows: repeat(4, minmax(100px, auto));
container-type: inline-size;

}

.subgrid {
  grid-column: 1 / -1;
  grid-row: 2;
  background-color: #6753ea;
  color: #fff;
}

.subgrid div {
	
  padding: 1rem;
	
}

@container (min-width: 600px) {
  
.subgrid {
	
display: grid;
grid-template-columns: subgrid;
	
  }
	
img{

grid-column: 1 / 3;
height: 100%;
width: 100%;
object-fit: cover
	
}
	
.subgrid div {  grid-column: 3 / 5}
	
}




Vous rencontrez un problème avec cet article ?

Vous avez remarqué une faute, un oubli, un lien mort ? Vous ne comprenez pas un point précis de l'article ? Vous pouvez me contacter par mail (contact@guyom-design.com) et je vous aiderai si je le peux.