Центрування в CSS Grid


179

Я намагаюся створити просту сторінку за допомогою CSS Grid.

Те, що мені не вдається зробити, - це центр тексту від HTML до відповідних комірок сітки.

Я спробував зміст укладання в окремих divз як всередині , так і за її межі left_bgі right_bgселектори і грати з деякими з властивостей CSS не дали ніяких результатів.

Як це зробити?

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.left_text {
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}

.right_text {
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  position: relative;
  z-index: 1;
  justify-self: center;
  font-family: Raleway;
  font-size: large;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
  </div>
</div>

<div class="right_bg">
  <!--right background color of the page-->
</div>

<div class="left_text">
  <!--left side text content-->
  <p>Review my stuff</p>

  <div class="right_text">
    <!--right side text content-->
    <p>Hire me!</p>
  </div>
</div>


1
Перевірте посилання w3.org/Style/Examples/007/center.en.html , сподіваюся, це буде корисним.
Алі

Відповіді:


433

Ця відповідь має два основні розділи:

  1. Розуміння того, як працює вирівнювання в CSS Grid.
  2. Шість методів центрування в 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на контейнері розміщуються елементи сітки, а не вміст (принаймні, не безпосередньо).

введіть тут опис зображення

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;
}

section {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid black;
  font-size: 3em;
}

введіть тут опис зображення

демонстрація 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;
}

Дивіться цю публікацію для повного пояснення:


Макет сітки

Таким же чином, як елемент flex також може бути контейнером flex, то елемент з сітки також може бути контейнером з сіткою. Це рішення схоже на рішення флексокса, вказане вище, за винятком того, що центрування виконується з властивостями сітки, а не згинання.


auto поля

Використовуйте margin: autoдля вертикального та горизонтального центральних елементів сітки.

grid-item {
  margin: auto;
}

Для центрування вмісту елементів сітки необхідно перенести елемент у контейнер з сіткою (або згинати), загортати анонімні елементи у власні елементи ( оскільки вони не можуть бути безпосередньо націлені CSS ) та застосувати поля до нових елементів.

grid-item {
  display: flex;
}

span, img {
  margin: auto;
}


Властивості поля вирівнювання

Розглядаючи можливість використання наступних властивостей для вирівнювання елементів сітки, прочитайте розділ на autoполях вище.

  • align-items
  • justify-items
  • align-self
  • justify-self

https://www.w3.org/TR/css-align-3/#property-index


text-align: center

Щоб централізувати вміст горизонтально в елементі сітки, ви можете використовувати text-alignвластивість.

Зверніть увагу, що для вертикального центрування vertical-align: middleне вийде.

Це пояснюється тим, що vertical-alignвластивість стосується лише вбудованих контейнерів та контейнерів таблиці.

Можна сказати, що 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:


Привіт Майкл, мені було цікаво, чи можливо лише за допомогою сітки змінити розмір кожного стовпця до розміру найменшого стовпця в рядку?
The Codesee

@ TheCodesee, це можливо, залежно від усіх ваших вимог. Чи є у вас зразок коду? Або розглянути можливість розміщення нового питання з усіма подробицями.
Майкл Бенджамін

це grid-container& grid-itemє теги HTML?
diEcho

1
Вони є спеціальними тегами HTML. Ви можете створити власні теги, як я це робив для демонстрації. stackoverflow.com/q/36380449/3597276 @ pro.mean
Michael Benjamin

5
Це чудова відповідь, дякую. Це змусило мене зрозуміти на ваших двох перших прикладах, що між flexі grid, align-itemsзалишається тим самим, але чомусь justify-contentстаєjustify-items
WoJ

11

Ви можете використовувати flexbox для центрування тексту. До речі, немає необхідності в додаткових контейнерах, оскільки текст вважається анонімним гнучким елементом.

З специфікацій flexbox :

Кожна дитина, що надходить у контейнер flex, стає елементом flex , і кожен безперервний текст, який безпосередньо міститься у контейнері flex , загортається в анонімний елемент flex . Однак анонімний флекс-елемент, який містить лише пробіл (тобто символи, на які може впливати white-spaceвластивість), не відображається (як би це було display:none).

Тому просто зробіть елементи сітки у вигляді гнучких контейнерів ( display: flex), додайте align-items: centerта justify-content: centerпо центру по вертикалі та горизонталі.

