Ця відповідь має два основні розділи:
- Розуміння того, як працює вирівнювання в 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: