Приветствую. Представляю вашему вниманию перевод статьи «Ten modern layouts in one line of CSS», опубликованной 7 июля 2020 года автором Una Kravets

Современный CSS позволяет разработчикам писать по-настоящему содержательные и надёжные правила с помощью всего нескольких нажатий клавиш.

Все приведённые в статье примеры можно опробовать во встроенном выше Glitch, или посетив 1linelayouts.glitch.me

01. Суперцентрирование: place-items: center

В первом примере "однострочной" раскладки давайте решим самую главную загадку во всём CSS: центрирование. Хочу, чтобы вы знали, что 'place-items: center' это проще, чем кажется.

Сначала задайте родительскому элементу свойству display со значением grid, а затем для него же place-items: center. Свойство place-items это краткая форма записи для align-items и justify-items, с помощью которого мы устанавливаем оба эти свойства в значение center.

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

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

02. Адаптивные блоки: flex: <grow> <shrink> <baseWidth>

Это распространённая раскладка, например, для лендингов, в которой может располагаться ряд из 3 элементов, обычно содержащих изображение, заголовок и текст, описывающих особенности продукта. Но мы хотим, чтобы эти элементы также аккуратно располагались и при просмотре страницы с мобильных устройств.

Если использовать Flexbox, вам не придётся настраивать расположение элементов для разных размеров экрана с помощью медиа-запросов.

Свойство flex является сокращением и позволяет задать набор значений flex: <flex-grow> <flex-shrink> <flex-basis>

Если нужно, чтобы блоки имели <flex-basis> размер, сжимались на меньших размерах, но не увеличивались для заполнения дополнительного свободного пространства, следует указать flex: 0 1 <flex-basis>. В данном случае <flex-basis> равно 150px. Код будет следующим:

.parent {
  display: flex;
}

.child {
  flex: 0 1 150px;
}

Если вы хотите, чтобы при переносе на новую строку блоки растягивали и заполняли пространство, установите <flex-grow> в значение 1.

.parent {
  display: flex;
}

.child {
  flex: 1 1 150px;
}

Теперь при изменении размера экрана Flex-элементы будут и сужаться и увеличиваться в размере.

03. Боковая панель: grid-template-columns: minmax(<min>, <max>) 1fr)

В этой демонстрации используется преимущество функции minmax для grid-раскладки. Мы устанавливаем минимальный размер боковой панели равным 150px, но на экранах бо?льшей ширины позволяем растягиваться на 25%. Таким образом, панель будет занимать 25% ширины родителя, пока эти 25% не станут меньше 150px.

Укажем эту функцию в значении свойства grid-template-columns. Элемент в первой колонке (в нашем случае это боковая панель) получает minmax между 150px и 25%, а второй элемент (в нашем случае это main) занимает оставшееся пространство 1fr.

.parent {
  display: grid;
  grid-template-columns: minmax(150px, 25%) 1fr;
}

04. Липкий футер: grid-template-rows: auto 1fr auto

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

Добавление display: grid к родительскому элементу создаст одноколоночную сетку. При этом, если в разделе "Main" будет недостаточно содержимого, чтобы достигнуть футера, данный блок всё равно увеличится, заполнив свободное пространство по высоте.

Чтобы прикрепить футер к нижней части, добавьте:

.parent {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

Высота хедера и футера будет установлена автоматически на основании минимального размера содержимого, а оставшееся свободное место (1fr) займёт раздел "Main"

05. Классический "Святой Грааль": grid-template: auto 1fr auto / auto 1fr auto

В данной раскладке присутствуют хедер, футер, левая и правая боковая панель, а также блок с основным содержимым. Он похож на предыдущий пример, но теперь с боковыми панелями.

Чтобы описать всю сетку с помощью одной строки кода, используйте свойство grid-template. Это свойство позволяет задавать значения для них обоих.

Записывается следующим образом: grid-template: auto 1fr auto / auto 1fr auto. Слеш разделяет значения для рядов (grid-template-rows) и колонок (grid-template-columns) сетки.

.parent {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
}

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

06. 12-колоночная сетка: grid-template-columns: repeat(12, 1fr)

В этом примере мы рассмотрим другой классический пример: 12-колоночную сетку. Вы можете быстро создавать подобные сетки в CSS с помощью функции repeat(). Использование repeat(12, 1fr); для шаблона колонок сетки создаёт 12 колонок, каждая шириной 1fr.

.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.child-span-12 {
  grid-column: 1 / 13;
}

Теперь мы можем разместить на ней дочерние элементы. Один из вариантов - использовать grid-линии. Например, колонка со свойством grid-column: 1/13 будет начинаться с первой и заканчиваться последней (13-й) линией, охватывая все 12 колонок. Со свойством grid-column: 1/5 - первые 4 колонки.

Другой способ размещения дочерних элементов - использование ключевого слова span. В этом случае задаётся начальная линия и количество колонок, которое нужно охватить, начиная со стартовой точки. Например, grid-column: 1 / span 12 будет аналогом grid-column: 1 / 13, а grid-columns: 2 / span 6 - аналогом grid-column: 2 / 8.

.child-span-12 {
  grid-column: 1 / span 12;
}

07. RAM (Repeat, Auto, MinMax): grid-template-columns(auto-fit, minmax(<base>, 1fr))

В этом примере мы объединим некоторые из рассмотренных концепций создания отзывчивого интерфейса с автоматически позиционируемыми и гибкими дочерними элементами. Довольно удобно. Ключевые термины repeat, auto-(fit|fill) и minmax() можно запомнить с помощью акронима RAM.

Всё вместе это выглядит так:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

Снова применяется функция repeat(), но на этот раз вместо числового значения используется ключевое слово auto-fit. Это активирует автоматическое расположение дочерних элементов, для которых базовая минимальная ширина равна 150px но может увеличиваться до 1fr. Это значит, что на маленьких экранах они будут занимать 1fr ширины, а при появлении достаточного пространства, элементы, расположенные ниже будут перетекать в первую строку.

Если в родительском элементе освобождается дополнительное место, в режиме auto-fit дочерние элементы будут растягиваться, чтобы это место заполнить. Если же изменить режим на auto-fill, элементы не будут превышать базовый размер из функции minmax(<baseWidth>, 1fr).

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

08. Ряд карточек: justify-content: space-between

Ключевым моментом данной раскладки является свойство justify-content: space-between, которое размещает первый и последний дочерние элементы у края родителя, поровну распределяя доступное пространство между самими элементами. В нашем случае внутри карточек выбран режим раскладки Flexbox, с вертикальным расположением элементов, заданным с использованием flex-direction: column

Это размещает заголовок, описание и блок изображения в одну колонку внутри родительской карточки. Затем применяется свойство justify-content: space-between, прикрепляющее первый (заголовок) и последний (блок изображения) элементы к краям, а блок описания между ними.

.parent {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

09. Стилизация с помощью Clamp: clamp(<min>, <actual>, <max>)

Здесь мы познакомимся с технологией, менее поддерживаемой браузерами, но существенно влияющей на концепцию отзывчивого дизайна интерфейсов. В этом демо ширина задаётся с использованием функции 'clamp': width: clamp(<min>, <actual>, <max>).

Она позволяет задать минимальное, предпочитаемое и максимальное значение.

.parent {
  width: clamp(23ch, 50%, 46ch);
}

Здесь минимальный размер - 23ch или 23 единицы ширины символа, а максимальный - 46ch. Единицы ширины символа основываются на размере шрифта элемента (в частности, ширине глифа 0). Предпочитаемая или "фактическая" ширина карточки равняется 50%, что означает 50% ширины родительского элемента.

В этой ситуации функция clamp() позволяет элементу сохранять ширину 50% от родителя до тех пор, пока она не превысит 46ch (на больших экранах) или не станет меньше 23ch (на маленьких). Видно, что во время увеличения или уменьшения размера родительского элемента, ширина карточки соответственно увеличивается до максимального возможного или уменьшается до минимально допустимого размера. Также, она остаётся по центру родительского элемента, поскольку мы использовали для этого дополнительные свойства. Это обеспечивает больше удобства при чтении, так как блок текста не будет слишком широким (более 46ch) или слишком сжатым и узким (менее 23ch).

Это также отличный способ реализовать отзывчивый размер шрифта. Например, можно написать: font-size: clamp(1.5rem, 20vw, 3rem). В этом случае размер шрифта заголовка всегда будет оставаться в пределах между 1.5rem и 3rem, но будет увеличиваться или уменьшаться в зависимости от размера экрана, соответствуя значению 20vw.

Это отличный способ обеспечить удобство чтения, но помните, что данное свойство поддерживается ещё не во всех современных браузерах, поэтому убедитесь, что не забыли про фолбек.

10. Сохранение пропорций: aspect-ratio: <width> / <height>

И, наконец, последний инструмент - самый экспериментальный из всех. Он был недавно представлен в Chrome Canary в Chromium 84, а Firefox ведёт активную работу над его внедрением, но пока что в стабильных версиях браузеров он не поддерживается.

Тем не менее, я хочу упомянуть и его, потому что он решает достаточно часто встречаемую проблему - сохранение пропорций изображений.

При использовании свойства aspect-ration, когда я изменяю размер карточки, зелёный блок сохраняет пропорции 16x9: aspect-ration: 16 / 9.

.video {
  aspect-ratio: 16 / 9;
}

Чтобы поддерживать соотношение сторон 16 x 9 без этого свойства, следует использовать хак с padding-top, задав padding 56.25%. Но сСкоро у нас появится свойство, позволяющее не прибегать к этому хаку и вычислению процентов. Можно сделать квадрат с соотношением сторон 1 / 1 или прямоугольник с соотношением 2 / 1, или любым другим, необходимым для изображения определённых размеров.

.square {
  aspect-ratio: 1 / 1;
}

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

Заключение

Благодарю, что ознакомились с этими 10 возможностями CSS. Чтобы узнать больше, можете посмотреть полное видео или поработать с демонстрацией.