Також проведена оптимізація HTML та CSS:

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  
  font-family: Raleway;
  font-size: large;
}

.left_bg,
.right_bg {
  display: flex;
  align-items: center;
  justify-content: center;
}

.left_bg {
  background-color: #3498db;
}

.right_bg {
  background-color: #ecf0f1;
}
<div class="container">
  <div class="left_bg">Review my stuff</div>
  <div class="right_bg">Hire me!</div>
</div>


9

Навіть не намагайтеся використовувати флекс; залишайся з css grid !! :)

https://jsfiddle.net/ctt3bqr0/

justify-self: center;
align-self: center;

тут робиться робота по центру.

Якщо ви хочете відцентрувати щось, divщо знаходиться всередині клітини сітки, вам потрібно визначити вкладену сітку для того, щоб вона працювала. (Будь ласка, подивіться на загадку обидва приклади, показані там.)

https://css-tricks.com/snippets/css/complete-guide-grid/

Ура!


Мені було цікаво про вкладені сітки. Дякую, що показали мені, як це робиться, я думаю. Отже, ви вважаєте, що слід уникати флексу з сіткою або це добре поєднувати?
буряк

Його добре поєднувати, але ви повинні бути впевнені, що використовуєте правильний інструмент для роботи. Знайдіть деякий час і подивіться презентацію Рейчелс, яка роз'ясне багато для вас у темі css grid. youtu.be/3vJE3bVoF-Q
Конрад Альбрехт

Проблема з таким підходом виникає, коли ви використовуєте межі на елементах сітки ...
Андрій

2
Це можна скоротити place-self: center;.
DevonDahon

6

Властивість скорочення елементів CSS- місця для місця встановлює відповідно елементи-вирівнювання та виправдовувальні елементи. Якщо друге значення не встановлено, перше значення також використовується для нього.

.parent {
  display: grid;
  place-items: center;
}

place-itemsнаразі не підтримується у краю
Konrad Albrecht

1

Спробуйте використовувати flex:

Демонстрація Plunker: https://plnkr.co/edit/nk02ojKuXD2tAqZiWvf9

/* Styles go here */

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;

}

.right_bg {
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}

HTML

    <div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>

-2

Ти хочеш це?

html,
body {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100vh;
  grid-gap: 0px 0px;
}

.left_bg {
  display: subgrid;
  background-color: #3498db;
  grid-column: 1 / 1;
  grid-row: 1 / 1;
  z-index: 0;
}

.right_bg {
  display: subgrid;
  background-color: #ecf0f1;
  grid-column: 2 / 2;
  grid_row: 1 / 1;
  z-index: 0;
}

.text {
  font-family: Raleway;
  font-size: large;
  text-align: center;
}
<div class="container">
  <!--everything on the page-->

  <div class="left_bg">
    <!--left background color of the page-->
    <div class="text">
      <!--left side text content-->
      <p>Review my stuff</p>
    </div>
  </div>

  <div class="right_bg">
    <!--right background color of the page-->
    <div class="text">
      <!--right side text content-->
      <p>Hire me!</p>
    </div>
  </div>
</div>


1
Не зовсім. Текст теж повинен бути вертикально вирівняний.
буряк

Використання.text{ font-family: Raleway; font-size: large; text-align: center; -webkit-transform: rotate(-90deg); -moz-transform: rotate(-90deg); }
Renato siqueira

-2

Я знаю, що цьому питанню вже пару років, але я здивований, коли ніхто не запропонував:

   text-align: center;

це більш універсальна властивість, ніж контент-виправдання, і, безумовно, не є унікальною для сітки, але я вважаю, що при роботі з текстом, про що конкретно задається це питання, він вирівнює текст у центр, не впливаючи на простір між елементами сітки або вертикальним центруванням. Він центрує текст горизонтально там, де стоїть на його вертикальній осі. Я також вважаю, що це видаляє шар складності, який виправдовує вміст та доповнення елементів-елементів. Виправлення вмісту та вирівнювання-елементи впливають на весь елемент сітки або елементи, вирівнювання тексту центрирує текст, не впливаючи на контейнер, в якому він знаходиться. Сподіваюся, це допоможе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.