Cette réponse comporte deux sections principales:
- Comprendre le fonctionnement de l'alignement dans CSS Grid.
- Six méthodes de centrage dans CSS Grid.
Si vous n'êtes intéressé que par les solutions, ignorez la première section.
La structure et l'étendue de la disposition de la grille
Pour bien comprendre le fonctionnement du centrage dans un conteneur de grille, il est important de comprendre d'abord la structure et la portée de la disposition de la grille.
La structure HTML d'un conteneur de grille comporte trois niveaux:
- le container
- l'article
- le contenu
Chacun de ces niveaux est indépendant des autres, en termes d'application des propriétés de grille.
La portée d'un conteneur de grille est limitée à une relation parent-enfant.
Cela signifie qu'un conteneur de grille est toujours le parent et un élément de grille est toujours l'enfant. Les propriétés de grille ne fonctionnent que dans cette relation.
Les descendants d'un conteneur de grille au-delà des enfants ne font pas partie de la disposition de grille et n'accepteront pas les propriétés de grille. (Du moins pas tant que la subgrid
fonctionnalité n'a pas été implémentée, ce qui permettra aux descendants des éléments de la grille de respecter les lignes du conteneur principal.)
Voici un exemple des concepts de structure et de portée décrits ci-dessus.
Imaginez une grille en forme de tic-tac-toe.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
Vous voulez que les X et O soient centrés dans chaque cellule.
Vous appliquez donc le centrage au niveau du conteneur:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Mais en raison de la structure et de la portée de la disposition de la grille, justify-items
sur le conteneur centre les éléments de la grille, pas le contenu (du moins pas directement).
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Même problème avec align-items
: le contenu peut être centré comme un sous-produit, mais vous avez perdu la conception de la mise en page.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Pour centrer le contenu, vous devez adopter une approche différente. En vous référant à nouveau à la structure et à la portée de la disposition de la grille, vous devez traiter l'élément de grille comme le parent et le contenu comme l'enfant.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Démo jsFiddle
Six méthodes de centrage dans la grille CSS
Il existe plusieurs méthodes pour centrer les éléments de la grille et leur contenu.
Voici une grille de base 2x2:
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Flexbox
Pour un moyen simple et facile de centrer le contenu des éléments de la grille, utilisez flexbox.
Plus précisément, transformez l'élément de grille en un conteneur flexible.
Il n'y a aucun conflit, violation de spécifications ou autre problème avec cette méthode. C'est propre et valide.
grid-item {
display: flex;
align-items: center;
justify-content: center;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex; /* new */
align-items: center; /* new */
justify-content: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Voir cet article pour une explication complète:
Disposition de la grille
De la même manière qu'un élément flexible peut également être un conteneur flexible, un élément de grille peut également être un conteneur de grille. Cette solution est similaire à la solution flexbox ci-dessus, sauf que le centrage est effectué avec des propriétés de grille et non de flex.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: grid; /* new */
align-items: center; /* new */
justify-items: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
auto
marges
Utilisez margin: auto
pour centrer verticalement et horizontalement les éléments de la grille.
grid-item {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Pour centrer le contenu des éléments de la grille, vous devez transformer l'élément en un conteneur de grille (ou flexible), envelopper les éléments anonymes dans leurs propres éléments ( car ils ne peuvent pas être directement ciblés par CSS ) et appliquer les marges aux nouveaux éléments.
grid-item {
display: flex;
}
span, img {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex;
}
span, img {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Propriétés d'alignement de boîte
Lorsque vous envisagez d'utiliser les propriétés suivantes pour aligner les éléments de la grille, lisez la section sur les auto
marges ci-dessus.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Pour centrer le contenu horizontalement dans un élément de grille, vous pouvez utiliser la text-align
propriété.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Notez que pour le centrage vertical, vertical-align: middle
ne fonctionnera pas.
En effet , la vertical-align
propriété s'applique uniquement aux conteneurs de cellules de table et inline.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* <--- works */
vertical-align: middle; /* <--- fails */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
On pourrait dire que cela display: inline-grid
établit un conteneur de niveau en ligne, et ce serait vrai. Alors pourquoi ne vertical-align
fonctionne pas dans les éléments de la grille?
La raison en est que dans un contexte de formatage de grille , les éléments sont traités comme des éléments de niveau bloc.
6.1. Affichage des éléments de grille
La display
valeur d'un élément de grille est bloquée : si la spécification display
d'un enfant en flux d'un élément générant un conteneur de grille est une valeur de niveau en ligne, elle calcule à son équivalent au niveau du bloc.
Dans un contexte de mise en forme de bloc , pour lequel la vertical-align
propriété a été conçue à l'origine, le navigateur ne s'attend pas à trouver un élément de niveau bloc dans un conteneur de niveau en ligne. C'est du HTML invalide.
Positionnement CSS
Enfin, il existe une solution générale de centrage CSS qui fonctionne également dans Grid: positionnement absolu
C'est une bonne méthode pour centrer les objets qui doivent être supprimés du flux de documents. Par exemple, si vous souhaitez:
Définissez simplement position: absolute
sur l'élément à centrer, et position: relative
sur l'ancêtre qui servira de bloc conteneur (c'est généralement le parent). Quelque chose comme ça:
grid-item {
position: relative;
text-align: center;
}
span {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
position: relative;
text-align: center;
}
span, img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Voici une explication complète du fonctionnement de cette méthode:
Voici la section sur le positionnement absolu dans la spécification Grid: