Центрирование в сетке CSS

Я пытаюсь создать простую страницу с сеткой CSS.

то, что я не могу сделать, это центрировать текст из HTML в соответствующие ячейки сетки.

Я пробовал размещать контент в отдельном divs как внутри, так и снаружи 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>

5 ответов


этот ответ состоит из двух основных разделов:

  1. понимание того, как выравнивание работает в сетке CSS.
  2. шесть методов центрирования в сетке CSS.

если вас интересуют только решения, пропустите первый раздел.


структура и объем сетки layout

чтобы полностью понять, как центрирование работает в сеточном контейнере, важно сначала понять структуру и объем сетки макет.

HTML-код структура контейнера сетки имеет три уровня:

  • контейнер
  • элемент
  • контент

каждый из этих уровней независим от других, с точки зрения применения свойств сетки.

на область контейнера сетки ограничивается отношением "родитель-потомок".

это означает, что контейнер сетки всегда родитель и элемент сетки всегда являются дочерними. Свойства сетки работают только в пределах этой связи.

потомки контейнера сетки за пределами дочерних элементов не являются частью макета сетки и не будут принимать свойства сетки. (По крайней мере, до subgrid реализована функция, которая позволит потомкам элементов сетки уважать линии основного контейнера.)

вот пример концепции структуры и области описанный выше.

представьте себе сетку, похожую на крестики-нолики.

article {
  display: inline-grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 3px;
}

enter image description here

вы хотите, чтобы 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 на контейнере центрирует элементы сетки, а не содержимое (по крайней мере, не непосредственно.)

enter image description here

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

enter image description here

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

enter image description here

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 также может быть контейнером grid. Это решение аналогично решению flexbox выше, за исключением того, что центрирование выполняется с помощью сетки, а не 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>

чтобы центрировать содержимое элементов сетки, вам нужно сделать элемент в контейнер сетки (или flex), обернуть анонимные элементы в свои собственные элементы (так как они не могут быть непосредственно направлены 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 на предке, который будет служить в качестве содержащего блока (обычно это родитель). Что-то вроде этого:--52-->

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>

вот полное объяснение как этот метод работает:

вот раздел об абсолютном позиционировании в спецификации сетки:


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

С спецификации flexbox:

каждый потоковый ребенок контейнер становится гибкий элемент, и каждый непрерывный запуск текста, который непосредственно содержится внутри контейнер завернут в анонимный гибкий элемент. Однако анонимный элемент 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>

попробуйте использовать flex:

Plunker demo: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>

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

https://jsfiddle.net/ctt3bqr0/

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

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

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

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

Ура!


вы этого хотите?

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>