Ця відповідь має два основні розділи:
- Розуміння того, як працює вирівнювання в 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>
Дивіться цю публікацію для повного пояснення:
Макет сітки
Таким же чином, як елемент flex також може бути контейнером 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 поля
Використовуйте 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: