Flex css3


article-main-image

Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?

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

Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.


Спецификация CSS Flexible Box Layout Module (в народе Flexbox) призвана кардинально изменить ситуацию в лучшую сторону при решении огромного количества задач. Flexbox позволяет контролировать размер, порядок и выравнивание элементов по нескольким осям, распределение свободного места между элементами и многое другое.

Основные преимущества flexbox

  1. Все блоки очень легко делаются “резиновым”, что уже следует из названия “flex”. Элементы могут сжиматься и растягиваться по заданным правилам, занимая нужное пространство.
  2. Выравнивание по вертикали и горизонтали, базовой линии текста работает шикарно.
  3. Расположение элементов в html не имеет решающего значения. Его можно поменять в CSS. Это особенно важно для некоторых аспектов responsive верстки.
  4. Элементы могут автоматически выстраиваться в несколько строк/столбцов, занимая все предоставленное место.
  5. Множество языков в мире используют написание справа налево rtl (right-to-left), в отличии от привычного нам ltr (left-to-right). Flexbox адаптирован для этого. В нем есть понятие начала и конца, а не права и лева. Т.е. в браузерах с локалью rtl все элементы будут автоматически расположены в реверсном порядке.
  6. Синтаксис CSS правил очень прост и осваивается довольно быстро.

Поддержка браузерами

Поддержка браузерами пока неполная (2014). Виноват в этом в основном Internet explorer, который поддерживает спецификацию 2011 года только начиная с 10 версии, . Не смотря на это, я бы порекомендовал обратить внимание на обширность поддержки всеми остальными мобильными и десктопными браузерами! Тут все прекрасно. Если Вам нужна мобильная версия сайта или web-based приложение, то его уже можно (а, возможно, и нужно) делать, используя все преимущества flexbox!

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

  • 2008 – CSS Working Group обсуждает предложение “Flexible Box Model” на основе XUL (XML User Interface Language – язык разметки в приложениях Mozilla) and XAML (Extensible Application Markup Language – язык разметки в приложениях Microsoft).
  • 2009 – опубликован черновик “Flexible Box Layout Module”. Chrome и Safari добавляет частичную поддержку, пока Mozilla начинает поддерживать XUL-подобный синтаксис, известный как “Flexbox 2009”.
  • 2011 – Tab Atkins берется за развитие Flexbox и публикует 2 черновика. В этих черновиках синтаксис изменен значительно. Chrome, Opera и IE 10 внедряют поддержку этого синтаксиса. Он известен под названием “flexbox 2011”
  • 2012 – Синтаксис снова немного изменен и уточнен. Спецификация переходит в статус Candidate Recommendation и известна под названием “flexbox 2012”. Opera внедряет беспрефиксную поддержку, Chrome поддерживает текущую спецификацию с префиксами, а Mozilla без них, IE10 добавляет поддержку устаревающего “flexbox 2011” синтаксиса.
  • 2014 – все новые браузеры поддерживают последнюю спецификацию (включая IE 11)

Мы будем рассматривать все примеры на основе новой спецификации. Если вам нужна поддержка старых Сhrome, FF и IE10, лучше использовать autoprefixer от Андрея Ситника, который автоматически добавит css правила и вендорные префиксы для устаревших спецификаций.

Начинаем погружение

Flexbox определяет набор CSS свойств для контейнера (flex-контейнер) и его дочерних элементов (flex-блоков). Первое, что нужно сделать – это указать контейнеру display:flex или display:inline-flex.

HTML

<div class="my-flex-container">  <div class="my-flex-block">item1</div>  <div class="my-flex-block">item2</div>  <div class="my-flex-block">item3</div> </div> 

CSS

.my-flex-container{  display: flex; } 

Основные свойства flex-контейнера. Главная и поперечная ось.

Одним из основных понятий в fleхbox являются оси.

  • Главной осью flex-контейнера является направление, в соответствии с которым располагаются все его дочерние элементы.
  • Поперечной осью называется направление, перпендикулярное главной оси.

Главная ось в ltr локали по умолчанию располагается слева направо. Поперечная – сверху вниз. Направление главной оси flex-контейнера можно задавать, используя базовое css свойство flex-direction.

flex-direction – направление главной оси

flexbox-main-columnflexbox-main-row

Доступные значения flex-direction:

  • row (значение по умолчанию) : слева направо (в rtl справа налево)
  • row-reverse: справа налево (в rtl слева направо)
  • column: сверху вниз
  • column-reverse: снизу вверх

justify-content – выравнивание по главной оси.

Css свойство justify-content определяет то, как будут выровнены элементы вдоль главной оси.

Доступные значения justify-content:

  • flex-start (значение по умолчанию) : блоки прижаты к началу главной оси
  • flex-end: блоки прижаты к концу главной оси
  • center: блоки располагаются в центре главной оси
  • space-between: первый блок располагается в начале главной оси, последний блок – в конце, все остальные блоки равномерно распределены в оставшемся пространстве.
  • space-around: все блоки равномерно распределены вдоль главной оси, разделяя все свободное пространство поровну.

flex-justify-content

align-items – выравнивание по поперечной оси.

Css свойство align-items определяет то, как будут выровнены элементы вдоль поперечной оси.

Доступные значения align-items:

  • flex-start: блоки прижаты к началу поперечной оси
  • flex-end: блоки прижаты к концу поперечной оси
  • center: блоки располагаются в центре поперечной оси
  • baseline: блоки выровнены по их baseline
  • stretch (значение по умолчанию) : блоки растянуты, занимая все доступное место по поперечной оси, при этом все же учитываются min-width/max-width, если таковые заданы.

flex-align-items

СSS свойства flex-direction


, justify-content, align-items должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.

Демо основных свойств flex-контейнера

Оси и выравнивания по ним – это основы flex. Расслабьтесь, покликайте по демке и используйте ее, если нужно будет освежить в памяти.

flexbox demo

Многострочная организация блоков внутри flex-контейнера.

flex-wrap

Все примеры, которые мы приводили выше, были построены с учетом однострочного (одностолбцового) расположения блоков. Надо сказать, что по умолчанию flex-контейнер всегда будет располагать блоки внутри себя в одну линию. Однако, спецификацией также поддерживается многострочный режим. За многострочность внутри flex-контейнера отвечает CSS свойство flex-wrap.

Доступные значения flex-wrap:

  • nowrap (значение по умолчанию) : блоки расположены в одну линию слева направо (в rtl справа налево)
  • wrap: блоки расположены в несколько горизонтальных рядов (если не помещаются в один ряд). Они следуют друг за другом слева направо (в rtl справа налево)
  • wrap-reverse: то-же что и wrap, но блоки располагаются в обратном порядке.

flex-flow

– удобное сокращение для flex-direction + flex-wrap

По сути,flex-flow предоставляет возможность в одном свойстве описать направление главной и многострочность поперечной оси. По умолчанию flex-flow: row nowrap.

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

CSS

/* т.е. ... */  .my-flex-block{  flex-direcrion:column;  flex-wrap: wrap; }  /* это то же самое, что ... */  .my-flex-block{  flex-flow: column wrap; } 

align-content

Существует также свойство align-content, которое определяет то, каким образом образовавшиеся ряды блоков будут выровнены по вертикали и как они поделят между собой все пространство flex-контейнера.

Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse;)

Доступные значения align-content:

  • flex-start: ряды блоков прижаты к началу flex-контейнера.
  • flex-end: ряды блоков прижаты к концу flex-контейнера
  • center: ряды блоков находятся в центре flex-контейнера
  • space-between: первый ряд блоков располагается в начале flex-контейнера, последний ряд блоков блок – в конце, все остальные ряды равномерно распределены в оставшемся пространстве.
  • space-around: ряды блоков равномерно распределены в от начала до конца flex-контейнера, разделяя все свободное пространство поровну.
  • stretch (значение по умолчанию): Ряды блоков растянуты, дабы занять все имеющееся пространство.

flex-align-content

СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.

Демо свойств многострочности в flex

flexbox demo

CSS правила для дочерних элементов flex-контейнера (flex-блоков)

flex-basis – базовый размер отдельно взятого flex-блока

Задает изначальный размер по главной оси для flex-блока до того, как к нему будут применены преобразования, основанные на других flex-факторах. Может быть задан в любых единицах измерения длинны (px, em, %, …) или auto(по умолчанию). Если задан как auto – за основу берутся размеры блока (width, height), которые, в свою очередь, могут зависеть от размера контента, если не указанны явно.

flex-grow – “жадность” отдельно взятого flex-блока

Определяет то, на сколько отдельный flex-блок может быть больше соседних элементов, если это необходимо. flex-grow принимает безразмерное значение ( по умолчанию 0)

Пример 1:

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:1, то они будут одинакового размера
  • Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные

Пример 2:

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:3, то они будут одинакового размера
  • Если один из них имеет flex-grow:12, то он будет в 4 раза больше, чем все остальные

Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень “жадности” по отношению к другим flex-блокам того же уровня.

flex-shrink – фактор “сжимаемости” отдельно взятого flex-блока

Определяет, насколько flex-блок будет уменьшаться относительно соседних эдементов внутри flex-контейнера в случае недостатка свободного места. По умолчанию равен 1.

flex – короткая запись для свойств flex-grow, flex-shrink и flex-basis

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

CSS

/* т.е. ... */  .my-flex-block{  flex-grow:12;  flex-shrink:3;  flex basis: 30em; }  /* это то же самое, что ... */  .my-flex-block{  flex: 12 3 30em; } 

Демо для flex-grow, flex-shrink и flex-basis

flexbox demo

align-self – выравнивание отдельно взятого flex-блока по поперечной оси.

Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.

Доступные значения align-self (те же 5 вариантов, что и для align-items)


  • flex-start: flex-блок прижат к началу поперечной оси
  • flex-end: flex-блок прижат к концу поперечной оси
  • center: flex-блок располагаются в центре поперечной оси
  • baseline: flex-блок выравнен по baseline
  • stretch (значение по умолчанию) : flex-блок растянут, чтобы занять все доступное место по поперечной оси, при этом учитываются min-width/max-width, если таковые заданы.

order – порядок следования отдельно взятого flex-блока внутри flex-контейнера.

По умолчанию все блоки будут следовать друг за другом в порядке, заданном в html. Однако этот порядок можно изменить с помощью свойства order. Оно задается целым числом и по умолчанию равно 0.

Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.

HTML

<div class="my-flex-container">  <div class="my-flex-block" style="order: 5" >item1</div>  <div class="my-flex-block" style="order: 10">item2</div>  <div class="my-flex-block" style="order: 5" >item3</div>  <div class="my-flex-block" style="order: 5" >item4</div>  <div class="my-flex-block" style="order: 0" >item5</div> </div> 

В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2

Демо для align-self и order

flexbox demo

margin: auto по вертикали. Мечты сбываются!

Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!

.my-flex-container {  display: flex;  height: 300px; /* Или что угодно */ }  .my-flex-block {  width: 100px; /* Или что угодно */  height: 100px; /* Или что угодно */  margin: auto; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ } 

Вещи, которые следует помнить

  1. Не следует использовать flexbox там, где в этом нет необходимости.
  2. Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
  3. Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
  4. Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
  5. Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
  6. flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580

В заключение

Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости 😉

html5.by

Поддержка браузерами технологии CSS Flexbox

Технология Flexbox поддерживается уже почти всеми используемые на сегодняшний момент браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).

Основы Flexbox (сетка)

В основу Flexbox положена сетка. Она состоит всего из 2 элементов. Первый элемент – это flex-контейнер. Создание flex-контейнера осуществляется посредством добавления к необходимому HTML элементу CSS-свойства display со значением flex или flex-inline.

После этого все непосредственные дочерние элементы flex-контейнера (дети) автоматически становятся flex-элементами (2 элемент flexbox сетки).

HTML разметка:

  <div class="flex-container">   <div>1</div>   <div>2</div>   <div>3</div>   <div>4</div>  </div>  

CSS-стили:

  .flex-container {   display: flex; /* flex || inline-flex */  }  
Структура flexbox сетки
Структура flexbox сетки

Flex-элементы по умолчанию занимают всю высоту flex-контейнера.

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

Направление выстраивания flex-элементов

Указание направления выстраивания flex-элементов внутри flex-контейнера осуществляется посредством осей.

CSS Flexbox — Направление осей по умолчанию
CSS Flexbox - Направление осей по умолчанию

Во flexbox выделяют 2 оси. Первая ось называется основной или главной (по умолчанию направлена вправо). Вторая — поперечная (по умолчанию направлена вниз).

Элементы во flex-контейнере располагаются в одну линию (по умолчанию) даже тогда, когда им не хватает места. Выстраиваются flex-элементы в flex-контейнере по направлению основной оси.

Расположение элементов в контейнере по умолчанию (flex-элементы, которым не хватает места во flex-контейнере, вылезают за его пределы)
CSS Flexbox - Расположение элементов в контейнере по умолчанию

В CSS Flexbox разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии) осуществляется с помощью установки flex-контейнеру CSS свойства flex-wrap со значением wrap или wrap-reverse.

  flex-wrap: wrap;   /*    nowrap (в одну линию - по умолчанию)    wrap (разрешить перенос flex-элементов на новые линии)    wrap-reverse (осуществлять перенос flex-элементов в обратном порядке)   */  

Значения wrap и wrap-reverse CSS-свойства flex-wrap определяют направление поперечной оси.

Установка направления главной оси flexbox осуществляется с помощью CSS-свойства flex-direction.

  flex-direction: row;   /*    row (вправо) - по умолчанию   row-reverse (налево)   column (вниз)   column-reverse (вверх)  */  

С помощью этого свойства можно сделать так, чтобы flex-элементы располагались не горизонтально (строками), а вертикально (колонками).

CSS Flexbox — Расположение элементов при установке свойству flex-direction значения column, а flex-wrap — wrap
CSS Flexbox - Расположение элементов при установке свойству flex-direction значения column, а flex-wrap - wrap

Свойства flex-direction и flex-wrap можно указать с помощью универсального CSS свойства flex-flow:

  flex-flow: row nowrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */  

Выравнивание flex-элементов

Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).

Выравнивание flex-элементов по направлению главной оси

Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства justify-content:

  justify-content: flex-start;   /*    flex-start (flex-элементы выравниваются относительно начала оси) – по умолчанию   flex-end (flex-элементы выравниваются относительно конца оси)   center (по центру flex-контейнера)   space-between (равномерно, т.е. с одинаковым расстоянием между flex-элементами)   space-around (равномерно, но с добавлением половины пространства перед первым flex-элементом и после последнего)  */  
Варианты выравнивания flex-элементов вдоль главной оси
CSS Flexbox - Варианты выравнивания flex-элементов вдоль главной оси

Выравнивание flex-элементов вдоль поперечной оси

Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства align-items:

  align-items: stretch;  /*    stretch (растягиваются по всей длине поперечной оси) – по умолчанию   flex-start (относительно начала поперечной оси)   flex-end (относительно конца поперечной оси)   baseline (относительно базовой линии)   center (по центру)  */  
Варианты выравнивания flex-элементов вдоль поперечной оси
CSS Flexbox - Варианты выравнивания flex-элементов вдоль поперечной оси<

Выравнивание линий flex-контейнера

CSS Flexbox позволяет выравнивать не только сами flex-элементы, но и линии на которых они расположены.

  align-content: stretch  /*    stretch (растягиваются по всей длине поперечной оси) – по умолчанию   flex-start (относительно начала поперечной оси)   flex-end (относительно конца поперечной оси)   center (по центру)   space-between (равномерно, т.е. с одинаковым расстоянием между линиями)   space-around (равномерно, но с добавлением половины пространства перед первой линией и после последней)  */  
Варианты выравнивания линий flex-контейнера
CSS Flexbox - Варианты выравнивания линий flex-контейнера<

Свойство align-content имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства flex-wrap значение wrap или wrap-reverse.

CSS-свойство align-self

Свойство align-self в отличие от предыдущих (justify-content, align-items и align-content) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство align-self может принимать такие же значения как align-items.

  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;  }   
Как работает CSS свойство align-self
Как работает CSS свойство align-self

Изменение порядка следования flex-элементов

По умолчанию flex-элементы отображаются во flex-контейнере в том порядке, в котором они расположены в HTML коде. Для изменения порядка следования одних flex-элементов относительно других в CSS Flexbox можно использовать свойство order. Данное CSS свойство выстраивает flex-элементы во flex-контейнере в порядке возрастания их номеров.

  order: 0;   /*    0 (по умолчанию)   целое положительное или отрицательное число  */  

Например:

  <div class="flex-container">   <div class="flex-container_element-1">...</div>   <div class="flex-container_element-2">...</div>   <div class="flex-container_element-3">...</div>   <div class="flex-container_element-4">...</div>  </div>  CSS:  .flex-container {   display: flex;  }  /* переместим 2 flex-элемент в конец */  .flex-container_element-2 {   order: 2;  }   /* передвинем 3 элемент до 2 */  .flex-container_element-3 {   order: 1;  }  /* расположим 4 flex-элемент до 1 */  .flex-container_element-4 {   order: -1;  }  
Как работает CSS свойство order
Flexbox - Как работает CSS свойство order

Управление шириной flex-элемента

Во Flexbox есть несколько CSS свойств, определяющих то, какая ширина может быть у flex-элемента.

CSS-свойство flex-basis

Данное свойство предназначено для установления начальной ширины flex-элементу. Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto (в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого).

Конечная ширина flex-элемента будет определяться в зависимости от значений CSS-свойств flex-grow и flex-shrink, которые установлены не только для этого элемента, но и для других flex-элементов этого flex-контейнера.

CSS-свойство flex-grow

Это свойство определяет, может ли начальная ширина flex-элемента увеличиваться (расти). Увеличение ширины flex-элемента осуществляется за счёт свободного пространства линии. В качестве значения CSS-свойства flex-grow указывается целое число. Именно это значение и определяет (если оно больше или равно 1) какую часть свободного пространства flex-элемент заберёт себе.

Например:

  <div class="flex-container">   <div class="flex-container_element-1">...</div>   <div class="flex-container_element-2">...</div>   </div>  CSS:  .flex-container {   display: flex;   width: 600px;  }  .flex-container_element-1 {   flex-basis: 40%;   flex-grow: 1;  }   .flex-container_element-2 {   flex-basis: 40%;   flex-grow: 4;  }  
Как работает CSS свойство flex-grow
Как работает CSS свойство flex-grow

В этом примере, если flex-элементы расположены на одной линии и в ней есть свободное пространство (600×(1-0,8)=120px):

  • к ширине элемента .flex-container_element-1 добавится 1/5 часть этого пространства (120×1/5=24px);
  • к ширине элемента .flex-container_element-2 добавится 4/5 части этого пространства (120×4/5=96px).

Другими словами, CSS свойство flex-grow позволяет не просто указать, что ширина flex-элемента может вырасти, но и задать, насколько эта величина может вырасти по отношению к другим элементам.

По умолчанию CSS свойство flex-grow имеет значение 0. Это означает, что flex-элемент не может расти (увеличивать свою ширину).

CSS-свойство flex-shrink

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

Например:

  <div class="flex-container">   <div class="flex-container_element-1">...</div>   <div class="flex-container_element-2">...</div>   </div>  CSS:  .flex-container {   display: flex;   width: 500px;  }  .flex-container_element-1 {   flex-basis: 300px;   flex-shrink: 1;  }   .flex-container_element-2 {   flex-basis: 300px;   flex-shrink: 3;  }  
Как работает CSS свойство flex-shrink
Как работает CSS свойство flex-shrink

Ширина flex-контейнера 500px. Для отображения flex-элементов необходимо 600px. В итоге не хватает 100px. В этом примере уменьшаться могут 2 flex-элемента (.flex-container_element-1 и .flex-container_element-2). Ширина первого flex-элемента .flex-container_element-1 в данном случае составит 300 – 1/4*100= 275px. Ширина второго flex-элемента .flex-container_element-2 в данном случае составит 300 – 3/4*100= 225px.

Значение по умолчанию:

  flex-shrink: 1;  

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

CSS-свойство flex

Для удобной установки flex-grow, flex-shrink и flex-basis можно использовать CSS свойство flex.

Значение по умолчанию:

  flex: 0 1 auto;  /*   0 - flex-grow (1 значение)   1 - flex-shrink (2 значение)   auto - flex-basis (3 значение)  */  

Верстка макета страницы на CSS Flexbox

В этом разделе создадим простой адаптивный макет на Flexbox.

Структура макета будет состоять из 3 секций:

  • header (для вывода заголовка и основного меню);
  • main (для отображения основной части);
  • footer (для футера).

Основную часть (main) в свою очередь разделим ещё на 2 раздела (их позиционирование будем осуществлять с помощью CSS Flexbox). На больших экранах (>=992px) эти разделы выстроим горизонтально, а на остальных — вертикально (<992px).

  <header class="container">   [Шапка страницы...]  </header>  <main class="container">   <div class="row-flex">   <article class="main_article col-flex">   [Основная часть...]   </article>   <aside class="main_aside col-flex">   [Дополнительная часть...]   </aside>   </div>  </main>  <footer class="container">   [Футер...]  </footer>  

CSS:

  /* контейнер (устанавливает ширину блока в зависимости от ширины viewport) */  .container {   position: relative;   margin-left: auto;   margin-right: auto;   padding-right: 15px;   padding-left: 15px;  }  @media (min-width: 576px) {   .container {   width: 540px;   max-width: 100%;   }  }  @media (min-width: 768px) {   .container {   width: 720px;   max-width: 100%;   }  }  @media (min-width: 992px) {   .container {   width: 960px;   max-width: 100%;   }  }  @media (min-width: 1200px) {   .container {   width: 1140px;   max-width: 100%;   }  }  /* flex-контейнер */  .row-flex {   display: -webkit-box;   display: -webkit-flex;   display: -ms-flexbox;   display: flex;   -webkit-flex-wrap: wrap;   -ms-flex-wrap: wrap;   flex-wrap: wrap;   margin-right: -15px;   margin-left: -15px;  }  /* CSS настройки flex-элементов */  .col-flex {   position: relative;   width: 100%;   min-height: 1px;   padding-right: 15px;   padding-left: 15px;  }  /* ширина блоков article и aside по умолчанию */  .main_article, .main_aside {   -webkit-box-flex: 0;   -webkit-flex: 0 0 100%;   -ms-flex: 0 0 100%;   flex: 0 0 100%;   max-width: 100%;  }  /* ширина блоков article и aside для больших экранов */  @media (min-width: 992px) {   /* 2/3 от ширины контейнера */   .main_article {   -webkit-box-flex: 0;   -webkit-flex: 0 0 66.666667%;   -ms-flex: 0 0 66.666667%;   flex: 0 0 66.666667%;   max-width: 66.666667%;   }   /* 1/3 от ширины контейнера */   .main_aside {   -webkit-box-flex: 0;   -webkit-flex: 0 0 33.333333%;   -ms-flex: 0 0 33.333333%;   flex: 0 0 33.333333%;   max-width: 33.333333%;   }  }  

Для поддержки макета большинством браузеров добавим в CSS необходимые префиксы и max-width.

Для «превращения» блока во flex-контейнер будем использовать класс row-flex. Установку ширины каждому flex-элементу (main_article и main_aside) внутри flex-контейнера будем осуществлять с помощью CSS-свойства flex.

Макет веб-страницы на Flexbox
Макет веб-страницы на Flexbox

В качестве примера разметим посредством Flexbox ещё блок «Футер» и секцию раздела main-article «Интересненькое на сайте».

Секцию «Футер» разделим на 4 равные части (минимальная ширина одной части — 200px), а «Интересненькое на сайте» на 3 части (минимальная ширина одной части — 300px).

  <header class="container">   [Шапка страницы...]  </header>  <main class="container">   <div class="row-flex">   <article class="main_article col-flex">   [Основная часть...]   <!-- Секция "Интересненькое на сайте -->   <div class="row-flex">   <div class="main_other_article col-flex" style="min-width:300px">   [Ещё 1...]   </div>   <div class="main_other_article col-flex" style="min-width:300px">   [Ещё 2...]   </div>   <div class="main_other_article col-flex" style="min-width:300px">   [Ещё 3...]   </div>   </div>   </article>   <aside class="main_aside col-flex">   [Дополнительная часть...]   </aside>   </div>  </main>  <footer class="container">   <div class="row-flex">   <div class="footer_block col-flex" style="min-width:200px">   [Секция футера 1...]   </div>   <div class="footer_block col-flex" style="min-width:200px">   [Секция футера 2...]   </div>   <div class="footer_block col-flex" style="min-width:200px">   [Секция футера 3...]   </div>   <div class="footer_block col-flex" style="min-width:200px">   [Секция футера 4...]   </div>   </div>  </footer>  

Дополнительный CSS:

  .footer_block, .main_other_article {   -webkit-flex-basis: 0;   -ms-flex-preferred-size: 0;   flex-basis: 0;   -webkit-box-flex: 1;   -webkit-flex-grow: 1;   -ms-flex-positive: 1;   flex-grow: 1;   max-width: 100%;  }  

Демо макета страницы на Flexbox

itchief.ru

Подробное руководство по свойству CSS3 Flexbox

Flexbox Layout официально называется CSS Flexible Box Layout Module — это новый модуль для макетов в CSS3, направленный на улучшение работы с элементами, их выравнивание, изменения направление и порядка их в контейнере, даже когда они динамические или неизвестного размера. Важнейшей особенностью flex-контейнера является возможность изменять ширину или высоту ее потомков, чтобы заполнять свободное пространство при различных размерах экрана.

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

Вместо того, чтобы объяснять как свойства Flex работают, эта статья будет сосредоточена на том, как они визуально оказывают влияние на макет.

Основы

Прежде чем мы начнем с описания flexbox-свойств давайте немного познакомимся с моделью flexbox. Flex-макет состоит из родительского контейнера, указанного как flex-container, и его блоков-потомков, которые называются flex-items (см. ниже).

CSS3-Flexbox-модель

На изображении выше вы можете видеть свойства и терминологию, используемую для описания flex-контейнера и его потомков. Для получения дополнительной информации вы можете прочитать спецификацию model flexbox от W3C.

Поддержка flexbox прошла через несколько изменений синтаксиса от его первоначального проекта в 2009 году, поэтому, чтобы избежать путаницы мы будем использовать только синтаксис с последнего рабочего проекта (Сентябрь 2014). Если вам нужно сохранить поддержку старых браузеров вы можете прочитать эту статью о том, как сделать это наилучшим образом.

Поддержка браузерами последней спецификации flexbox:

  • Chrome 29+
  • Firefox 28+
  • Internet Explorer 11+
  • Opera 17+
  • Safari 6.1+ (с префиксом -webkit-)
  • Android 4.4+
  • IOS 7.1+ (с префиксом -webkit-)

Вы можете просмотреть подробную информацию о поддержке браузерами и совместимости здесь.

Использование

Чтобы использовать макет flexbox нужно просто установить свойство display для родительского HTML-элемента:

Если вы хотите отображать его как inline элемент, используйте свойство inline-flex:

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

Ниже описаны все свойства flexbox и как они влияют на макет визуально.

Flexbox-свойства контейнеров

Flex-direction

Это свойство определяет, как flex-элементы размещаются в flex-контейнере, устанавливает направление главной оси flex-контейнеров. Они могут быть установлены в двух основных направлениях, как строки по горизонтали или как колонки по вертикали.

Значения:

Flex-элементы размещаются в строке слева направо в ltr-контексте (направление текста слева-направо).

flexbox flex direction row

Flex-элементы размещаются в строке справа налево в ltr-контексте.

flexbox flex direction row reverse

Flex-элементы размещаются в колонке сверху вниз.

flexbox flex direction column

Flex-элементы размещаются в колонке снизу вверх.

flexbox flex direction column reverse

Значение по умолчанию: row

Примечание: row и row-reverse зависят от режима вывода текста, так в контексте rtl они будут работать в обратном порядке.

Flex-wrap

По первоначальной концепции flexbox — это контейнер, в котором все его элементы расположены в одной строке. Свойство flex-wrap позволяет располагать flex-элементы в виде одной или нескольких строк, и управлять направлением этих строк.

Значения:

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

flexbox flex wrap nowrap

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

flexbox flex-wrap wrap

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

flexbox flex-wrap wrap-reverse

Значение по-умолчанию: nowrap

Замечание: Эти свойства зависят от режима вывода текста, так в контексте rtl они будут работать в обратном порядке.

flex-flow

Это свойство просто сокращение свойств flex-direction и flex-wrap.

Значения:

Значение по-умолчанию: row nowrap

justify-content

Свойство justify-content выравнивает flex-элементы вдоль основной оси текущей линии flex-контейнера. Это свойство помогает распределять оставшееся свободное пространство.

Значения:

Flex-элементы выравниваются по левой стороне flex-контейнера при ltr-контексте.

flexbox justify-content flex-start

Flex-элементы выравниваются по правой стороне flex-контейнера при ltr-контексте.

flexbox justify-content flex-end

Flex-элементы выравниваются по центру flex-контейнера.

flexbox justify-content center

Flex-элементы располагаются с равными промежутками между ними, первый и последний элемент прижимаются к краям flex-контейнера.

flexbox justify-content space-between

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

flexbox justify-content space-around

Значение по-умолчанию: flex-start

align-items

Flex-элементы могут быть выравнены по поперечной оси текущей линии flex-контейнера, похоже на justify-content, но в перпендикулярном направлении. Это свойство устанавливает выравнивание для всех flex-элементов.

Values:

Flex-элементы заполняют всю высоту (или ширину) поперечной оси flex-контейнера.

flexbox align-items stretch

Flex-элементы располагаются в начале поперечной оси flex-контейнера.

flexbox-align-items-flex-start

Flex-элементы располагаются в конце поперечной оси flex-контейнера.

flexbox-align-items-flex-end

Flex-элементы располагаются в центре поперечной оси flex-контейнера.

flexbox-align-items-center

Flex-элементы выровнены таким образом, что их базовая линия находится на одном уровне.

flexbox-align-items-baseline

Значение по-умолчанию: stretch

Замечание: Как высчитывается базовая линия можно прочитать здесь.

align-content

Свойство align-content выравнивает линии внутри flex-контейнера, когда там есть дополнительное свободное место по поперечной оси, похоже на то как justify-content выравнивает отдельные элементы по основной оси.

Значения:

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

flexbox align-content stretch

Flex-элементы располагаются в начале поперечной оси flex-контейнера.

flexbox align-content flex-start

Flex-элементы располагаются в конце поперечной оси flex-контейнера.

flexbox align-content flex-end

Линии flex-элементов располагаются в центре поперечной оси flex-контейнера.

flexbox align-content center

Линии flex-элементов располагаются с равными промежутками между ними, первая и последняя линии прижимаются к краям flex-контейнера.

flexbox align-content space-between

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

flexbox align-content space-around

Значение по-умолчанию: stretch

Замечание: Это свойство работает только когда flex-контейнер содержит несколько линий flex-элементов. Если элементы расположены в одну линию, то это свойство не оказывает никакого эффекта на макет.

Замечание для flex-контейнеров:

Все свойства column-* не оказывают никакого эффекта на flex-контейнер.
Псевдо-элементы ::first-line и ::first-letter не применяются к flex-контейнерам.

Свойства flexbox-элементов

order

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

Значения:

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

flexbox order

Значение по-умолччанию: 0

flex-grow

Это свойство определяет фактор «жадности», это означает сколько flex-элемент будет забирать пространства по отношению к остальной части flex-элементов в контейнере, когда свободное пространство всё распределено.

Значения:

Если все flex-элементы имеют одинаковое значение flex-grow, тогда все элементы имеют одинаковый размер.

flexbox flex-grow 1

Второй flex-элемент занимает больше места относительно размера других flex-элементов.

flexbox flex-grow 2

Значение по-умолчанию: 0

Замечание: Отрицательные числа не работают.

flex-shrink

Свойство flex-shrink определяет фактор сжатия, это означает насколько flex-элемент будет сокращаться по отношению к остальной части flex-элементов.

Значения:

По-умолчанию все flex-элементы могут быть сжаты, но если вы установите это свойство равным 0 (не сжимать) элемент будет сохранять первоначальный размер.

flexbox flex-shrink

Значение по-умолчанию: 1

Замечание: отрицательные числа не работают.

flex-basis

Это свойство принимает те же значения, что и ширина и высота, и определяет начальный размер flex-элемента.

Значения:

flex-basis определено для 4-го flex-элемента и устанавливает начальный размер для него.

flexbox flex-basis

Значение по-умолчанию: auto

flex

Это свойство сокращение для flex-grow, flex-shrink и flex-basis свойств.

Значение по-умолчанию: 0 1 auto

Замечание: W3C рекомендуется использовать сокращенный синтаксис flex, а не отдельные свойства, так как сокращение правильно сбрасывает любые неуказанные свойства.

align-self

Свойство align-self позволяет определять выравнивание для отдельных flex-элементов.

Значения:

Для 3-го и 4-го flex-элемента было переопределено выравнивание при помощи свойства align-self.

flexbox align-self

Значение по-умолчанию: auto

Замечание для flex-элементов:

Свойства float, clear и vertical-align не оказывают влияние на flex-элементы.

www.webmasters.by

Базовый макет

Чтобы понять, каково это — создавать макеты на каждой системе, мы сделаем одну и ту же HTML-страницу дважды — один раз с помощью Flexbox, а затем на CSS Grid. Вы можете скачать оба проекта отсюда или проверить их в этой демонстрационной версии.

Уменьшенный макет веб-страницы

Уменьшенный макет веб-страницы

Дизайн довольно простой — он состоит из выровненного по центру контейнера, внутри которого у нас есть шапка, основной раздел, боковая панель и подвал. Вот главные «испытания», которые мы должны провести, сохраняя CSS и HTML по возможности чистыми:

  1. Разместить четыре основных раздела макета.
  2. Сделать страницу адаптивной (боковая панель опускается ниже основного содержимого на маленьких экранах).
  3. Выровнять содержимое шапки — навигация слева, кнопка справа.

Как вы можете видеть, ради сравнения мы оставили всё максимально простым. Начнём с первого испытания.

Испытание 1. Размещение разделов страницы

Решение на Flexbox

Добавляем display: flex к контейнеру и задаём направление дочерних элементов по вертикали. Это позиционирует все разделы друг под другом.

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

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

<header></header> <div class="main-and-sidebar-wrapper">  <section class="main"></section>  <aside class="sidebar"></aside> </div> <footer></footer>

Затем мы устанавливаем этому элементу display: flex и flex-direction с противоположным направлением.

.main-and-sidebar-wrapper {  display: flex;  flex-direction: row; }

Последний шаг — задать размеры основного раздела и боковой панели. Мы хотим, чтобы основное содержимое было в три раза шире боковой панели, что несложно сделать с помощью flex или процентов.

.main {  flex: 3;  margin-right: 60px; } .sidebar {  flex: 1; }

Как вы можете видеть, Flexbox сделал всё хорошо, но нам кроме этого понадобилось довольно много свойств CSS плюс дополнительный элемент HTML. Давайте посмотрим, как будет работать CSS Grid.

Решение на CSS Grid

Существует несколько вариантов использования CSS Grid, но мы воспользуемся синтаксисом grid-template-areas, как наиболее подходящего для наших целей.

Сперва мы определим четыре grid-area, по одному на каждый раздел страницы:

<header></header> <!-- Обратите внимание, что в этот раз нет дополнительных элементов --> <section class="main"></section> <aside class="sidebar"></aside> <footer></footer>
header {  grid-area: header; } .main {  grid-area: main; } .sidebar {  grid-area: sidebar; } footer {  grid-area: footer; }

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

.container {  display: grid;    /* Определяем размер и число колонок нашей сетки.   Единица fr работает подобно Flexbox:  колонки делят свободное пространство в строке согласно их значениям.  У нас будет две колонки — первая в три раза больше второй. */  grid-template-columns: 3fr 1fr;    /* Связываем сделанные ранее области с местами в сетке.  Первая строка — шапка.  Вторая строка делится между основным разделом и боковой панелью.  Последняя строка — подвал. */  grid-template-areas:   "header header"  "main sidebar"  "footer footer";   /* Интервал между ячейками сетки будет 60 пикселей */  grid-gap: 60px; }

Вот и всё! Наш макет теперь будет соответствовать указанной выше структуре и мы его настроили так, что нам не придётся иметь дело с margin или padding.

Испытание 2. Делаем страницу адаптивной

Решение на Flexbox

Выполнение этого шага строго связано с предыдущим. Для решения на Flexbox нам придётся изменить flex-direction и отрегулировать margin.

@media (max-width: 600px) {  .main-and-sidebar-wrapper {  flex-direction: column;  }    .main {  margin-right: 0;  margin-bottom: 60px;  } }

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

Решение на CSS Grid

Поскольку мы уже определили grid-areas, нам просто нужно переопределить их порядок в медиа-запросе. Мы можем использовать ту же настройку колонок.

@media (max-width: 600px) {  .container {  /* Выравнивание областей сетки для мобильного макета */  grid-template-areas:   "header header"  "main main"  "sidebar sidebar"  "footer footer";  } }

Или можем переопределить весь макет с нуля, если считаем, что это решение чище.

@media (max-width: 600px) {  .container {  /* Переделываем сетку в одноколоночный макет */  grid-template-columns: 1fr;  grid-template-areas:   "header"  "main"  "sidebar"  "footer";  } }

Испытание 3. Выравнивание компонентов шапки

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

Решение на Flexbox

<header>  <nav>  <li><a href="#"><h1>Logo</h1></a></li>  <li><a href="#">Link</a></li>  <li><a href="#">Link</a></li>  </nav>  <button>Button</button> </header>

Мы уже делали похожий макет на Flexbox в одной из наших старых статей — Простейший способ создания адаптивной шапки. Техника довольно простая:

header {  display: flex;  justify-content: space-between; }

Теперь список навигации и кнопка выровнены правильно. Осталось только разместить пункты внутри <nav> по горизонтали. Проще это сделать с помощью display: inline-block, но поскольку мы собираемся целиком использовать Flexbox, применим решение только для него:

header nav {  display: flex;  align-items: baseline; }

Только две строки! Совсем неплохо. Давайте посмотрим, как с этим справится CSS Grid.

Решение на CSS Grid

Чтобы разделить навигацию и кнопку, мы должны добавить display: grid к header и настроить двухколоночную сетку. Нам также понадобятся две дополнительные строки в CSS, чтобы позиционировать всё на соответствующих границах.

header{  display: grid;  grid-template-columns: 1fr 1fr; } header nav {  justify-self: start; } header button {  justify-self: end; }

Что касается ссылок в одну строку внутри навигации, у нас не получилось сделать это корректно с CSS Grid. Вот как выглядит наша лучшая попытка:

Flex css3

Ссылки строчные, но они не могут быть выровнены правильно, поскольку не существует варианта baseline, как у align-items. Мы также должны определить ещё одну вложенную сетку.

header nav {  display: grid;  grid-template-columns: auto 1fr 1fr;  align-items: end;  }

Понятно, что CSS Grid не справилась с этой частью макета, но это и не удивительно — основное внимание уделяется выравниванию контейнеров, а не содержимому внутри них. Эта система не для нанесения последних штрихов.

Выводы

Если вы прочитали статью целиком (а это отличная работа!), выводы не должны вас удивить. На деле нет лучшей системы — и Flexbox и CSS Grid хороши по своему и должны использоваться совместно, а не как альтернатива друг другу.

Для тех из вас, кто перепрыгнул непосредственно к выводам этой статьи (не волнуйтесь, мы тоже так делаем), вот краткий итог сравнения:

  • CSS Grid отлично подходит для создания большой картины. Эта система облегчает управление макетом страницы и даже может иметь дело с нестандартным и асимметричным дизайном.
  • Flexbox отлично подходит для выравнивания содержимого внутри элементов. Используйте эту систему для размещения мелких деталей дизайна.
  • Используйте CSS Grid для двумерных макетов (строк И колонок).
  • Flexbox лучше работает только в одном измерении (со строками ИЛИ с колонками).
  • Нет причин применять только CSS Grid или только Flexbox. Изучайте их и используйте совместно.

htmlbook.ru


You May Also Like

About the Author: admind

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.