Полное руководство по css flex + опыт использования
Содержание:
Я довольно глуп
Сколько бы раз я не читал следующий параграф, я остался неспособным его понять…
Слова проходят через мои отверстия, преобразуются в электрические импульсы, путешествующие по моему оптическому нерву, и прибывают как раз вовремя, чтобы увидеть как мой мозг выбегает через черный ход в клубе дыма.
Как будто Минни Маус и Мэд Макс завели ребенка семь лет назад, и теперь он, будучи пьяным с мятного шнапса, оскорбляет всех в пределах слышимости словами, которые он узнал когда Мамочка и Папочка ругались.
Леди и Джентльмены, мы начали наш спуск в чепуху, что значит пришло время подвести итоги (или перестань читать, если ты здесь для изучения нового).
Самое интересное из того, что я узнал, читая спецификацию, это то, насколько неполным было мое понимание, несмотря на полдюжины блог-постов которые я прочитал, и на то, насколько относительно простым является flexbox. Оказывается, что «опыт» — это не просто занятие одним и тем же из года в год.
С удовольствием могу отметить, что время, потраченное мной на чтение, уже окупилось. Я прошелся по старому коду, выставил авто margin’ы, flex-значения в краткой записи auto или none, и задал минимальную ширину в ноль там, где это было нужно.
Я лучше отношусь к этому коду теперь, зная что я делаю это должным образом.
Еще я узнал, что несмотря на то, что спецификация — местами — перенасыщена и предназначена для вендоров как я и думал, все же содержит много дружественных слов и примеров. В ней даже выделены части которые скромные веб-разработчики могут пропустить.
Однако это спорный вопрос, потому что я рассказал тебе про все хорошие отрывки, так что тебе не нужно утруждать себя ее чтением.
Теперь, если позволите, мне надо идти и прочитать все остальные CSS спецификации.
P.S. Я крайне рекомендую прочитать следующий список всех flexbox багов по браузерам:github.com/philipwalton/flexbugs
CSS Advanced
CSS Rounded CornersCSS Border ImagesCSS BackgroundsCSS ColorsCSS Color KeywordsCSS Gradients
Linear Gradients
Radial Gradients
CSS Shadows
Shadow Effects
Box Shadow
CSS Text EffectsCSS Web FontsCSS 2D TransformsCSS 3D TransformsCSS TransitionsCSS AnimationsCSS TooltipsCSS Style ImagesCSS Image ReflectionCSS object-fitCSS object-positionCSS ButtonsCSS PaginationCSS Multiple ColumnsCSS User InterfaceCSS Variables
The var() Function
Overriding Variables
Variables and JavaScript
Variables in Media Queries
CSS Box SizingCSS Media QueriesCSS MQ ExamplesCSS Flexbox
CSS Flexbox
CSS Flex Container
CSS Flex Items
CSS Flex Responsive
flex-grow
Это свойство немного сложнее. Для начала зададим блокам одинаковую ширину в 120px:
По умолчанию значение равно 0. Это значит, что блокам запрещено увеличиваться в размерах. Зададим равным 1 для каждого блока:
Теперь блоки заняли оставшееся место в контейнере. Но что значит ? Попробуем сделать равным 999:
И… ничего не произошло. Так получилось из-за того, что принимает не абсолютные значения, а относительные
Это значит, что не важно, какое значение у , важно, какое оно по отношению к другим блокам:
Вначале каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда третьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.
работает только для главной оси, пока мы не изменим её направление.
8
Основы CSS Flexbox
Создание CSS разметки с помощью Flexbox начинается с установки необходимому HTML элементу CSS-свойства со значением или .
После этого данный элемент становится flex-контейнером, а все его непосредственные дочерние элементы – flex-элементами. При этом когда мы говорим о flexbox то подразумеваем под этим только элемент с или и все элементы непосредственно расположенные в нём. Таким образом в CSS Flexbox имеется всего два типа элементов: flex-контейнер и flex-элемент.
<style> .flex-container { display: flex; /* flex || inline-flex */ } <style> <!-- flex-контейнер --> <div class="flex-container"> <div>flex-элемент #1</div> <div>flex-элемент #2</div> <div>flex-элемент #3</div> </div>
По умолчанию flex-элементы во flex-контейнере занимают всю его высоту.
Значение или определяет то, как flex-контейнер будет представлен на странице. Если его необходимо отобразить в виде блока, то используйте значение . Если элемент необходимо представить как строку, то используйте значение . В этом случае он будет занимать столько места странице, сколько необходимо для отображения его элементов.
Устройство flex-контейнера. Направление осей
На рисунке представлена схема устройства flex-контейнера:
Направление расположение flex-элементы в flex-контейнере определяется посредством осей.
В CSS Flexbox имеются две оси. Первая ось называется главной (по умолчанию она направлена слева направо). Вторая — поперечная (по умолчанию направлена сверху вниз), она всегда перпендикулярно главной. Главная ось задаёт основное направление flex-элементов во flex-контейнере, а поперечная ось определяет их направление при переносе на новую линию.
По умолчанию элементы во flex-контейнере располагаются вдоль направления главной оси (т.е. слева направо) на одной линии.
Направление главной оси можно изменить, осуществляется это с помощью CSS-свойства .
flex-direction: row; /* row (слева направо) - по умолчанию row-reverse (справа налево) column (сверху вниз) column-reverse (снизу вверх) */
С помощью этого свойства можно сделать так, чтобы flex-элементы располагались не рядами (rows), а колонками (columns). Осуществляется это с помощью значения или .
По умолчанию flex-элементы не переносятся на новую линию, даже когда им не хватает места в текущей линии. Они просто выходят за её пределы.
Но это можно изменить. Разрешить перенос flex-элементов на новые линии осуществляется с помощью установки flex-контейнеру CSS свойства со значением или .
flex-wrap: wrap; /* nowrap (только на одной линии - по умолчанию) wrap (разрешить перенос flex-элементов на новые линии) wrap-reverse (осуществлять перенос flex-элементов в обратном порядке) */
Значения и CSS-свойства определяют направление поперечной оси.
Свойства и можно указать с помощью универсального CSS свойства :
flex-flow: row nowrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */
Вместо заключения
Итак, мы выяснили, в каких случаях уместнее использовать Float, Flexbox и Grid, но возможно ли их смешение? Давайте разберемся.
Если вы начали, например, использовать , то конечно же писать там свойства, которые относятся к Grid неуместно. Это неправильно.
Однако, если в одной части страницы блок выполнен полностью из Flexbox, а далее вам потребуется в следующем блоке сделать картинку, которая будет обрамляться текстом, то будет правильным использовать float.
Пример:
Не забывай задавать свои вопросы по вёрстке или фронтенд разработке у профессионалов на FrontendHelp в режиме онлайн.
Выравнивание flex-элементов
Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).
Выравнивание flex-элементов по направлению главной оси
Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства :
justify-content: flex-start; /* flex-start (flex-элементы выравниваются относительно начала оси) – по умолчанию flex-end (flex-элементы выравниваются относительно конца оси) center (по центру flex-контейнера) space-between (равномерно, т.е. с одинаковым расстоянием между flex-элементами) space-around (равномерно, но с добавлением половины пространства перед первым flex-элементом и после последнего) */
Выравнивание flex-элементов вдоль поперечной оси
Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства :
align-items: stretch; /* stretch (растягиваются по всей длине линии вдоль направления поперечной оси) – по умолчанию flex-start (располагаются относительно начала поперечной оси) flex-end (относительно конца поперечной оси) baseline (относительно базовой линии) center (по центру) */
Выравнивание линий flex-контейнера
CSS Flexbox позволяет выравнивать не только сами flex-элементы, но и линии на которых они расположены.
align-content: stretch /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) center (по центру) space-between (равномерно, т.е. с одинаковым расстоянием между линиями) space-around (равномерно, но с добавлением половины пространства перед первой линией и после последней) */
Свойство имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства значение или .
CSS-свойство align-self
Свойство в отличие от предыдущих (, и ) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство может принимать такие же значения как .
align-items: stretch; /* auto (по умолчанию) || stretch || flex-start || flex-end || baseline || center */
Пример:
<div class="flex-container"> <div class="flex-container_element-1"> 1 </div> <div class="flex-container_element-2"> 2 </div> <div class="flex-container_element-3"> 3 </div> <div class="flex-container_element-4"> 4 </div> </div>
CSS:
.flex-container { display: flex; width: 300px; height: 150px; align-items: center; padding: 10px; background-color: #efefef; } .flex-container_element-1, .flex-container_element-2, .flex-container_element-3, .flex-container_element-4 { flex-basis: 70px; text-align: center; padding: 15px; font-size: 30px; } .flex-container_element-1 { align-self: flex-start; background: #fe4; } .flex-container_element-2 { align-self: flex-end; background: pink; } .flex-container_element-3 { align-self: stretch; background: lime; } .flex-container_element-4 { align-self: auto; background: cyan; }
min-width имеет значение
Возможно, ты думаешь, что несложно заставить все flex-элементы внутри flex-контейнера сжиматься, для того чтобы уместить контент. Наверняка, если ты укажешь flex-shrink: 1 на элементах, они так и будут себя вести, правда?
Может, пример.
Скажем, у тебя есть часть DOM, которая отображает книгу на продажу и кнопку чтобы ее купить.
Ты разместил все с помощью flexbox и все хорошо.
(Поскольку ты хочешь кнопку «Купить» справа — даже для очень коротких названий — ты, будучи умным, указал margin-left: auto)
Название книги довольно длинное, поэтому оно использует столько пространства сколько может и затем переходит на следующую строку. Ты счастлив, жизнь прекрасна. Ты блаженно отправляешь свой код в продакшн, с уверенностью, что он выдержит все.
И потом получаешь неприятный сюрприз. Совсем не хорошего рода.
Некий дурень, много о себе возомнивший, написал книгу с длинным словом в названии.
Все сломано!
Если красная граница обозначает ширину смартфона, и ты скрываешь переполнение (overflow: hidden), ты только что потерял свою кнопку «Купить». Твой коэффициент конверсии — как и эго бедного автора — будет страдать.
(Примечание: к счастью, там где я работаю, есть хорошая QA команда, которая наполнила нашу базу данных разнородным текстом, наподобие такого. В частности, именно эта проблема побудила меня прочитать спецификацию.)
Оказывается, такое поведение происходит из-за того, что min-width элемента описания изначально установлена в auto, что в данном случае равняется ширине слова Electroencephalographically (электроэнцефалографически). Flex-элементу буквально не разрешается быть уже чем это слово.
Решение? Переопределить эту проблемную минимальную ширину min-width: auto установив min-width: 0, указывая flexbox’у, что этот элемент может быть уже, чем содержимое внутри него.
Теперь за управление текстом внутри элемента отвечаешь ты. Я предлагаю перенести слово. Таким образом, твой CSS будет выглядеть так:
Результат будет таким:
Опять же, min-width: 0 не какой-то хак для обхода нелепости, это .
В следующем разделе, я вернусь к тому, что кнопка «Купить» совсем не 80 пикселей по ширине, как я довольно ясно ей сказал.
CSS Tutorial
CSS HOMECSS IntroductionCSS SyntaxCSS SelectorsCSS How ToCSS CommentsCSS Colors
Colors
RGB
HEX
HSL
CSS Backgrounds
Background Color
Background Image
Background Repeat
Background Attachment
Background Shorthand
CSS Borders
Borders
Border Width
Border Color
Border Sides
Border Shorthand
Rounded Borders
CSS Margins
Margins
Margin Collapse
CSS PaddingCSS Height/WidthCSS Box ModelCSS Outline
Outline
Outline Width
Outline Color
Outline Shorthand
Outline Offset
CSS Text
Text Color
Text Alignment
Text Decoration
Text Transformation
Text Spacing
Text Shadow
CSS Fonts
Font Family
Font Web Safe
Font Fallbacks
Font Style
Font Size
Font Google
Font Pairings
Font Shorthand
CSS IconsCSS LinksCSS ListsCSS Tables
Table Borders
Table Size
Table Alignment
Table Style
Table Responsive
CSS DisplayCSS Max-widthCSS PositionCSS OverflowCSS Float
Float
Clear
Float Examples
CSS Inline-blockCSS AlignCSS CombinatorsCSS Pseudo-classCSS Pseudo-elementCSS OpacityCSS Navigation Bar
Navbar
Vertical Navbar
Horizontal Navbar
CSS DropdownsCSS Image GalleryCSS Image SpritesCSS Attr SelectorsCSS FormsCSS CountersCSS Website LayoutCSS UnitsCSS SpecificityCSS !important
justify-content
Copied!
Copied!
Copied!
Copied!
Copied!
Copied!
Свойство justify-content определяет, как браузер распределяет пространство вокруг флекс-элементов вдоль главной оси контейнера. Это делается после того, как применяются размеры и автоматические отступы, за исключением ситуации, когда по крайней мере у одного элемента flex-grow больше нуля. При этом не остаётся никакого свободного пространства для манипулирования.
Применяется к: flex контейнерам.
Значение по умолчанию: flex-start.
- flex-start
- Флексы прижаты к началу строки.
- flex-end
- Флексы прижаты к концу строки.
- center
- Флексы выравниваются по центру строки.
- space-between
- Флексы равномерно распределяются по всей строке. Первый и последний элемент прижимаются к соответствующим краям контейнера.
- space-around
- Флексы равномерно распределяются по всей строке. Пустое пространство перед первым и после последнего элементов равно половине пространства между двумя соседними элементами.
- space-evenly
- Флексы распределяются так, что расстояние между любыми двумя соседними элементами, а также перед первым и после последнего, было одинаковым.
The justify-content property aligns flex items along the main axis of the current line of the flex container. This is done after any flexible lengths and any auto margins have been resolved. Typically it helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.
Applies to: flex containers.
Initial: flex-start.
- flex-start
- Flex items are packed toward the start of the line. The main-start margin edge of the first flex item on the line is placed flush with the main-start edge of the line, and each subsequent flex item is placed flush with the preceding item.
- flex-end
- Flex items are packed toward the end of the line. The main-end margin edge of the last flex item is placed flush with the main-end edge of the line, and each preceding flex item is placed flush with the subsequent item.
- center
- Flex items are packed toward the center of the line. The flex items on the line are placed flush with each other and aligned in the center of the line, with equal amounts of space between the main-start edge of the line and the first item on the line and between the main-end edge of the line and the last item on the line. (If the leftover free-space is negative, the flex items will overflow equally in both directions.)
- space-between
- Flex items are evenly distributed in the line. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to flex-start. Otherwise, the main-start margin edge of the first flex item on the line is placed flush with the main-start edge of the line, the main-end margin edge of the last flex item on the line is placed flush with the main-end edge of the line, and the remaining flex items on the line are distributed so that the spacing between any two adjacent items is the same.
- space-around
- Flex items are evenly distributed in the line, with half-size spaces on either end. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to center. Otherwise, the flex items on the line are distributed such that the spacing between any two adjacent flex items on the line is the same, and the spacing between the first/last flex items and the flex container edges is half the size of the spacing between flex items.
- space-evenly
- Flex items are evenly distributed in the line. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to center. Otherwise, the flex items on the line are distributed such that the spacing between each one is the same.
flex-direction
Copied!
Copied!
Copied!
Copied!
Свойство flex-direction задаёт направление основных осей в контейнере и тем самым определяет положение флексов в контейнере. На само направление также влияет значение атрибута dir у контейнера.
Применяется к: flex контейнерам.
- row
- Главная ось направлена так же, как и ориентация текста, по умолчанию слева направо. Если значение dir задано как rtl, то направление оси идёт справа налево.
- row-reverse
- Похоже на значение row, но меняются местами начальная и конечная точки и главная ось направлена справа налево. Если значение dir задано как rtl, то направление оси идёт слева направо.
- column
- Главная ось располагается вертикально и направлена сверху вниз.
- column-reverse
- Главная ось располагается вертикально, но меняется положение начальной и конечной точек и ось направлена снизу вверх.
The flex-direction property specifies how flex items are placed in the flex container, by setting the direction of the flex container’s main axis. This determines the direction in which flex items are laid out.
Note: The reverse values do not reverse box ordering: like and , they only change the direction of flow. Painting order, speech order, and sequential navigation orders are not affected.
Applies to: flex containers.
- row
- The flex container’s main axis has the same orientation as the of the current . The main-start and main-end directions are equivalent to the and directions, respectively, of the current .
- row-reverse
- Same as row, except the main-start and main-end directions are swapped.
- column
- The flex container’s main axis has the same orientation as the of the current . The main-start and main-end directions are equivalent to the and directions, respectively, of the current .
- column-reverse
- Same as column, except the main-start and main-end directions are swapped.
Свойства Flexbox CSS
В следующей таблице перечислены свойства CSS, используемые с Flexbox:
Свойство | Описание |
---|---|
display | Указывает тип поля, используемого для элемента HTML |
flex-direction | Задает направление гибких элементов внутри контейнера Flex |
justify-content | Горизонтально выравнивает элементы Flex, если элементы не используют все доступное пространство на главной оси |
align-items | Вертикальное выравнивание элементов Flex, если элементы не используют все доступное пространство на поперечной оси |
flex-wrap | Указывает, должны ли элементы Flex обернуть или нет, если для них недостаточно места на одной гибкой линии |
align-content | Изменяет поведение свойства Flex-Wrap. Он похож на выравнивание-элементы, но вместо выравнивания элементов Flex, он выравнивает гибкие линии |
flex-flow | Сокращенное свойство для Flex-направление и Flex-Wrap |
order | Задает порядок гибкого элемента относительно остальных элементов Flex внутри того же контейнера |
align-self | Используется для элементов Flex. Переопределяет свойство выравнивания элементов контейнера |
flex | Сокращенное свойство для Flex-расти, Flex-сжатия и Flex-основы свойства |
❮ Назад
Дальше ❯
Авторы flexbox обладают хрустальным шаром
Как вы возможно знаете, свойство flex является краткой записью flex-grow, flex-shrink и flex-basis.
Должен признать, я потратил энное количество минут, гадая-проверяя различные значения для этой тройки, когда пытался заставить элементы тянуться так, как надо мне.
Что я не знал до сей поры, это то, что, в общем случае, я хочу одну из трех комбинаций:
- Если я хочу, чтобы элемент немного сжимался, когда места недостаточно, но не тянулся шире чем ему надо: flex: 0 1 auto
- Если мой flex-элемент должен тянуться для заполнения всего доступного пространства, и немного сжиматься если места не хватает: flex: 1 1 auto
- Если мой элемент не должен менять размеры совсем: flex: 0 0 auto
Надеюсь, что ты пока не на максимальном изумлении — сейчас станет еще поразительнее.
Видишь ли, Бригада Flexbox’а (мне нравится думать, что команда flexbox’а носит кожаные куртки с этой надписью сзади — доступны мужские и женские размеры). Где там было это предложение? Ах да, Бригада Flexbox’а знала, что я хочу эти три комбинации свойств в большинстве случаев. Поэтому они дали им .
Первый случай — это значение initial так что ключевое слово не нужно. Для второго случая используется flex: auto, и flex: none замечательно простое решение чтобы элемент не тянулся совсем.
Кто бы мог подуть! (Who woulda thunk it — игра слов, прим. переводчика)
Это как если бы было box-shadow: garish, что по умолчанию равнялось 2px 2px 4px hotpink потому что считалось «полезным значением по умолчанию».
Вернемся к невероятно уродливому книжному примеру. Чтобы сделать ту кнопку «Купить» стабильно широкой для попадания пальцем…
… мне всего лишь надо задать на ней flex: none:
(Да, я мог бы указать flex: 0 0 80px; и сэкономить строку CSS. Но есть что-то особенное в том, как ясно flex: none демонстрирует намерение кода. Это хорошо для Будущего Дэвида который забудет как это все работает.)
Свойство выравнивания содержимого
Свойство используется для выравнивания гибких линий.
В этих примерах мы используем контейнер высотой 600 пикселей с свойством Flex-Wrap, который имеет значение Wrap, чтобы лучше продемонстрировать свойство.
Пример
Значение пробел-между отображает гибкие линии с равным пространством между ними:
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: space-between;
}
Пример
Значение пространство вокруг отображает гибкие линии с пробелами до, между и после них:
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: space-around;
}
Пример
Значение Stretch растягивает гибкие линии, чтобы занять оставшееся пространство (по умолчанию):
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: stretch;
}
Пример
Значение Center отображает гибкие линии в середине контейнера:
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: center;
}
Пример
Значение Flex-Start отображает гибкие линии в начале контейнера:
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: flex-start;
}
Пример
Значение Flex-End отображает гибкие линии в конце контейнера:
.flex-container {
display: flex; height: 600px;
flex-wrap: wrap;
align-content: flex-end;
}