Главная » Статьи » CSS Grid меняет наше представление о структуре контента

CSS Grid меняет наше представление о структуре контента

CSS Grid меняет наше представление о структуре контента

От автора: любой, кто хоть немного занимался созданием веб-сайтов, знает, что div — это важный строительный блок для управления макетами. HTML5 представил новые семантические элементы, и хотя они являются фантастическим дополнением к языку, они немного похожи на гарнир в супе div.

С grid нам больше не нужно полагаться на div, чтобы создать структуру страницы или даже более сложный компонент. Структура буквально определяется родителем, а не тем, как контент организован в нем.

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

Grid может быть сложным, но и flexbox непрост

Я слышал, что многие жалуются, что Grid слишком сложен, и что flexbox прекрасно справляется со своей работой. Я бы сказал, что им комфортно с flexbox и они не хотят иметь дела с Grid из-за необходимости изучения.

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

Можете ли вы назвать мне преимущества flex-структуры при настройке ширины? Или того, как flexbox вычисляет ширину flex-элементов, если мы не установили ее явно?

Например, если вы покажете приведенный ниже пример тому, кто никогда не использовал flexbox, как вы объясните тот факт, что это одинаковая разметка и одинаковый CSS для обоих наборов столбцов? Что еще хуже, второй столбец в обоих имеет ширину: 50%. Очевидно, что ширина 50% на самом деле не 50%.

«Ну, код начинается с сжатия гибких элементов, если им не хватает места, поэтому, хотя мы установили ширину элемента 50%, для этого нет места, поэтому он сжимается, потому что другой div требует больше места. 50% — это больше идеального размера, который он будет иметь.

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

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

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

Ограничения flexbox

Даже если мы возьмем простой компонент и создадим его с помощью flexbox, потому что он действует только в 1 измерении (flex-элементы — это либо строки, либо столбцы, они не могут быть и тем и другим), у нас остается много элементов div, позволяющих разбить вещи на строки, которые затем можно разбить на столбцы.

Например, если мы работаем над карточкой, которая выглядит следующим образом:

CSS Grid меняет наше представление о структуре контента

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

CSS Grid меняет наше представление о структуре контента

Желтые и оранжевые поля нужны, чтобы указании display: flex; для самой .card (красное поле) создавались два столбца. Итак, чтобы структурировать все, мы получаем разметку, которая выглядит примерно так:

<div class="card"> <div class="profile-sidebar"> <!-- profile image and social list here --> </div> <div class="profile-body"> <!-- name, position, description here --> </div>
</div>

Это не слишком сложно с любой стороны, и как только вы поймете, как работает flexbox, все относительно просто. Когда мы зададим display: flex для .card, мы получим две колонки, а затем нам нужно перейти к ним и начать их стилизацию. Вот рабочий пример со всеми стилями:

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

Упрощение всего с помощью CSS Grid

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

Мы привыкли обязательно применять div для этого, как в приведенном выше примере с flexbox. Благодаря сетке мы можем полностью удалить элементы div.

<div class="card"> <img src="https://i.pravatar.cc/125?image=3" alt="" class="profile-img"> <ul class="social-list"> ... </ul> <h2 class="profile-name">Ramsey Harper</h2> <p class="profile-position">Graphic Designer</p> <p class="profile-info">Lorem ipsum ...</p>
</div>

С точки зрения разметки, разве это не имеет больше смысла? У нас есть .card, а затем мы размещаем содержимое этого компонента. Нам не нужно беспокоиться о том, как разобраться в том, как он будет структурирован, мы просто размещаем контент, который нам нужен.

Структурирование макета

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

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

CSS Grid меняет наше представление о структуре контента

С flexbox мы создавали два элемента div, которые работали как столбцы. При использовании сетки мы вместо этого настраиваем всю сетку в самом родителе, а затем можем указать дочерним элементам, каким частям сетки они принадлежат.

Чтобы настроить сетку, мы можем сделать что-то вроде этого:

.card { display: grid; grid-template-columns: 1fr 3fr;
}

Единица fr является уникальной для сетки, и представляет собой одну часть свободного пространства. Такое использование очень похоже на установку двух столбцов во flexbox и указание для них ширины 25% и 75% соответственно.

Размещение элементов в сетке

Может быть, это потому, что я в течение многих лет использовал для создания макетов float, но мне всегда кажется, что это немного магия, когда разные элементы оказываются там, где мы хотим их видеть!

Мы могли бы использовать grid-row и grid-column для каждого элемента, чтобы разместить их там, где мы хотим, но чем больше я использую сетку, тем больше мне нравится то, что дает нам grid-template-areas.

Настройка немного длиннее, но отдача действительно большая, когда мы делаем вещи адаптивными (мы скоро дойдем до этого).

Итак, сначала нам нужно настроить для .card grid-template-areas, а затем мы можем назначить всех потомков в эти области:

.card { ... display: grid; grid-template-columns: 1fr; grid-column-gap: 2em; grid-template-areas: "image name" "image position" "social description";
} .profile-name { grid-area: name; }
.profile-position { grid-area: position; }
.profile-info { grid-area: description; }
.profile-img { grid-area: image; }
.social-list { grid-area: social; }

Вот все это в действии:

Это так четко

Одна из вещей, которые мне нравятся в использовании grid-template-areas, это то, что кто-то посторонний может взглянуть на код и легко и сразу понять, что происходит.

Если кто-то показывает вам что-то, что было настроено с использованием grid-row и grid-column и чисел и интервалов, достаточно просто вычислить вещи и выяснить, где они окажутся. Для простых макетов, я думаю, что хорошо использовать их, но так приятно посмотреть только на CSS родительского элемента и сразу понять, как будет выглядеть весь этот макет.

Проще узнать фактический размер элемента при использовании сетки

В самом первом примере, когда мы установили ширину одного из элементов flex 50%, на самом деле это не было 50%. Если вы понимаете, почему это так, это здорово, но иногда это может раздражать. Это достаточно легко обойти, но при использовании сетки проблем гораздо меньше.

Поскольку мы определяем полный макет, мы также точно определяем, сколько места мы хотим отвести элементам.
И, конечно же, мы имеем minmax() и fr, которые немного мутят воду, поскольку они позволяют более гибкую настройку (как мы используем в примере выше), но даже с учетом этого мы все еще имеем полный контроль над этой гибкостью, и все это контролируется родителем, вместо того, чтобы устанавливать некоторые вещи для родителей, а другие — для потомков.

Ограниченные изменения

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

CSS Grid меняет наше представление о структуре контента

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

С плоской разметкой сетки все возможно! И в качестве дополнительного бонуса от использования grid-template-area, эти изменения вносятся очень просто!

.card { /* old layout grid-template-areas: "image name" "image position" "social description"; */ /* updated layout */ grid-template-areas: "image name" "image position" "image social" ". description";
}

Играя с grid-template-areas подобным образом, мы перемещает иконки социальных сетей туда, куда хотим, быстро и легко (в последней части указывается и пустая ячейка).

Это облегчает жизнь при работе с медиа-запросами

Как я уже упоминал несколько раз, один из аспектов, где это также полезно — это адаптивность. Мы можем полностью контролировать макет через родитель:

.card { /* setup for small screens */ display: grid; grid-template-columns: 1fr; grid-column-gap: 2em; grid-template-areas: "name" "image" "social" "position" "description";
}
.profile-name { grid-area: name;}
.profile-position { grid-area: position; }
.profile-info { grid-area: description; }
.profile-img { grid-area: image; }
.social-list { grid-area: social; } /* rearanging the layout for large screens */ @media (min-width: 600px) { .card { text-align: left; grid-template-columns: 1fr 3fr; grid-template-areas: "image name" "image position" "social description"; } .profile-name::after { margin-left: 0; }
}

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

Flexbox по-прежнему имеет свое место

Я все больше и больше обращаюсь к сетке, но думаю, что у flexbox все еще есть свое место. Если у меня логотип и меню навигации должны располагаться рядом друг с другом, можно просто сделать что-то вроде этого и знать, что они там, где мне нужно:

.header { display: flex; justify-content: space-between;}

То же самое касается ul, которые мы используем для навигации, чтобы просто разместить элементы рядом друг с другом, или, как вы могли заметить в примере карточки, который мы рассматривали, это идеально подходит для .social-list.

Для простых компонентов, где нам не нужна более сложная компоновка, это работает очень хорошо. Но я все больше и больше двигаюсь в сторону сетки, иногда из-за того, что она действительно нужна, а иногда из-за того, что я хочу использовать minmax() или fr.

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

Заключение

Как бы ни был хорош flexbox, он не проще, чем grid. Он действительно хорошо выполняет определенные задачи, но сетка при работе над более сложными макетами позволяет нам иметь гораздо больший контроль. Этот контроль усиливается при работе с адаптивным дизайном при внесении изменений в медиа-запросы.

С flexbox одно большое изменение — изменение направления flex. С помощью сетки мы можем полностью и быстро перестроить компонент.

Автор: Kevin Powell

Источник: https://www.freecodecamp.org

Редакция: Команда webformyself.