[Перевод] CSS Grid — швейцарский армейский нож для макетов сайтов и приложений
В течение последних двух месяцев я углубился в изучение CSS Grid. В этой заметке я хочу поделиться своими основными соображениями. Чтобы было более понятно, я объясню все с помощью диаграмм.
Вероятно, вы уже знакомы с блоковой моделью CSS для обычных элементов. Давайте начнем с аналогичного «общего обзора» для CSS Grid:
В основе структуры CSS Grid находится основной контейнер, представляющий собой обычный div
, имеющий margin
, border
и padding
. Для создания CSS grid контейнера добавим свойство display: grid
. Элементы сетки — это потомки, размещенные внутри родительского контейнера. Они обычно определяются как список, описывающий header
, sidebar
, footer
или другие аналогичные элементы макета сайта, зависящие от его дизайна.
В данном случае мы имеем 3 div
. Третий растягивается на 2 ячейки.
Обратите внимание, линии можно отсчитывать и в обратную сторону, используя отрицательную систему координат.
Сетка из примера выше имеет размер 5 на 4 ячейки. Это определяется следующим образом:
div#grid { /* This is our CSS grid parent container */
display: grid;
grid-template-columns: 100px 100px 100px 100px 100px; /* 5 cols */
grid-template-rows: 100px 100px 100px 100px; /* 4 rows */
}
Количество строк и столбцов определяется в соответствии с установленными значениями. Между ячейками располагаются линии и дополнительные отступы. Строки и столбцы между линиями называются полосами сетки. Количество линий всегда будет равно [количеству ячеек + 1] в заданном направлении. Так 5 столбцов будут иметь 6 линий, тогда как 4 строки будут иметь 5 линий. В следующем примере мы видим 7 столбцов и только 1 строку:
Одни из первых особенностей, которые можно отметить в поведении CSS grid (по умолчанию CSS grid не имеет границы, поэтому линии 1 сверху вниз и 1 слева направо начинаются в верхнем левом углу первого элемента, к ним не применяется отступ; линия сетки размещается посередине отступа; даже если задано свойство padding
, к первой и последней линиям не применяется отступ)
Во-первых, следует заметить относительно CSS grid, что внешние линии не зависят от размера интервала. Только внутренние линии. Мы подробнее рассмотрим это чуть позже, когда посмотрим на долевые (fr) единицы.
Сетка CSS является двухмерной. Элементы могут размещаться горизонтально (столбец) или вертикально (строка). Зададим значение свойства grid-auto-flow
.
Это работает так же, как и Flex:
Использование grid-auto-flow: row
или grid-auto-flow: column
для определения направления заполнения сетки элементами.
Представим себе абстрактную сетку:
Итак, мы имеем общее представление о том, как это работает.
Творческая часть начинается, когда вы сталкиваетесь с проблемой жонглирования местами размещения элементов для создания отзывчивого макета. CSS Grid предлагает несколько возможностей именно для достижения этого. Мы рассмотрим их в следующем разделе этой заметки.
Давайте закрепим полученные знания, рассмотрев несколько примеров:
Я использовал только два элемента div
. И вот такая сетка получилась.
Неявное и явное размещение содержимого
Но что произойдет, если мы добавим еще один элемент в список?
Добавление элемента 3 в этот же макет автоматически расширит его (синий элемент). Это новое пространство создается автоматически путем копирования значений из первой строки. Давайте добавим элемент 4?
И снова CSS grid приняла решение растянуть элемент 4 на оставшееся место во второй строке. Так произошло, потому что grid-template-rows
точно определяет пространство только для 1 строки. Остальное происходит автоматически.
Размещение синих элементов не было указано вами явно. Это неявное (автоматическое) размещение. Элементы просто попадают в это пространство.
Явное размещение содержимого
Вот это то, что вы ожидаете от ячеек, если установите значения для всех элементов списка:
По сути, вы можете контролировать размер во всех последовательных строках, добавив больше значений с помощью свойства grid-template-rows
. Заметьте, в этом случае, элементы больше не скрыты. Вы точно их определили (25 px 75 px).
Автоматический интервал
CSS Grid предлагает несколько свойств, чтобы автоматически растягивать ячейки по переменной / неизвестной величине. Вот основные примеры автоматического расширения для столбцов и строк:
Нижний пример демонстрирует применение ключевого слова auto. Это означает, что ячейка будет растягиваться для заполнения всего оставшегося в родительском контейнере пространства после его наполнения явно заданными элементами.
Отступы CSS Grid
Говоря о CSS Grid, невозможно обойти вниманием отступы. Отступы — это пространство по горизонтали и вертикали между ячейками сетки.
Интервалы контролируются при помощи свойств grid-column-gap
и grid-row-gap
:
Вы можете использовать разные отступы для обоих направлений. Это может оказаться полезным для создания галерей видео или изображений:
Отступы для разных направлений (между столбцами и строками) могут отличаться. Но размер интервала указывается один раз для всей сетки в заданном направлении. Как вы видим — отступы разного размера для одного направления не допускаются:
Мне бы хотелось иметь возможность задавать разные размеры отступов. Я думаю, это было бы удобно. Некоторые предлагают использовать пустые полосы для достижения подобного эффекта.
Единицы измерения fr (дробная часть)
Дробные части (fr) уникальны для CSS Grid. Дробная часть распределяет пространство в зависимости от остальных элементов в родительском контейнере:
Поведение изменяется, но 1fr остается неизменной, независимо от использования других значений. Дробная часть работает подобно значениям в процентах, но более легка и интуитивно понятна при разделении пространства:
Поведение изменения дробных единиц основано на всех значениях, представленных для данного направления
В этом примере для наглядности показано только поведение для столбцов. Но аналогично это работает и для строк. Просто используйте свойство grid-template-row
.
Дробные части и их взаимодействие с отступами
Пространство, определяемое при помощи дробных частей, изменяется на основе отступов. То же самое значение 1fr внутри одного и того же родительского контейнера будет сокращаться до меньшего размера, когда будут добавлены интервалы:
Мы добавили интервалы между ячейками, заданными при помощи единиц fr
Как мы видим, это дает нам довольно хороший набор инструментов для размещения содержимого с интервалами практически как угодно, и при этом не беспокоясь о значениях в пикселях.
Эти новые изменения оставляют дизайн пиксель-в-пиксель в прошлом. Теперь мы думаем о дизайне, используя интуитивный подход.
Наконец, это дает интересные идеи относительно использования не целых fr — посмотрите на созданную мной забавную сетку. Вы можете определить сетку, используя также числа с запятой:
Размещение содержимого
Мы только что рассмотрели строение CSS Grid. Надеюсь, вы получили представление о том, как структурирован контент в CSS Grid. Сейчас же мы должны проявить фантазию и разместить некоторые элементы внутри сетки. После этого стандартное поведение CSS grid может поменяться. Как это происходит, мы сейчас и рассмотрим.
Для упорядочивания элементов внутри ячеек или областей макета сетки, вы должны обращаться к ним по линиям между ячейками. Никаких table
-подобных интервалов.
CSS Grid позволяет использовать интервалы для определения ширины и высоты области контента (в пространстве ячеек) подобно тому, как это происходит в таблице. Мы коснемся этого. Но вы можете и, вероятно, должны указать начальную ячейку, используя номер строки или ее название (подробнее об этом чуть позже). Это зависит от ваших предпочтений.
Относительно размещения контента на нескольких ячеек, то наиболее очевидным и заманчивым является объединение ячеек.
Объединение содержимого ячеек
Вы можете объединить элементы в нескольких ячейках.
Важно: объединение изменяет местоположение окружающих элементов.
Объединение при помощи grid-column и grid-row
Используем свойства grid-column
и grid-row
для следующего элемента:
Синие элементы изменили расположение после того, как для размещения элемента 7 были объединены несколько ячеек. Оранжевые элементы были вытеснены на следующий ряд.
Есть и другой способ сделать то же самое.
Объединение при помощи grid-column-start…
…grid-column-end
, grid-row-start
и grid-row-end
— вы можете определять конкретные начальные и конечные точки, по которым хотите объединить ячейки.
Я удалил элементы после 15 (оранжевые), потому что они больше не нужны:
Задайте эти свойства непосредственно для элемента, к которому они должны быть применены
Растяжение содержимого столбцов и строк работает в обоих направлениях.
min-content и max-content
Значения min-content
и max-content
используются в свойствах grid-template-columns
или grid-template-rows
, как и любое другое значение, связанное с размером (например, px, 1fr и др).
Давайте посмотрим на этот образец. Это наша начальная точка. Мы немного изменим ситуацию, чтобы увидеть как значения min / max влияют на ячейки.
Посмотрим, какие результаты будут получены, если мы изменим один из столбцов с помощью min-content
и max-content
:
С текстом из одного слова не видно разницы между полученными результатами, используем ли мы min-content
или max-content
. Hello — это единственное слово. Его минимальное и максимальное значение одинаково.
Но все становится интереснее для более сложного текста. Следующий пример демонстрирует ключевую идею для min-content
или max-content
:
Здесь min-content
использовало самое длинное слово в предложении (stranger) в качестве базовой ширины. Если использовать max-content
, вся текстовая строка с пробелами заполняет пространство ячейки. Но что произойдет, если мы применим min-content
или max-content
ко всем ячейкам?
Я заметил, что по умолчанию текст был центрирован, когда я использовал min-content
, хотя text-align: center
не было установлено.
Изображения и max-content
Я поместил изображение синей розы в ячейку. И, как и ожидалось, сетка расширилась, чтобы выделить достаточно места под картинку:
Когда я точно устанавливаю ширину изображения 50%, только для того, чтобы посмотреть результат, CSS Grid все еще сохраняет ширину ячейки в 100% размера изображения, но отображает его с шириной 50% (как и ожидалось) и автоматически центрирует его по горизонтали внутри ячейки.
И текст, и изображение (или другое содержимое) будут по умолчанию автоматически центрироваться в ячейках CSS Grid.
Позиционирование содержимого
До этого момента мы говорили в целом о структуре CSS Grid. Далее мы рассмотрим, как добиться «разнонаправленного» смещения внутри ячейки. Конечно, мы не будет использовать свойство float
.
Смещение в разных направлениях
Я не думаю, что специфика CSS Grid призывает нас к этому. Однако вполне возможно задать смещение в пределах 360°.
Это работает одинаково со строчными и блочными элементами! Я думаю, что это моя любимая возможность из всего набора CSS Grid.
Все 9 комбинаций возможны при использовании свойств align-self
и justify-self
. Поясню их ниже.
align-self
Это свойство помогает позиционировать содержимое по вертикали.
Используйте align-self: start
для выравнивания содержимого по верхнему краю ячейки.
Используйте align-self: center
для вертикального выравнивания по центру.
Используйте align-self: end
для выравнивания по нижнему краю ячейки.
justify-self
Это свойство помогает позиционировать содержимое по горизонтали.
Используйте justify-self: start
для выравнивания содержимого по левому краю ячейки.
Используйте justify-self: center
для горизонтального выравнивания по центру.
Используйте justify-self: end
для выравнивания по правому краю ячейки.
Вы можете использовать любую из 9 комбинаций justify-self
и align-self
, чтобы выровнять все, что угодно, в любом направлении.
Шаблоны областей
Шаблоны областей определяются с помощью свойства grid-template-areas
.
Обратите внимание, что шаблоны областей для каждой строки заключены в двойные кавычки. Каждый столбец отделен пробелом. В этом примере я только объяснил, как назвать окна. Чтобы по-настоящему использовать все преимущества от шаблонов областей, вам необходимо сгруппировать прямоугольные блоки ячеек с одинаковым именем. Блоки «тетриса» не допускаются. Вы можете использовать только прямоугольники:
Здесь Left — это область, объединяющая 3 ячейки. CSS Grid автоматически рассматривает её как единый блок. То же самое с Right. В этом простом примере я создал 2 столбца. Но вы поняли идею. Объединяйте области большего размера, давая им имена.
Чтобы поместить элемент в эту область, просто используйте свойство grid-area: TemplateName
. В данном случае, grid-area: Left
или grid-area: Right
.
В имени шаблона не могут использоваться пробелы. Здесь я использовал тире.
Практический пример использования шаблона областей в CSS Grid
Сейчас мы знаем, как объединять прямоугольные области. Давайте рассмотрим потенциально возможный сценарий. Я продемонстрирую очень простой макет.
Я создал примитивный макет веб-сайта, имеющего две боковых панели, header и footer. Основная область находится в центре и занимает площадь 3×2 ячейки:
Здесь мы имеем только 5 элементов. Добавьте больше и они будут вытеснены за пределы основной области в неявные ячейки.
Просто убедитесь в том, что ваши окна всегда квадратные или прямоугольные.
Названия линий
Вместо того, чтобы всегда ссылаться на линии по их номеру, вы можете назвать их. Тем самым их легче запомнить для растягивания элементов по нескольким ячейкам. Числа могут так утомлять!
Ниже показано, как это выглядит:
Используйте квадратные скобки для названия линий. Затем используйте эти имена для определения длины, на которую должны быть растянуты ваши элементы при помощи прямой слеш.
В заключение
CSS Grid — это всеобъемлющий, комплексный предмет.
Конечно, здесь представлено далеко не полное обучающее пособие о том, как создавать макеты при помощи CSS Grid. Я использовал только один пример для каждой части в качестве отправной точки изучения сетки.
Надеюсь, представленная здесь информация была полезной и вдохновила к созданию сайтов с использованием CSS Grid.
CSS Grid — это не только часть HTML. Это целая система для создания адаптивных веб-сайтов и приложений.
Его свойства и значения базируются на технологиях, опирающихся на более чем десятилетний опыт создания веб-сайтов с использованием обычных тегов HTML.
LOOKING.HOUSE — на проекте собрано более 150 точек looking glass в 40 странах. Можно быстро выполнить команды host, ping, traceroute и mtr.