Центрирование в 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;
}

Смотрите этот пост для полного объяснения:


Макет сетки

Точно так же, как гибкий элемент также может быть гибким контейнером, элемент сетки также может быть сеточным контейнером. Это решение аналогично решению Flexbox, описанному выше, за исключением того, что центрирование выполняется с использованием свойств сетки, а не гибкости.


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:

Майкл Бенджамин
источник
Привет Майкл, мне было интересно, если это возможно, просто с помощью сетки изменить размер каждого столбца до размера самого маленького столбца в строке?
Codesee
@TheCodesee, это может быть возможно, в зависимости от всех ваших требований .. У вас есть пример кода? Или рассмотрите возможность размещения нового вопроса со всеми подробностями.
Майкл Бенджамин
такое grid-containerи grid-itemесть ли теги HTML?
diEcho
1
Это пользовательские теги HTML. Вы можете создать свои собственные теги, как я сделал для этой демонстрации. stackoverflow.com/q/36380449/3597276 @ pro.mean
Майкл Бенджамин
5
Это прекрасный ответ, спасибо. Это заставило меня понять, в своих первых двух примерах, что между flexи grid, align-itemsостается тем же , но по какой - то причине justify-contentстановитсяjustify-items
WOJ
11

Вы можете использовать flexbox для центрирования вашего текста. Кстати, дополнительные контейнеры не нужны, потому что текст рассматривается как анонимный элемент flex.

Из спецификации flexbox :

Каждый дочерний поток в гибком контейнере становится гибким элементом , и каждый непрерывный фрагмент текста, который непосредственно содержится внутри гибкого контейнера , оборачивается в анонимный гибкий элемент . Однако анонимный элемент Flex, содержащий только пробел (т. Е. Символы, на которые может влиять white-spaceсвойство), не отображается (как если бы он был display:none).

Так что просто сделайте элементы сетки в виде flex-контейнеров ( 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

Даже не пытайтесь использовать flex; остаться с сеткой CSS! :)

https://jsfiddle.net/ctt3bqr0/

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

выполняет центрирующую работу здесь.

Если вы хотите центрировать что-то внутри div, внутри ячейки сетки, вам нужно определить вложенную сетку, чтобы она работала. (Пожалуйста, посмотрите на скрипку обоих примеров, показанных там.)

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

Ура!

Конрад Альбрехт
источник
Я задавался вопросом о вложенных сетках. Спасибо, что показал мне, как это сделано, я думаю. Таким образом, вы думаете, что следует избегать прогибов с помощью сетки, или это хорошо, чтобы сочетать?
свекла
Его можно комбинировать, но вы должны быть уверены, что вы используете правильный инструмент для работы. Найдите время и посмотрите презентацию Rachels, которая прояснит вам многое в теме сетки CSS. youtu.be/3vJE3bVoF-Q
Конрад Альбрехт
Проблема с этим подходом возникает, когда вы используете границы для элементов сетки ...
Эндрю
2
Это может быть сокращено place-self: center;.
ДевонДахон
6

Сокращенное свойство CSS place-items устанавливает свойства align-items и justify-items соответственно. Если второе значение не установлено, для него также используется первое значение.

.parent {
  display: grid;
  place-items: center;
}
CloudBranch
источник
place-itemsв настоящее время не поддерживается в крае
Конрад Альбрехт
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); }
Ренато Сикейра
-2

Я знаю, что этому вопросу пару лет, но я с удивлением обнаружил, что никто не предложил:

   text-align: center;

это более универсальное свойство, чем justify-content, и оно определенно не уникально для grid, но я обнаружил, что при работе с текстом, о котором конкретно задается этот вопрос, он выравнивает текст по центру, не затрагивая пространство между элементами сетки, или вертикальное центрирование. Текст центрируется горизонтально там, где он стоит на вертикальной оси. Я также нахожу это для удаления слоя сложности, который добавляет justify-content и align-items. justify-content и align-items влияет на весь элемент или элементы сетки, text-align центрирует текст, не затрагивая контейнер, в котором он находится. Надеюсь, это поможет.

Aft3rL1f3
источник