Сетка отзывчивых квадратов

Мне интересно, как бы я мог создать макет с адаптивными квадратами. Каждый квадрат будет иметь содержимое по вертикали и по горизонтали. Конкретный пример показан ниже...

отзывчивые квадраты с содержанием

6 ответов

Решение

Вы можете создать адаптивную сетку квадратов с содержимым по вертикали и по центру только с помощью CSS. Я объясню, как в пошаговом процессе, но сначала приведем 2 демонстрации того, чего вы можете достичь:

Отзывчивая 3х3 квадратная сетка Адаптивные квадратные изображения в сетке 3х3

Теперь давайте посмотрим, как сделать эти модные адаптивные квадраты!



1. Создание адаптивных квадратов:

Хитрость для сохранения элементов в квадрате (или любого другого соотношения) заключается в использовании процентов padding-bottom,
Примечание: вы можете использовать верхнее заполнение или верхнее / нижнее поле, но фон элемента не будет отображаться.

Поскольку верхний отступ рассчитывается в соответствии с шириной родительского элемента ( см. MDN для справки), высота элемента будет изменяться в зависимости от его ширины. Теперь вы можете сохранить его соотношение сторон в соответствии с его шириной.
На данный момент вы можете код:

HTML:

 <div></div>

CSS

div {
    width: 30%;
    padding-bottom: 30%; /* = width for a square aspect ratio */
}

Вот простой пример компоновки сетки 3*3 с использованием приведенного выше кода.

С помощью этой техники вы можете сделать любое другое соотношение сторон, вот таблица, в которой приведены значения нижнего отступа в соответствии с соотношением сторон и шириной 30%.

 Aspect ratio  |  padding-bottom  |  for 30% width
------------------------------------------------
    1:1        |  = width         |    30%
    1:2        |  width x 2       |    60%
    2:1        |  width x 0.5     |    15%
    4:3        |  width x 0.75    |    22.5%
    16:9       |  width x 0.5625  |    16.875%




2. Добавление контента внутри квадратов

Поскольку вы не можете добавлять контент непосредственно внутри квадратов (это увеличит их высоту и квадраты больше не будут квадратами), вам нужно создать дочерние элементы (для этого примера я использую divs) внутри них с помощью position:abolute; и поместите содержимое в них. Это позволит вывести содержимое из потока и сохранить размер квадрата.

Не забудьте добавить position:relative; на родительских элементах div, поэтому абсолютные дочерние элементы располагаются / измеряются относительно своих родителей.

Давайте добавим немного контента к нашей сетке квадратов 3х3:

HTML:

<div class="square">
    <div class="content">
        .. CONTENT HERE ..
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS:

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom: 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}

РЕЗУЛЬТАТ <- с некоторым форматированием, чтобы сделать его красивым!



3. Центрирование контента

По горизонтали:

Это довольно просто, вам просто нужно добавить text-align:center в .content,
РЕЗУЛЬТАТ

Вертикальное выравнивание

Это становится серьезным! Хитрость заключается в использовании

display:table;
/* and */
display:table-cell;
vertical-align:middle;

но мы не можем использовать display:table; на .square или же .content div, потому что это конфликтует с position:absolute; поэтому нам нужно создать двух детей внутри .content дивы. Наш код будет обновлен следующим образом:

HTML:

<div class="square">
    <div class="content">
        <div class="table">
            <div class="table-cell">
                ... CONTENT HERE ...
            </div>
        </div>
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS:

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom : 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}
.table{
    display:table;
    height:100%;
    width:100%;
}
.table-cell{
    display:table-cell;
    vertical-align:middle;
    height:100%;
    width:100%;
}




Теперь мы закончили, и мы можем посмотреть на результат здесь:

LIVE FULLSCREEN RESULT

редактируемая скрипка здесь


Вы можете использовать единицы измерения vw (view-width), которые сделают квадраты отзывчивыми в соответствии с шириной экрана.

Быстрый макет этого будет:

html,
body {
  margin: 0;
  padding: 0;
}
div {
  height: 25vw;
  width: 25vw;
  background: tomato;
  display: inline-block;
  text-align: center;
  line-height: 25vw;
  font-size: 20vw;
  margin-right: -4px;
  position: relative;
}
/*demo only*/

div:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: inherit;
  width: inherit;
  background: rgba(200, 200, 200, 0.6);
  transition: all 0.4s;
}
div:hover:before {
  background: rgba(200, 200, 200, 0);
}
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>

Принятый ответ отличный, однако это можно сделать с flexbox,

Вот сеточная система, написанная с синтаксисом БЭМ, который позволяет отображать 1-10 столбцов на строку.

Если последняя строка является неполной (например, вы хотите отобразить 5 ячеек в строке и 7 элементов), конечные элементы будут отцентрированы по горизонтали. Чтобы контролировать горизонтальное выравнивание конечных элементов, просто измените justify-content собственность под .square-grid учебный класс.

.square-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.square-grid__cell {
  background-color: rgba(0, 0, 0, 0.03);
  box-shadow: 0 0 0 1px black;
  overflow: hidden;
  position: relative;
}

.square-grid__content {
  left: 0;
  position: absolute;
  top: 0;
}

.square-grid__cell:after {
  content: '';
  display: block;
  padding-bottom: 100%;
}

// Sizes – Number of cells per row

.square-grid__cell--10 {
  flex-basis: 10%;
}

.square-grid__cell--9 {
  flex-basis: 11.1111111%;
}

.square-grid__cell--8 {
  flex-basis: 12.5%;
}

.square-grid__cell--7 {
  flex-basis: 14.2857143%;
}

.square-grid__cell--6 {
  flex-basis: 16.6666667%;
}

.square-grid__cell--5 {
  flex-basis: 20%;
}

.square-grid__cell--4 {
  flex-basis: 25%;
}

.square-grid__cell--3 {
  flex-basis: 33.333%;
}

.square-grid__cell--2 {
  flex-basis: 50%;
}

.square-grid__cell--1 {
  flex-basis: 100%;
}

.square-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.square-grid__cell {
  background-color: rgba(0, 0, 0, 0.03);
  box-shadow: 0 0 0 1px black;
  overflow: hidden;
  position: relative;
}

.square-grid__content {
  left: 0;
  position: absolute;
  top: 0;
}

.square-grid__cell:after {
  content: '';
  display: block;
  padding-bottom: 100%;
}

// Sizes – Number of cells per row

.square-grid__cell--10 {
  flex-basis: 10%;
}

.square-grid__cell--9 {
  flex-basis: 11.1111111%;
}

.square-grid__cell--8 {
  flex-basis: 12.5%;
}

.square-grid__cell--7 {
  flex-basis: 14.2857143%;
}

.square-grid__cell--6 {
  flex-basis: 16.6666667%;
}

.square-grid__cell--5 {
  flex-basis: 20%;
}

.square-grid__cell--4 {
  flex-basis: 25%;
}

.square-grid__cell--3 {
  flex-basis: 33.333%;
}

.square-grid__cell--2 {
  flex-basis: 50%;
}

.square-grid__cell--1 {
  flex-basis: 100%;
}
<div class='square-grid'>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
</div>

Скрипка: https://jsfiddle.net/patrickberkeley/noLm1r45/3/

Это проверено в FF и Chrome.

Теперь мы можем легко сделать это, используя aspect-ratio ref свойство

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

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

Я использую это решение для адаптивных коробок разных рационов:

HTML:

<div class="box ratio1_1">
  <div class="box-content">
            ... CONTENT HERE ...
  </div>
</div>

CSS:

.box-content {
  width: 100%; height: 100%;
  top: 0;right: 0;bottom: 0;left: 0;
  position: absolute;
}
.box {
  position: relative;
  width: 100%;
}
.box::before {
    content: "";
    display: block;
    padding-top: 100%; /*square for no ratio*/
}
.ratio1_1::before { padding-top: 100%; }
.ratio1_2::before { padding-top: 200%; }
.ratio2_1::before { padding-top: 50%; }
.ratio4_3::before { padding-top: 75%; }
.ratio16_9::before { padding-top: 56.25%; }

Посмотреть демо на JSfiddle.net

Другие вопросы по тегам