Выбор CSS макета — Grid или Flexbox?

от автора

Удачно оформленный макет удерживает пользователей на сайте, так как делает важные элементы доступными и легко находимыми. Слабые же макеты отпугивают посетителей, которые покидают ресурс, так и не найдя того, за чем пришли.
В веб-дизайне макет – это то, как сайт отображается на экране. В HTML 5 есть довольно много элементов, определяющих внешний вид веб-страницы: заголовок, навигационный блок, абзац, сноска, статья и нижний колонтитул, каждый из которых имеет свое особое значение в создании макета. Вместе же они формируют четыре основных раздела страницы – заголовок/баннер, поисковый блок, содержимое и нижний колонтитул.
Языки программирования помогают сделать сайты «живыми», но в основе каждой страницы по-прежнему лежит старый добрый HTML. При рассмотрении макетов необходимо учитывать факторы, определяющие их качество, а именно отзывчивость, порты просмотра, устройства отображения, браузеры и размеры экранов пользователей. Грамотный макет не только здорово смотрится, но также может сохранять задуманную структуру, вписываясь в экраны с любым возможным соотношением сторон. Как раз за эту подстройку и отвечает CSS. В текущей статье мы в общих чертах рассмотрим два его мощнейших инструмента: Flexbox и Grid.

Что такое макет CSS FLEXBOX?

Flexbox – это общепринятое сокращение для Flexible Box Module (модуль гибкого контейнера), который представляет собой одномерную модель макета. Это значит, что одновременно он может работать только со строкой или столбцом, но не с обоими сразу. Flexbox эффективно справляется с выравниванием, распределением и направлением элементов страницы.
Двумя основными понятиями этой модели макета являются главная ось и поперечная ось. Главная ось flex-контейнера – это основное направление, вдоль которого выстраиваются flex-элементы, поперечная же ось ей перпендикулярна.

Для начала давайте обернем HTML-элементы div во flex-wrapper.

<div class="flex-wrapper">   <div id="one">Header</div>   <div id="two">Nav</div>   <div id="three">Content</div>     <div id="four">Footer</div> </div>

В CSS родительский контейнер “flex-wrapper” преобразуется во flexbox с помощью простой инструкции.

.flex-wrapper {    display: flex;  } 

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

.flex-wrapper{    display: flex;    background-color: beige;  }  .flex-wrapper > div {    background-color: green;    height: 100px;    width: 100px;    margin: 10px;  } 

Вы можете видеть, как удачно элементы div располагаются по горизонтали, но при этом они занимают не всю область контейнера, и в конце остается пустое пространство. Это можно исправить, добавив flex-grow.

.flex-wrapper > div {    flex-grow: 1;  }

Свойство flex-grow отвечает за распределение каждого элемента flex-контейнера. По умолчанию значение этого свойства равно 0, присваивая же разное количество единиц div-элементам, вы увеличиваете их по отношению к остальным. Противоположный эффект дает свойство flex-shrink.

#one{    flex-grow: 10; }  /* таким образом первый div-элемент станет на 10 единиц больше остальных */

FLEX-DIRECTION

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

.flex-wrapper{    display: flex;    flex-direction: row; /* направление по умолчанию */  } .flex-wrapper{    display: flex;    flex-direction: row-reverse;   }

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

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

Здесь же упорядочивание происходит уже вертикально – сверху вниз.

.flex-wrapper{    display: flex;    flex-direction: column-reverse;  }

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

FLEX BASIS

Flex basis определяет размер элемента внутри контейнера. При этом значение размера может указываться в em, px или процентах. Это свойство отличается от flex-grow тем, что не распределяет пространство между элементами контейнера равномерно.

#three {    flex-basis: 200px;  }

FLEX

Flex – это сокращенное свойство, объединяющее flex-shrink, flex-grow и flex-basis. Его рекомендуется использовать вместо раздельного написания свойств, указывая в нем их значения в следующем порядке: flex-grow, flex-shrink, flex-basis.

.flex-wrapper {    display: flex;    flex: 0 0 200px;  } 

JUSTIFY-CONTENT И ALIGN-SELF

Justify-content и align-self – это идеальное решение для размещения div или контейнера в центре окна браузера.

.flex-wrapper {    display: flex;    flex: 0 0 200px;    justify-content: center;    align-items: center;  } 

CSS GRID Layout

CSS grid (сетка) представляет собой мощный двухмерный макет, при использовании которого можно одновременно работать со строками и столбцами. В основе CSS Grid лежит неявное разделение экрана на сетку из 12 частей, в которые в итоге и вписываются элементы.
Преимущество этой технологии перед Flexbox и другими видами макетов в ее возможности работать двухмерно. При этом она также упрощает позиционирование, и элементы контейнера могут размещаться, перекрывая друг на друга.

ОПРЕДЕЛЕНИЕ СЕТКИ В CSS GRID

Преобразование HTML-структуры в СSS сетку выполняется одной простой CSS инструкцией.

<div class="container">    <div id="one">Header</div>    <div id="two">Nav</div>    <div id="three">Content</div>     <div id="four">Aside</div>      <div id="five">Section</div>     <div id="six">Footer</div>  </div>  .container {    display: grid;  } 

GRID TEMPLATE-COLUMNS И GRID-TEMPLATE-ROWS

Свойства grid-template-columns и grid-template-row устанавливают величину столбца или строки, определяя размер div-элементов согласно присвоенным значениям, которые указываются в px, fr, процентах или em.

.container {    display: grid;    grid-template-columns:  40px 1fr 20%;     grid-template-rows: 200px;    background-color: beige;    } .container > div {    background-color: green;    margin: 10px;  } 

grid-template-columns: 40px 1fr 20%; — эта строка дает браузеру команду присвоить первому div ширину 40px, второй же занимает одну долю отведенного места, а третий 20%. Элементы с 4 по 6 автоматически смещаются под первые 3 и принимают те же значения в том же порядке, т.е. div 4 получает размер 40px, div 5 — одну долю, а div 6 – 20%.
Чтобы поместить все шесть div-элементов в одну строку нужно указать в свойстве grid-template-column шесть значений. При этом не обязательно использовать для столбцов разные единицы измерения, можно задать только проценты, fr или px.

grid-template-rows: 200px; — эта строка присваивает всем div-элементам высоту в 200px.

FR

.container {    display: grid;    grid-template-columns: 16.7% 16.7% 16.7% 16.7% 16.7% 16.7%;   } 

Присвоив 16,7% для 6 точек, я успешно разделил шесть элементов контейнера по шести равным частям экрана. Значение 16,7% я выбрал, потому что при умножении 16,7 на 6 как раз получится 100% ширины экрана.
Использование процентов и пикселей работает идеально, но им недостает гибкости, и они уступают наиболее эффективному компоненту – долям CSS сетки.
Fr – это дробная единица, которая присваивает каждому элементу одну долю доступного пространства, которое можно увеличивать, выделяя под div необходимую ему область.

Теперь наше свойство grid-template-columns стало:

grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; 

В результате каждый div-элемент был размещен на экране равномерно.

grid-template-columns: 1fr 2fr 1fr 2fr 1fr 1fr; 

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

ФУНКЦИЯ REPEAT

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

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

Синтаксис этой функции относительно прост. Сначала пишем слово “repeat”, после которого определяем, сколько раз нужно повторить размер, в данном случае 6, а затем указываем величину единицы измерения. Эта функция аналогичным образом работает со свойством template-row и позволяет использовать как fr, em, px, так и проценты.

GAP

Gap – это отступ, представляющий свойство CSS сетки, которое позволяет указывать расстояние между div-элементами контейнера. Работает оно точно также, как свойство margin и измеряется обычно в px.

gap: 10px;

GRID-COLUMN-START/GRID-COLUMN-END И GRID-ROW-START/GRID-ROW-END

Свойства grid-column-start и grid-column-end помещают элемент сетки в конкретное место столбца относительно определенных строк сетки. Свойства же grid-row-start и grid-row-end делают то же самое, но в отношении строки. Присваивая этим свойствам значения, можно удобно управлять начальной и конечной точкой элемента сетки, выделяя ему нужную область.

.container {    display: grid;    grid-template-columns: repeat (3, 1fr);    grid-template-rows: repeat(4, 200px);  } #one {    grid-column-start: 1;    grid-column-end: 3;    grid-row-start: 1;    grid-row-end: 4;  }

Если вы присвоите указанные значения первому div, то заметите, что он смещает второй div на одну единицу и занимает первые две позиции, смещая третий div вниз. В отношении же строк теперь он занимает три позиции и становится выше.
В программировании индексация производится по особому правилу, согласно которому мы обычно начинаем отсчет с 0. В этом случае последнее значение, как правило, упоминается, но не учитывается. Например, значение свойства grid-column-end равно 3, но по факту оканчивается оно на 2-х также, как и grid-row-end оканчивается на 3-х, а не на 4-х.

GRID-COLUMNS И GRID-ROW

Это сокращенный вариант для свойств grid-column-start/grid-column-end и grid-row-start/grid-row-end. В качестве значений в этом случае через слэш указываются начальные и конечные позиции элемента:

#one {    grid-column: 1/3;    grid-row: 1/4;  }

СОЗДАНИЕ ГАЛЕРЕЙ

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

Мозаичный макет галереи

Такой макет создает равные плитки изображений, равномерно распределенные по странице/контейнеру.

<div class="container">    <div id="one">Image One</div>    <div id="two">Image Two</div>    <div id="three">Image Three</div>     <div id="four">Image Four</div>      <div id="five">Image Five</div>     <div id="six">Image Six</div>    <div id="seven">Image Seven</div>    <div id="eight">Image Eight</div>    <div id="nine">Image Nine</div>  </div> .container{    display: grid;    grid-template-columns: repeat(3, 1fr);     grid-template-rows: repeat(3, 200px);    background-color: beige;    gap: 10px  } .container > div {    background-color: green;  } 

Этот код создаст прекрасный макет плиточной галереи изображений.

Мозаичный макет

Макет Masonry-галереи

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

.container {    display: grid;    grid-template-columns:  repeat(3, 1fr);     grid-template-rows: repeat(5, 200px);    background-color: beige;    gap: 10px;  } .container > div {    background-color: green;  } #one {    grid-column: 1/3;    grid-row: 1/4;  }  #two {   grid-row: 1/3;  }   #five {    grid-column: 4/2;  }    #seven {    grid-row: 6/1;  }

Макет Masonry

GRID TEMPLATE AREAS

Свойство Grid-template-areas присваивает элементам имена, чтобы свойство grid-area могло на них ссылаться. Работает оно аналогично grid-column и grid-row, позволяя легко отображать и размещать конкретные области в структуре сетки.

<div class="container">   <div id="one">Header</div>    <div id="two">Nav</div>    <div id="three">Aside</div>     <div id="four">Content</div>      <div id="five">Section</div>     <div id="six">Footer</div> </div> .container {    display: grid;    grid-template-columns:  repeat(3, 1fr);     grid-template-rows: repeat(2,100px);    background-color: beige;    gap: 10px;    grid-template-areas: 'header header header'                         'nav nav nav'                         'aside content content'                         'aside section section'                         'footer footer footer';  } .container > div {    background-color: green;    font-size: 40px;  }    #one {    grid-area: header;  }  #two {   grid-area: nav;  } #three {    grid-area: aside;  }      #four {    grid-area: content;  }  #five {    grid-area: section;  }     #six {    grid-area: footer;  }

GRID AREAS

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

Что же лучше — Flexbox или Grid?

В своей сути Grid является макетом на основе контейнеров, а Flexbox на основе содержимого. И тот, и другой по-своему эффективен, хотя CSS Grid включает больше возможностей и позволяет легче манипулировать строками и столбцами сетки. Прежде чем решать, какой использовать, следует проанализировать сложность, структуру и содержимое создаваемого вами сайта. Приведу еще одно несколько углубленное сравнение: в макете flexbox размер ячейки (flex-элемента) определяется в самом flex-элементе, а в макете Grid размер элемента определяется уже в его контейнере.
Лично я могу посоветовать использовать CSS Grid для общего макета сайта, а затем уже Flexbox для элементов контейнера. Однако CSS Grid также отлично работает с отдельными элементами и учитывает нюансы реальной структуры сетки лучше, чем Flexbox. Например, инструкция grid-template-areas отобразит структуру сайта буквально за несколько секунд, после чего вы сможете сосредоточится на выравнивании контента по своему усмотрению.

ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/523808/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *