Questa risposta ha due sezioni principali:
- Comprensione del funzionamento dell'allineamento nella griglia CSS.
- Sei metodi per centrare nella griglia CSS.
Se sei interessato solo alle soluzioni, salta la prima sezione.
Struttura e ambito di layout della griglia
Per comprendere appieno il funzionamento del centraggio in un contenitore della griglia, è importante comprendere innanzitutto la struttura e l'ambito del layout della griglia.
La struttura HTML di un contenitore della griglia ha tre livelli:
- Il container
- l'oggetto
- il contenuto
Ciascuno di questi livelli è indipendente dagli altri, in termini di applicazione delle proprietà della griglia.
L' ambito di un contenitore della griglia è limitato a una relazione padre-figlio.
Ciò significa che un contenitore della griglia è sempre il genitore e un elemento della griglia è sempre il figlio. Le proprietà della griglia funzionano solo all'interno di questa relazione.
I discendenti di un contenitore della griglia oltre i figli non fanno parte del layout della griglia e non accetteranno le proprietà della griglia. (Almeno non fino a quando la subgridfunzione non sarà stata implementata, il che consentirà ai discendenti degli elementi della griglia di rispettare le linee del contenitore primario.)
Ecco un esempio dei concetti di struttura e ambito descritti sopra.
Immagina una griglia simile al tic-tac-toe.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}

Vuoi che le X e le O siano centrate in ogni cella.
Quindi applichi il centraggio a livello di contenitore:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Ma a causa della struttura e della portata del layout della griglia, justify-itemssul contenitore centra gli elementi della griglia, non il contenuto (almeno non direttamente).

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>
Stesso problema con align-items: il contenuto può essere centrato come sottoprodotto, ma hai perso il design del layout.
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>
Per centrare il contenuto è necessario adottare un approccio diverso. Facendo nuovamente riferimento alla struttura e all'ambito del layout della griglia, è necessario considerare l'elemento della griglia come elemento principale e il contenuto come elemento secondario.
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>
jsFiddle demo
Sei metodi per centrare nella griglia CSS
Esistono diversi metodi per centrare gli elementi della griglia e il loro contenuto.
Ecco una griglia 2x2 di base:
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
Per un modo semplice e facile per centrare il contenuto degli elementi della griglia, utilizzare la flexbox.
Più specificamente, trasforma l'elemento griglia in un contenitore flessibile.
Non vi è alcun conflitto, violazione delle specifiche o altri problemi con questo metodo. È pulito e valido.
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>
Vedi questo post per una spiegazione completa:
Layout della griglia
Allo stesso modo in cui un articolo flessibile può anche essere un contenitore flessibile, un elemento griglia può anche essere un contenitore griglia. Questa soluzione è simile alla soluzione flexbox di cui sopra, tranne per il fatto che il centraggio viene eseguito con proprietà grid, non 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 margini
Utilizzare margin: autoper centrare verticalmente e orizzontalmente gli elementi della griglia.
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>
Per centrare il contenuto degli elementi della griglia è necessario trasformarlo in un contenitore a griglia (o flessibile), avvolgere gli elementi anonimi nei propri elementi ( poiché non possono essere scelti come target direttamente dai CSS ) e applicare i margini ai nuovi elementi.
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>
Proprietà di allineamento casella
Quando si considera l'utilizzo delle seguenti proprietà per allineare gli elementi della griglia, leggere la sezione sui automargini sopra.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Per centrare il contenuto in orizzontale in un elemento della griglia, è possibile utilizzare la text-alignproprietà
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>
Si noti che per il centraggio verticale, vertical-align: middlenon funzionerà.
Questo perché la vertical-alignproprietà si applica solo ai contenitori inline e a celle di tabella.
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>
Si potrebbe dire che display: inline-gridstabilisce un contenitore a livello di linea e che sarebbe vero. Quindi perché non vertical-alignfunziona con gli elementi della griglia?
Il motivo è che in un contesto di formattazione della griglia , gli elementi vengono trattati come elementi a livello di blocco.
6.1. Visualizzazione elemento griglia
Il displayvalore di un elemento della griglia è bloccato : se il valore specificato displaydi un figlio in-flow di un elemento che genera un contenitore di griglia è un valore a livello in linea, viene calcolato al suo equivalente a livello di blocco.
In un contesto di formattazione a blocchi , qualcosa per cui la vertical-alignproprietà è stata originariamente progettata, il browser non si aspetta di trovare un elemento a livello di blocco in un contenitore a livello inline. Questo è HTML non valido.
Posizionamento CSS
Infine, esiste una soluzione di centraggio CSS generale che funziona anche in Grid: posizionamento assoluto
Questo è un buon metodo per centrare oggetti che devono essere rimossi dal flusso di documenti. Ad esempio, se si desidera:
Basta impostare position: absolutesull'elemento da centrare e position: relativesull'antenato che fungerà da blocco contenitore (di solito è il genitore). Qualcosa come questo:
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>
Ecco una spiegazione completa di come funziona questo metodo:
Ecco la sezione sul posizionamento assoluto nelle specifiche Grid: