Изучаем Flexbox
Технологии не стоят на месте и мир высоких технологий развивается очень быстро. Тяжело успевать за техническим прогрессом и быть в курсе всех изменений.
Сегодня мы будем изучать долгожданное нововведение всех вебмастеров - Flexbox-лейаут или гибкие блоки.
Этот модуль призван сделать более эффективным верстку при выравнивании и распределении свободного пространства между элементами в контейнере, даже если их размер неизвестен или меняется динамически.
Начнем разбираться по порядку.
Для просмотра этой статьи и использования этих технологий, используйте современные браузеры
Поддержка браузерами: Google Chrome 21+, Opera 12.1+, Mozilla FireFox 22+, IE 10+, Safari 3+, Android 2.1+, iOS 3.2+.
Создадим простую структуру:
<div class="parent"> <div class="child">100500</div> <div class="child">2</div> <div class="child">3</div> </div>
1 контейнер и 3 дочерних элемента. С этими элементами мы будем выполнять все манипуляции. Структура изменяться не будет, поэтому в дальнейшем буду приводить изменения только стилей css.
Итак, сейчас у нас все элемента блочные и без стилей все дочерние элементы будут располагаться друг под другом.
display:flex
Применяется к родительскому элементу. Определяет родительский элемент как блочный.
Поэтому добавим базовые стили, которые определят, что используемые нами элементы относятся к теме статьи:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
В результате мы получим вот такую картинку:
При этом контейнер будет занимать всю доступную ширину (так как свойство display:flex определяет элемент как блочный) - для примера, ограничил ширину - 760px, а дочерние элементы занимают ширину по содержимому.
Если мы зададим родителю свойство display:inline-flex, то это определит родителя как блок-инлайновый элемент (при этом результат не изменится), родитель будет занимать ширину по содержимому (а вести себя как display:inline-block).
По умолчанию, дочерние элементы располагаются у левого края. Но это можно изменить:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; flex-direction:row-reverse; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
Теперь элементы располагаются справа-налево. И первый дочерний элемент стоит справа. (Если направление текста изменено для всех страницы на обратное - справа налево rtl, вместо ltr - то все свойства выравнивания - это и далее - работают наоборот).
flex-direction
Применяется к родительскому элементу. Устанавливает направление дочерних flex элементов.
Все доступные варианты выравнивания для свойства flex-direction:
- row (по умолчанию): слева направо для ltr, справа налево для rtl
- row-reverse: справа налево для ltr, слева направо для rtl
- column: аналогично row, сверху вниз
- column-reverse: аналогично row-reverse, снизу вверх
display:inline-flex
Применяется к родительскому элементу. Определяет родительский элемент как инлайн-блочный (аналог inline-block).
На картинке наглядно видна разница между display:flex и display:inline-flex на основе свойства flex-direction. Больше к этим свойствам обращаться не будем.
flex-wrap
Применяется к родительскому элементу. Определяет контейнер как однострочный или многострочный, а также направление расположения строк.
Все доступные варианты выравнивания для свойства flex-wrap:
- nowrap (по умолчанию): однострочный / слева направо для ltr, справа налево для rtl
- wrap: многострочный / слева направо для ltr, справа налево для rtl
- wrap-reverse: многострочный / справа налево для ltr, слева направо для rtl
Зададим стили для примера:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; flex-wrap:wrap; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
Это свойство указывает, что если контейнеры не будут умещаться на экране, то они перенесутся на другую строку.
Применим свойство flex-wrap:wrap-reverse;:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; flex-wrap:wrap-reverse; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
flex-flow
Применяется к родительскому элементу. Служит сокращением для flex-direction и flex-wrap.
Значение по умолчанию: flex-flow:row nowrap;
.parent { display:flex; border:2px solid #FF8C00; padding:20px; flex-flow:row nowrap; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
justify-content
Применяется к родительскому элементу. Определяет выравнивание дочерних элементов внутри родителя. Помогает распределить свободное пространство в случае, когда элементы строки не тянутся, либо достигли своего максимального размера.
Все возможные значения для свойства:
- flex-start (по умолчанию): элементы сдвигаются к началу строки
- flex-end: элементы сдвигаются к концу строки
- center: элементы выравниваются по центру строки
- space-between: элементы распределяются равномерно (первый элемент в начале строки, последний — в конце)
- space-around: элементы распределяются равномерно с равным расстоянием между собой и границами строки
Зададим свойства для выравнивания элементов по центру:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; justify-content:center; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; }
align-items
Применяется к родительскому элементу. Выравнивает дочерние элементы по вертикали. Свойство работает аналогично justify-content, но перпендикулярно.
Все возможные значения для свойства:
- flex-start: граница cross-start для элементов располагается на позиции cross-start
- flex-end: граница cross-end для элементов располагается на позиции cross-end
- center: элементы выравниваются по центру поперечной оси
- baseline: элементы выравниваются по своей базовой линии
- stretch (по умолчанию): элементы растягиваютcя, заполняя контейнер (с учётом min-width/max-width)
Внимание! Для примера немного добавились стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; align-items:center; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; } .child:last-child { height:200px; }
align-content
Применяется к родительскому элементу. Свойство не работает с однострочным flexbox. Определяет выравнивание строк (аналогично свойству justify-content).
Все возможные значения свойства:
- flex-start: строки выравниваются относительно начала контейнера
- flex-end: строки выравниваются относительно конца контейнера
- center: строки выравниваются по центру контейнера
- space-between: строки распределяются равномерно (первая строка в начале строки, последняя — в конце)
- space-around: строки распределяются равномерно с равным расстоянием между собой
- stretch (по умолчанию): строки растягиваются, заполняя свободное пространство
Обновим стили для примера:
.parent { height:500px; /* организуем лишнее пространство */ display:flex; border:2px solid #FF8C00; padding:20px; width:760px; flex-wrap:wrap; /* делаем flexbox многострочным */ align-content:space-around; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; width:100%; /* делаем перенос строк */ }
Это все свойства, которые применяются к родителю. Теперь разберем свойства, которые применяются к дочерним элементам.
order
Применяется к дочерним элементам. Определяет порядок расположения элементов (можно изменить исходный порядок расположения в контейнере).
Обновляем стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; } .child:first-child { order:3; }
Вуаля! Первый элемент стал последним.
flex-grow
Применяется к дочерним элементам. Принимает безразмерное значение, которое означает пропорцию, которую дочерний элемент занимает внутри родителя.
Если у всех дочерних элементов задано: flex-grow:1;, то они займут одинаковый размер (или 33,3333%). Если один из элементов будет иметь значение 2, то он будет занимать размер в 2 раза больше остальных.
Обновим стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; flex-grow:1; } .child:first-child { flex-grow:2; }
Первый элемент занимает в 2 раза больше места, чем другие.
flex-shrink
Применяется к дочерним элементам. Определяет возможность элементов сжиматься при необходимости.
По умолчанию значение 1. Отрицательные числа не принимаются. 0 - элемент не сжимается.
Обновим стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; width:200px; flex-shrink:5; } .child:first-child { flex-shrink:1; }
Несмотря на то, что дочерние элементы имеют одинаковый размер, в примере 2 последних блока будут сжиматься в 5 раз быстрее первого.
flex-basis
Применяется к дочерним элементам. Определяет размер по умолчанию для элемента перед распределением пространства в контейнере (что-то похожее на width).
По умолчанию значение default auto. Принимает значение ширины (px, em и другие).
Обновим стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:1060px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; flex-basis:200px; }
В представленном примере все блоки имеют одинаковую начальную ширину - 200px.
flex
Применяется к дочерним элементам. Сокращение для flex-grow, flex-shrink и flex-basis. Второй и третий параметры не обязательны.
Значения по умолчанию: 0 1 auto.
Обновим стили:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; flex:none; }
В приведенном примере дочерние элементы имеют ширину по содержимому.
align-self
Применяется к дочерним элементам. Позволяет переопределить выравнивание, заданное в align-items для отдельных элементов.
Все возможные значения для свойства:
- flex-start: граница cross-start для элементов располагается на позиции cross-start
- flex-end: граница cross-end для элементов располагается на позиции cross-end
- center: элементы выравниваются по центру поперечной оси
- baseline: элементы выравниваются по своей базовой линии
- stretch (по умолчанию): элементы растягиваютcя, заполняя контейнер (с учётом min-width/max-width)
Обновим стили. Зададим другое выравнивание первому элементу:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; align-items:center; height:300px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; } .child:first-child { align-self:flex-start; }
В приведенном примере - первый блок находится в начале родительского, а второй и третий выравнены по центру.
Ну и в заключение приведу пример, в которой в строку будут стоят 3 блока. Первый блок будет 200px, сжиматься и растягиваться не будет. Остальные 2 блока будут занимать все оставшееся пространство, причем как растягиваться так и сжиматься. Без flexbox это сделать достаточно проблематично. Посмотрим на код css при использовании flexbox:
.parent { display:flex; border:2px solid #FF8C00; padding:20px; width:760px; } .child { background-color:#ededed; border:2px solid #768D44; padding:30px; margin:10px; flex:1 200px; } .child:first-child { flex:0 0 200px; }
Вот и все! Обзорная экскурсия по flexbox закончена. Экспериментируйте и все получится!