Верстка макета с помощью CSS Grid

Автор: Ire Aderinokunbit    Источник: bitsofco.de
01.02.2017
1229
0
img

Не смотря на то, что CSS Grid еще в разработке, он уже близок к финишу. Сейчас он доступен в нескольких браузерах для тестирования и поиска возможных ошибок. CSS Grid довольно сложный, даже сложнее, чем Flexbox. В нем 17 новых свойств и много новых концепций на счет написания css. Пытаясь разобраться в новой спецификации и том, как она работает, я создала макет «Holy Grail» («Святой Грааль»).

О макете

«Holy Grail» - это макет страницы, которая состоит из 4 секций – шапки, футера и главного блока с двумя сайдбарами по бокам. Макет придерживается следующих правил:

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

Это довольно таки трудно сделать, используя только CSS.

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

Вот решение, к которому я пришла, используя CSS Grid. Сначала разметка:

<body class="hg">  
  <header class="hg__header">Title</header>
  <main class="hg__main">Content</main>
  <aside class="hg__left">Menu</aside>
  <aside class="hg__right">Ads</aside>
  <footer class="hg__footer">Footer</footer>
</body>   

Ну и CSS, всего на 31 строку (растянутый!):

.hg__header { grid-area: header; }
.hg__footer { grid-area: footer; }
.hg__main { grid-area: main; }
.hg__left { grid-area: navigation; }
.hg__right { grid-area: ads; }

.hg {
    display: grid;
    grid-template-areas: "header header header"
                         "navigation main ads"
                         "footer footer footer";
    grid-template-columns: 150px 1fr 150px;
    grid-template-rows: 100px 
                        1fr
                        30px;
    min-height: 100vh;
}

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
        grid-template-columns: 100%;
        grid-template-rows: 100px 
                            50px 
                            1fr
                            50px 
                            30px;
    }
}

Рассмотрим подробнее

Как я уже упоминала, CSS Grid может быть довольно сложным. Однако, для создания этого макета, я использовала только 4 новые свойства и 17:

  • grid-area
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows

Создание этого макета можно разбить на 5 шагов.

1. Определение сетки

Первое, что нужно сделать – определить области сетки, чтобы в дальнейшем обращаться к ним по именам. Для этого используем свойство grid-area.

.hg__header { grid-area: header; }
.hg__footer { grid-area: footer; }
.hg__main { grid-area: main; }
.hg__left { grid-area: navigation; }
.hg__right { grid-area: ads; }

Затем, используя свойство grid-template-areas, размечаем макет интуитивным и визуально понятным способом. Свойство grid-template-areas принимает как значение список строк, разделенных пробелом. Каждая строка представляет собой ряд. Внутри каждой строки находятся разделенные пробелом области сетки. Каждая область сетки занимает один столбец. Таким образом, если мы хотим, чтобы область занимала 2 колонки, указываем ее дважды.

В нашем макете 3 колонки и 3 ряда. Ряды шапки и футера охватывают 3 колонки, остальные области занимают по 1 колонке.

.hg {
    display: grid;
    grid-template-areas: "header header header"
                         "navigation main ads"
                         "footer footer footer";
}     

С этой разметкой мы получаем следующий результат:

2. Определение ширины колонок

Дальше нужно задать ширину колонок. Для этого используем свойство grid-template-columns. Как значение оно принимает список из разделенных пробелами ширин для каждой из колонок. Поскольку в нашем макете 3 колонки, задаем 3 ширины:

grid-template-columns: [column 1 width]  [column 2 width]  [column 3 width];

Сайдбары должны быть по 150px каждый.

.hg {
  grid-template-columns: 150px  [column 2 width] 150px;
}

Центральная колонка должна занимать все оставшееся пространство. Мы можем указать это, используя новую единицу - fr (фракцию). Эта единица представляет собой свободное пространство, оставшееся в сетке. В нашем случае – это текущая ширина сетки минус 300px (ширина двух сайдбаров).

.hg {
    grid-template-columns: 150px 1fr 150px;
}

После настройки колонок, макет выглядит так:

3. Определение высоты строк

Далее задаем высоту строк. Так же, как мы задавали ширину колонок с помощью grid-template-columns, задаем высоту строк с помощью grid-template-rows. Это свойство тоже принимает разделенный пробелами список высот для каждого ряда. Можно писать их в одну строку, но я думаю, что красивее и визуально понятнее, если писать их в столбик.

.hg {
    grid-template-rows: 100px 
                        1fr
                        30px;
}

Таким образом, высота шапки - 100 px, высота футера - 30px, а средняя колонка (с основным контентом и двумя сайдбарами) занимает все оставшееся пространство.

4. Фиксированный футер

Нужно, чтобы футер всегда был в нижней части страницы, даже если на ней мало контента. Для этого .hg элементу можно задать минимальную высоту, которая будет соответствовать высоте viewport:

.hg {
    min-height: 100vh;
}

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

5. Адаптивность

И наконец, адаптивность. На маленьких экранах, все элементы сетки должны отображаться в одну колонку, друг под другом. Для этого нужно переопределить 3 заданные ранее свойства - grid-template-areas, grid-template-columns и grid-template-rows.

Во-первых, нужно, чтобы все элементы стали в одну колонку в определенном порядке:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
    }
}

Теперь нужно, чтобы все элементы занимали 100% ширины:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-columns: 100%;
    }
}

И наконец, задаем высоту для каждого ряда. Все ряды, кроме главного, имеют определенную высоту:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-rows: 100px /* Header */
                            50px /* Navigation */
                            1fr /* Main Content */
                            50px /* Ads */
                            30px; /* Footer */
    }
}

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

Поддержка

Can I Use css-grid? Data on support for the css-grid feature across the major browsers from caniuse.com.

ПОХОЖИЕ СТАТЬИ: