Этот ответ состоит из двух основных разделов:
- Понимание того, как выравнивание работает в CSS Grid.
- Шесть методов для центрирования в CSS Grid.
Если вас интересуют только решения, пропустите первый раздел.
Структура и объем сетки
Чтобы полностью понять, как центрирование работает в сеточном контейнере, важно сначала понять структуру и область расположения сетки.
HTML- структура контейнера сетки имеет три уровня:
Каждый из этих уровней не зависит от других с точки зрения применения свойств сетки.
Область действия контейнера сетки ограничена отношениями родитель-потомок.
Это означает, что контейнер сетки всегда является родительским, а элемент сетки всегда дочерним. Свойства сетки работают только в этих отношениях.
Потомки контейнера сетки за пределами дочерних элементов не являются частью макета сетки и не будут принимать свойства сетки. (По крайней мере, пока subgridне будет реализована функция, которая позволит потомкам элементов сетки уважать линии основного контейнера.)
Вот пример концепции структуры и области применения, описанной выше.
Представьте себе сетку, похожую на крестики-нолики.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}

Вы хотите, чтобы X и O центрировались в каждой ячейке.
Таким образом, вы применяете центрирование на уровне контейнера:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Но из-за структуры и области расположения сетки, justify-itemsна контейнере центрируются элементы сетки, а не содержимое (по крайней мере, не напрямую).

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>
Та же проблема с align-items: контент может быть центрирован как побочный продукт, но вы потеряли дизайн макета.
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>
Для центрирования контента вам нужен другой подход. Снова обращаясь к структуре и области действия макета сетки, вы должны рассматривать элемент сетки как родительский элемент, а содержимое как дочерний.
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
Шесть методов для центрирования в CSS Grid
Существует несколько способов центрирования элементов сетки и их содержимого.
Вот основная сетка 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
Для простого и удобного способа центрировать содержимое элементов сетки используйте flexbox.
Более конкретно, сделайте элемент сетки в гибкий контейнер.
В этом методе нет конфликта, нарушения спецификации или других проблем. Это чисто и актуально.
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>
Смотрите этот пост для полного объяснения:
Макет сетки
Точно так же, как гибкий элемент также может быть гибким контейнером, элемент сетки также может быть сеточным контейнером. Это решение аналогично решению Flexbox, описанному выше, за исключением того, что центрирование выполняется с использованием свойств сетки, а не гибкости.
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 поля
Используйте margin: autoдля вертикального и горизонтального центрирования элементов сетки.
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>
Чтобы центрировать содержимое элементов сетки, вам нужно превратить элемент в контейнер сетки (или флекс), обернуть анонимные элементы в их собственные элементы ( так как они не могут быть непосредственно нацелены на CSS ) и применить поля к новым элементам.
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>
Свойства выравнивания коробки
При рассмотрении вопроса об использовании следующих свойств для выравнивания элементов сетки прочитайте раздел, посвященный autoполям выше.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Для центрирования контента по горизонтали в элементе сетки вы можете использовать text-alignсвойство.
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>
Обратите внимание, что для вертикального центрирования vertical-align: middleне будет работать.
Это связано с тем, что vertical-alignсвойство применяется только к встроенным контейнерам и контейнерам с табличными ячейками.
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>
Можно сказать, что display: inline-gridустанавливает контейнер на уровне строки, и это было бы правдой. Так почему же не vertical-alignработает с элементами сетки?
Причина в том, что в контексте форматирования сетки элементы обрабатываются как элементы уровня блока.
6.1. Отображение элемента сетки
displayЗначение элемента сетки является blockified : если указанный displayиз ребенка в потоке элемента , генерирующее контейнер сетки является значение строкового уровня, он вычисляет его уровень блока эквивалента.
В контексте форматирования блока , для vertical-alignкоторого изначально было разработано свойство, браузер не ожидает найти элемент уровня блока во встроенном контейнере. Это неверный HTML.
CSS Позиционирование
Наконец, есть общее решение для центрирования CSS, которое также работает в Grid: абсолютное позиционирование
Это хороший метод для центрирования объектов, которые необходимо удалить из потока документов. Например, если вы хотите:
Просто установите position: absoluteэлемент, который должен быть центрирован, и position: relativeна предка, который будет служить содержащим блоком (обычно это родительский элемент ). Что-то вроде этого:
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>
Вот полное объяснение того, как работает этот метод:
Вот раздел об абсолютном позиционировании в спецификации Grid: