Как расположить элементы в строку с помощью Flexbox

Эта статья основана на одном из практических заданий verstaem.online.

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

Перейти к заданию

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

Создаем HTML-разметку

Сначала создадим базовую HTML-разметку страницы. с помощью Emmet. Нажимаем !, затем клавишу Tab, и у нас раскроется базовая структура. Сразу обращу ваше внимание на атрибут lang. Поскольку у нас здесь присутствует контент на русском языке, и лишь технические названия языков программирования на английском, я бы использовал ru.

<!doctype html>
<html lang="ru">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Панель фильтров</title>
  </head>
  <body>
  </body>
</html>

Далее переходим к самой панели. Здесь можно сразу определить одно общее правило, присущее нескольким подряд идущим элементам — их лучше всего делать с помощью списка <ul>.

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

Раз уж мы сделали список, то внутри него нужно сделать элементы списка — <li>. Здесь важно запомнить, что напрямую внутри списка могут быть только его элементы, а уже внутри них все остальное.

<ul class="panel">
  <li class="panel__item"></li>
  <li class="panel__item"></li>
  <li class="panel__item"></li>
  <li class="panel__item"></li>
</ul>

После этого нам нужно добавить сами фильтры — в данном случае это кнопки, тег <button>, т. к. элемент не осуществляет переход между страницами, а фильтрует контент. Не забудьте добавить отдельный класс для первой кнопки, т. к. она выделена активной в макете.

Теперь это выглядит так:

<ul class="panel">
  <li class="panel__item">
    <button class="panel__btn panel__btn--active">Все</button>
  </li>
  <li class="panel__item">
    <button class="panel__btn">HTML</button>
  </li>
  <li class="panel__item">
    <button class="panel__btn">CSS</button>
  </li>
  <li class="panel__item">
    <button class="panel__btn">JavaScript</button>
  </li>
</ul>

Добавляем стили

Переходим к стилизации. Для начала, разумеется, подключим файл стилей, который уже есть в проекте, используя <link>. После этого нам стоит задать базовые стили. Не будем тянуть целый reset.css, нам достаточно переопределить блочную модель, а также сбросить базовый отступ у <body>. Также сразу стоит подключить шрифт, который используется в задании — Inter.

* {
  box-sizing: border-box;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/InterRegular.woff2");
  font-display: swap;
  font-weight: 400;
}

body {
  margin: 0;
  font-family: "Inter", sans-serif;
}

Теперь можем переходить непосредственно к панели, и пойдем «сверху вниз», то есть от родителя к потомкам. Для начала стоит задать стили списку. Здесь нам нужно сбросить все лишнее — это и margin, и padding, и list-style. Впрочем, padding мы можем не просто переопределить, а сразу задать из макета.

Также, здесь мы впервые сталкиваемся с flexbox. Поскольку нам нужно, чтобы элементы списка встали в одну строку, нужно задавать display: flex именно родителю — списку. Также мы можем указать свойство gap для отступов между элементами.

.panel {
  display: flex;
  margin: 0;
  padding: 16px;
  list-style: none;
  gap: 12px;
}

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

Важно: не забудьте написать font-family: inherit, чтобы стиль от <body> передался кнопкам, т. к. они по умолчанию не умеют наследовать шрифт.

.panel__btn {
  display: inline-flex;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 12px 24px;
  font-family: inherit;
  font-weight: 400;
  font-size: 16px;
  color: #111827;
  background: #fff;
}

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

.panel__btn {
  display: inline-flex;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 12px 24px;
  font-family: inherit;
  font-weight: 400;
  font-size: 16px;
  color: #111827;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.3s, color 0.3s, background 0.3s;
}

.panel__btn:hover {
  border-color: #523ee8;
  color: #fff;
  background: #523ee8;
}

.panel__btn--active {
  border-color: #523ee8;
  color: #fff;
  background: #523ee8;
  pointer-events: none;
}

Последний важный момент здесь — свойство pointer-events: none. С его помощью мы «отключаем» возможность взаимодействия с элементом, то есть, на него больше нельзя нажать. Это сделано намеренно, ведь элемент уже активный, нет смысла делать его активным еще раз.

Теперь вы умеете выстраивать элементы в одну строку с помощью Flexbox, использовать gap для отступов и оформлять простую панель фильтров. Попробуйте добавить новые кнопки, изменить их размеры или адаптировать компонент для мобильных устройств — это поможет лучше закрепить полученные знания.

Решение задачи

предыдущий пост следующий пост