Этот ответ состоит из двух основных разделов:
- Понимание того, как выравнивание работает в 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: