Esta resposta tem duas seções principais:
- Entendendo como o alinhamento funciona na CSS Grid.
- Seis métodos para centralizar no CSS Grid.
Se você estiver interessado apenas nas soluções, pule a primeira seção.
A estrutura e o escopo do layout de grade
Para entender completamente como a centralização funciona em um contêiner de grade, é importante primeiro entender a estrutura e o escopo do layout da grade.
A estrutura HTML de um contêiner de grade possui três níveis:
- o recipiente
- o item
- o conteúdo
Cada um desses níveis é independente dos outros, em termos de aplicação das propriedades da grade.
O escopo de um contêiner de grade é limitado a um relacionamento pai-filho.
Isso significa que um contêiner de grade é sempre o pai e um item de grade é sempre o filho. As propriedades da grade funcionam apenas dentro desse relacionamento.
Descendentes de um contêiner de grade além dos filhos não fazem parte do layout da grade e não aceitarão propriedades da grade. (Pelo menos não até que o subgrid
recurso seja implementado, o que permitirá que os descendentes de itens da grade respeitem as linhas do contêiner primário.)
Aqui está um exemplo dos conceitos de estrutura e escopo descritos acima.
Imagine uma grade do tipo tic-tac-toe.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
Você quer que os X e O estejam centralizados em cada célula.
Então você aplica a centralização no nível do contêiner:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Porém, devido à estrutura e ao escopo do layout da grade, justify-items
o contêiner centraliza os itens da grade, não o conteúdo (pelo menos não diretamente).
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>
Mesmo problema com align-items
: o conteúdo pode ser centralizado como subproduto, mas você perdeu o design do 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>
Para centralizar o conteúdo, você precisa adotar uma abordagem diferente. Referindo-se novamente à estrutura e ao escopo do layout da grade, você precisa tratar o item da grade como pai e o conteúdo como filho.
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>
Demonstração do jsFiddle
Seis métodos para centralizar na grade CSS
Existem vários métodos para centralizar itens da grade e seu conteúdo.
Aqui está uma grade 2x2 básica:
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
Para uma maneira simples e fácil de centralizar o conteúdo dos itens da grade, use o flexbox.
Mais especificamente, transforme o item da grade em um contêiner flexível.
Não há conflito, violação de especificação ou outro problema com este método. É limpo e válido.
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>
Veja este post para uma explicação completa:
Layout da grade
Da mesma maneira que um item flexível também pode ser um contêiner flexível, um item de grade também pode ser um contêiner de grade. Essa solução é semelhante à solução flexbox acima, exceto que a centralização é feita com propriedades de grade, e não 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
margens
Use margin: auto
para centralizar vertical e horizontalmente os itens da grade.
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>
Para centralizar o conteúdo dos itens de grade, você precisa transformá-lo em um contêiner de grade (ou flex), agrupar itens anônimos em seus próprios elementos ( já que eles não podem ser direcionados diretamente pelo CSS ) e aplicar as margens aos novos elementos.
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>
Propriedades de alinhamento de caixa
Ao considerar usar as seguintes propriedades para alinhar itens da grade, leia a seção nas auto
margens acima.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Para centralizar o conteúdo horizontalmente em um item de grade, você pode usar a text-align
propriedade
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>
Observe que, para centralização vertical, vertical-align: middle
não funcionará.
Isso ocorre porque a vertical-align
propriedade se aplica apenas a contêineres embutidos e de célula da tabela.
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>
Pode-se dizer que display: inline-grid
estabelece um contêiner em nível de linha e isso seria verdade. Então, por que não vertical-align
funciona em itens de grade?
O motivo é que, em um contexto de formatação de grade , os itens são tratados como elementos no nível do bloco.
6.1 Exibição do item de grade
O display
valor de um item de grade é bloqueado : se o especificado display
de um filho em fluxo de um elemento que gera um contêiner de grade for um valor em nível de linha, ele computará para seu equivalente em nível de bloco.
Em um contexto de formatação de bloco , algo para o qual a vertical-align
propriedade foi projetada originalmente, o navegador não espera encontrar um elemento em nível de bloco em um contêiner em nível de linha. Isso é HTML inválido.
Posicionamento CSS
Por fim, existe uma solução geral de centralização CSS que também funciona no Grid: posicionamento absoluto
Este é um bom método para centralizar objetos que precisam ser removidos do fluxo de documentos. Por exemplo, se você deseja:
Basta definir position: absolute
o elemento a ser centralizado e position: relative
o ancestral que servirá como bloco de contenção (geralmente é o pai). Algo assim:
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>
Aqui está uma explicação completa de como esse método funciona:
Aqui está a seção sobre posicionamento absoluto na especificação Grid: