Flexbox

Free Preview
Продолжительность: 13 мин

Немного истории

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

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

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

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

Для реализации сложных макетов порой использовалисьсовсем изощренные методы, например табличная вёрстка. Его суть состоит в том, что для позиционирования элементов на странице используются свойства, имитирующие поведение HTML‑таблиц.

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

Для чего нужен flexbox и что это такое

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

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

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

Давайте рассмотрим пример из реальной жизни. Представьте что нам нужно сверстать вот такой блок: flex-container-example.png

Мы можем создать такой блок с использованием уже известных нам CSS-свойств. Например, жестко задать отступы между блоками, их выравнивание и т.д. Но основная проблема будет состоять в том, что это будет работать только для одного размера экрана. Если вы попробуете масштабировать получившийся блок верстка "поедет". То же самое каксается табличной верстки - реализовать можно, но таблицы предназначены для отображения данных, а не верстки.

С использованием flexbox данная проблема решается буквально в пару строк кода.

Flex-container и flex-direction

Основой работы с flexbox является flex-контейнер - это родительский блок, который будет:

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

Чтобы сделать элемент flex-контейнером, ему нужно задать свойство display: flex;:

<div class="container">
  <div class="item">Элемент 1</div>
  <div class="item">Элемент 2</div>
  <div class="item">Элемент 3</div>
</div>
<style>
  .container {
    display: flex;
  }
</style>
html

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

Flexbox оперирует двумя осями:

  • главная ось (main axis)
  • поперечная ось (cross axis)

По умолчанию главная ось идёт слева направо, а поперечная — сверху вниз. В примере выше мы явно не определяли направление и сработало значение по умолчанию. Однако, мы можем задать его явно. Для этого используется CSS-свойство flex-direction. Оно может принимать два возможных значения row и column, и задает направление главной оси по горизонтали и по вертикали соответвенно.

От направления главной оси зависит работа всех остальных свойств flexbox. При этом все они применябтся именно к контейнеру. Это принципиальное отличие от старых способов вёрстки, где каждый элемент приходилось настраивать отдельно.

Давайте подробнее рассмотрим свойства flex-контейнера и как они влияют на отображение содержимого.

Горизонтальное и вертикальное выравнивание

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

За выравнивание вдоль главной оси отвечает свойство justify-content. С его помощью задается то, как дочерние элементы будут распределены вдоль главной оси. Подробнее про все возможные значения этого свойства и их применение можно почитать в [документации для justify-content] (https://developer.mozilla.org/ru/docs/Web/CSS/Reference/Properties/justify-content). А здесь отметим только наиболее часто используемые значения:

  • space-between - первый и последний блоки прилипают к краям контейнера, а остальные элементы распределяются так, что между ними остается одинаковое расстояние.

  • space-around - все дочернии элементы равномерно распределяются внутри контейнера, при этом первые и последние блоки имеют отсуп от края контейнера равный половине расстояния между элементами.

За выравнивание вдоль поперечной оси отвечает свойство align-items. Как обычно, можно почитать подробности в документации . Наиболее части используются следущие значения:

  • flex-start/ flex-end - прижимает элементы к началу или концу флекс контейнера;
  • center - вырвнивает все элемены по центру контейнера;
  • baseline - выравнивает базовае линии дочерних элементов по центру контейнера.

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

Другие свойства flex-контенера

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

Например, свойство flex-wrap позволяет определить что делать с дочерними элементами, если они не помещаются внутри контейнера.

По умолчанию flex-контейнер пытается уместить все элементы в одну строку, даже если им откровенно тесно. В результате элементы могут сжиматься до очень маленькой ширины. Свойство flex-wrap управляет тем, разрешено ли элементам переноситься на новую строку. Основные значениякоторые принимает это свойство:

  • nowrap — значение по умолчанию, перенос запрещён;
  • wrap — элементы переносятся на новую строку, если не помещаются.

Если у flex-контейнера несколько строк (то есть используется flex-wrap), появляется ещё одно свойство — align-content. Оно отвечает за распределение строк вдоль поперечной оси, а не отдельных элементов.

Свойства элементов внутри flex-контейнера

Мы рассмотрели основные свойства flex-контейнера, но во flexbox существуют также ряд свойств, которые применяются к элементам внутри контейнера. Давайте рассмотрим их чуть подробнее.

flex-grow

Свойство flex-grow определяет, может ли элемент увеличиваться, если внутри контейнера есть свободное пространство. Если всем элементам задать flex-grow: 1, они разделят доступное пространство поровну. Если одному элементу задать flex-grow: 2, а остальным 1, то он займет в два раза больше свободного места.

flex-shrink

flex-shrink управляет тем, насколько элемент может сжиматься, если места не хватает. По умолчанию flex-shrink: 1, и это означает что элемент внутри контейнера может сжиматься. Если задать flex-shrink: 0 - элемент не будет сжиматься, даже если ему не хватает места.

flex-basis

flex-basis задаёт базовый размер элемента вдоль главной оси до распределения свободного пространства. Например мы можем задать flex-basis: 200px. Если flex-direction: row, то это будет ширина, если column - высота.

Сокращённая запись flex

Очень часто три свойства объединяют в одно:

.item {
  flex: 1 1 200px;
}
css

При такой записи на первом месте указывается flex-grow, далее идет flex-shrink и в конце - flex-basis, В итоге в одну строку мы записываем что элемент может расягиваться, сжиматься и его "базовый" размер должен быть 200px.

Итого

Flexbox — это мощный инструмент для построения адаптивных макетов. Он позволяет:

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

Следующий урок будет посвящен практическому применению flexbox.