DevGang
Авторизоваться

CSS Grid против Flexbox

Не так давно макет для всех HTML-страниц создавался с помощью таблиц, float элементов и других CSS-свойств, которые плохо подходили для стилизации сложных веб-страниц.

Затем появился flexbox - режим макета, который был специально разработан для создания надежных адаптивных страниц. Flexbox облегчает правильное выравнивание элементов и их содержимого, и в настоящее время является предпочтительной системой CSS для большинства веб-разработчиков.

Теперь у нас есть новый претендент на награду «Лучшая система для сборки в формате HTML» (название трофея находится в стадии разработки). Это мощная технология - CSS Grid, и к концу этого месяца она будет доступна изначально в Firefox 52 и Chrome 57, а скоро появятся другие браузеры (надеюсь).

Базовый тест макета

Чтобы понять, что такое создание макетов для каждой системы, мы создали одну и ту же HTML-страницу дважды - один с помощью flexbox, а другой - с помощью CSS Grid. 

Дизайн довольно простой - он состоит из центрированного контейнера, внутри которого у нас есть заголовок, основной раздел, боковая панель и нижний колонтитул. Вот основные «проблемы», которые мы должны решить, сохраняя при этом CSS и HTML как можно более чистыми:

  1. Расположите четыре основных раздела макета.
  2. Сделайте страницу адаптивной (боковая панель находится под основным содержимым на небольших экранах).
  3. Выровняйте содержимое заголовка - навигация слева, кнопка справа.

Как видите, для сравнения мы сделали все очень просто. Давайте начнем с проблемы номер один.

Задача 1: Позиция разделов страницы

Решение с помощью Flexbox

Мы начнем с решения на flexbox. Мы добавляем свойство display: flex к контейнеру и направляем его дочерние элементы вертикально. Это позволит расположить все разделы один под другим.

.container {
    display: flex;
    flex-direction: column;
}

Теперь нам нужно сделать основной раздел и боковую панель, они должны стоять рядом друг с другом. Поскольку flex-контейнеры, как правило, являются однонаправленными, нам нужно добавить элемент-обертку.

<header></header>
<div class="main-and-sidebar-wrapper">
    <section class="main"></section>
    <aside class="sidebar"></aside>
</div>
<footer></footer>

Затем мы делаем отображение обертки: display:flex и flex-direction.

.main-and-sidebar-wrapper {
    display: flex;
    flex-direction: row;
}

Последний шаг - установить размер основного раздела и боковой панели. Мы хотим, чтобы основной контент был в три раза больше боковой панели, что не сложно сделать с помощью flex или процентов.

.main {
    flex: 3;
    margin-right: 60px;
}
.sidebar {
   flex: 1;
}

Как вы можете видеть, flexbox работал довольно хорошо, но нам все еще требовалось довольно много свойств CSS + дополнительный элемент HTML. Посмотрим, как будет работать CSS Grid.

Решение с CSS Grid

Существует несколько разных способов использования сетки CSS, но мы будем использовать синтаксис grid-template-area, так как он кажется наиболее подходящим для того, чего мы пытаемся достичь.

Сначала мы определим четыре grid-area-s, по одному для каждого раздела страницы:

<header></header>
<!-- Обратите внимание, что на этот раз нет обертки -->
<section class="main"></section>
<aside class="sidebar"></aside>
<footer></footer>
header {
    grid-area: header;
}
.main {
    grid-area: main;
}
.sidebar {
    grid-area: sidebar;
}
footer {
    grid-area: footer;
}

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

.container {
    display: grid;

    /*  Определите размер и количество столбцов в нашей сетке.
        Модуль fr работает аналогично flex:
        Столбцы fr будут распределять свободное место в строке пропорционально их значению.
        У нас будет 2 столбца - первый будет в 3 раза больше второго. */
    grid-template-columns: 3fr 1fr;

    /*  Присвойте области сетки, которые мы сделали ранее, определенным местам сетки.
         Первый ряд - весь заголовок.
         Второй ряд разделен между главной и боковой панелью.
         Последний ряд все нижний колонтитул.  */
    grid-template-areas: 
        "header header"
        "main sidebar"
        "footer footer";

    /*  Отступы между каждой ячейкой сетки будут 60 пикселей. */
    grid-gap: 60px;
}

И это все! Наш макет теперь будет следовать приведенной выше структуре, и из-за того, как мы его настроили, нам даже не приходится иметь дело с полями или отступами.

Задача 2: сделать страницу отзывчивой

Решение Flexbox

Выполнение этого шага тесно связано с предыдущим. Для решения flexbox нам придется изменить направление flex-обертки и отрегулировать некоторые поля.

@media (max-width: 600px) {
    .main-and-sidebar-wrapper {
        flex-direction: column;
    }

    .main {
        margin-right: 0;
        margin-bottom: 60px;
    }
}

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

Решение с CSS Grid

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

@media (max-width: 600px) {
    .container {
    /*  Выровняйте области сетки для мобильного макета. */
        grid-template-areas: 
            "header header"
            "main main"
            "sidebar sidebar"
            "footer footer";
    }
}

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

@media (max-width: 600px) {
    .container {
        /*  Переопределите сетку в одну колонку. */
        grid-template-columns: 1fr;
        grid-template-areas: 
            "header"
            "main"
            "sidebar"
            "footer";
    }
}

Задача 3: Выровнять компоненты заголовка

Решение Flexbox

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

<header>
    <nav>
        <li><a href="#"><h1>Logo</h1></a></li>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
    </nav>
    <button>Button</button>
</header>

Самый простой способ сделать отзывчивые заголовки. Техника действительно проста:

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

Теперь список навигации и кнопка правильно выровнены. Осталось только сделать элементы внутри <nav> горизонтальными. Здесь проще всего использовать display: inline-block, но так как мы собираемся использовать flexbox, давайте применим решение только для flexbox:

header nav {
    display: flex;
    align-items: baseline;
}

Всего две строчки! Совсем неплохо. Давайте посмотрим, как CSS-сетка справляется с этим.

Решение с CSS Grid

Чтобы разделить навигацию и кнопку, мы должны сделать отображение заголовка: display: grid и настроить сетку из 2 столбцов. Нам также понадобятся две дополнительные строки CSS, чтобы расположить их на соответствующих границах.

header{
    display: grid;
    grid-template-columns: 1fr 1fr;
}
header nav {
    justify-self: start;
}
header button {
    justify-self: end;
}

Что касается встроенных ссылок внутри навигации - мы не могли сделать это правильно с помощью CSS-сетки. Вот как выглядит наша лучшая попытка:

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

header nav {
    display: grid;
    grid-template-columns: auto 1fr 1fr;
    align-items: end; 
}

Понятно, что CSS-сетка боролась с этой частью макета, но это не так уж и удивительно - она ​​сосредоточена на выравнивании контейнеров, а не на содержимом внутри них. Она просто не предназначено для того, чтобы делать последние примеры.

Заключение

Если вы прошли через всю статью (в этом случае отличная работа!), Заключение не должно вас удивить. Правда в том, что лучшей системы не существует - и flexbox, и CSS-сетка хороши в разных вещах и должны использоваться вместе, а не как альтернативы друг другу.

Для тех из вас, кто переходит непосредственно к заключению статей (не беспокойтесь, мы делаем это тоже), вот краткое изложение сравнения:

  • CSS-сетки отлично подходят для создания более широкой картины. Они позволяют легко управлять макетом страницы и даже могут обрабатывать более неортодоксальные и асимметричные дизайны.
  • Flexbox отлично подходит для выравнивания содержимого внутри элементов. Используйте flex, чтобы расположить мелкие детали дизайна.
  • Используйте CSS-сетки для 2D-макетов (строки и столбцы).
  • Flexbox работает лучше только в одном измерении (строки или столбцы).
  • Нет причин использовать только CSS-сетки или только flexbox. Изучите оба и используйте их вместе.
#CSS #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Сделайте первый шаг к новой профессии

Получить скидку