Flexbox изображения. Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице. Примеры Flex верстки
Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?
Любой верстальщик знает несколько путей выровнять что-либо по вертикали или сделать 3-х колоночный макет с резиновой средней колонкой. Но давайте признаем, что все эти способы довольно странные, похожи на хак, подходят не во всех случаях, сложны для восприятия и не работают при несоблюдении определенных магических условий, которые сложились исторически.
Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.
Многострочная организация блоков внутри 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 (значение по умолчанию) : Ряды блоков растянуты, дабы занять все имеющееся пространство.
СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.
Демо свойств многострочности в flex
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
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
В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2
Демо для align-self и order
margin: auto по вертикали . Мечты сбываются!
Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!
My-flex-container { display: flex; height: 300px; /* Или что угодно */ } .my-flex-block { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ }
Вещи, которые следует помнить
- Не следует использовать flexbox там, где в этом нет необходимости.
- Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
- Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
- Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
- Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
- flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580
В заключение
Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости;)
Flexbox призван спасти нас от неприятных моментов чистого CSS (например, от вертикального выравнивания), и он отлично справляется со своей задачей. Но разобраться в принципах его работы порой бывает сложно, особенно, если вы новичок.
Основная задача Flexbox - сделать слои гибкими, а работу с ними - интуитивно понятными. Для достижения этой цели он позволяет контейнерам самим решать, как обращаться со своими дочерними элементами, в том числе изменять их размер и расстояние между ними.
Звучит неплохо, но давайте посмотрим, так ли оно гладко на практике. В этой статье мы изучим 5 самых популярных свойств Flexbox, разберемся, что они делают, и как они на самом деле работают.
Display: Flex
Вот пример страницы:
У нас есть 4 разноцветных div’а разных размеров, которые находятся внутри серого div’а. У каждого div’а есть свойство display: block . Поэтому каждый квадрат занимает всю ширину строки.
Чтобы начать работать с Flexbox, нам нужно сделать наш контейнер flex-контейнером. Делается это так:
#container { display: flex; }
Вроде бы ничего особо и не изменилось - div’ы всего лишь встали в ряд. Но вы сделали что-то действительно мощное. Вы дали вашим квадратам классное свойство, называемое «flex-контекст».
Flex Direction
У flex-контейнера есть две оси: главная ось и перпендикулярная ей.
По умолчанию все предметы располагаются вдоль главной оси: слева направо. Поэтому наши квадраты выровнялись в линию, когда мы применили display: flex . Однако flex-direction позволяет вращать главную ось.
#container { display: flex; flex-direction: column; }
Важно заметить, что flex-direction: column не выравнивает квадраты по оси, перпендикулярной главной. Главная ось сама меняет свое расположение и теперь направлена сверху вниз.
Есть еще парочка свойств для flex-direction: row-reverse и column-reverse .
Justify Content
Justify-content отвечает за выравнивание элементов по главной оси.
Вернемся к flex-direction: row .
#container { display: flex; flex-direction: row; justify-content: flex-start; }
Justify-content может принимать 5 значений:
- flex-start ;
- flex-end ;
- center ;
- space-between ;
- space-around .
Space-between задает одинаковое расстояние между квадратами, но не между контейнером и квадратами. Space-around также задает одинаковое расстояние между квадратами, но теперь расстояние между контейнером и квадратами равно половине расстояния между квадратами.
Align Items
Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси.
Вернемся обратно к flex-direction: row и пройдемся по командам align-items:
- flex-start ;
- flex-end ;
- center ;
- stretch ;
- baseline .
Стоит заметить, что для align-items: stretch высота квадратов должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится вот так:
Чтобы получше разобраться в том, как работают оси, давайте объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction:
Align Self
Align-self позволяет выравнивать элементы по отдельности.
#container { align-items: flex-start; } .square#one { align-self: center; } // Only this square will be centered.
Давайте для двух квадратов применим align-self , а для остальных применим align-items: center и flex-direction: row .
Flex-Basis
Flex-basis отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами Flexbox:
Flex-basis влияет на размер элементов вдоль главной оси.
Давайте посмотрим, что случится, если мы изменим направление главной оси:
Заметьте, что нам пришлось изменить и высоту элементов. Flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.
Flex Grow
Это свойство немного сложнее.
Для начала давайте зададим нашим квадратикам одинаковую ширину в 120px:
По умолчанию значение flex-grow равно 0. Это значит, что квадратам запрещено расти (занимать оставшееся место в контейнере).
Попробуем задать flex-grow равным 1 для каждого квадрата:
Квадраты заняли оставшееся место в контейнере. Значение flex-grow аннулирует значение ширины.
Но здесь возникает один вопрос: что значит flex-grow: 1 ?
Попробуем задать flex-grow равным 999:
И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные.
Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим квадратам:
Вначале flex-grow каждого квадрата равен 1, в сумме получится 6. Значит, наш контейнер поделен на 6 частей. Каждый квадрат будет занимать 1/6 часть доступного пространства в контейнере.
Когда flex-grow третьего квадрата становится равным 2, контейнер делится на 7 частей (1 + 1 + 2 + 1 + 1 + 1).
Теперь третий квадрат занимает 2/7 пространства, остальные - по 1/7.
Стоит помнить, что flex-grow работает только для главной оси (пока мы не поменяем ее направление).
Flex Shrink
Flex-shrink - прямая противоположность flex-grow . Оно определяет, насколько квадрату можно уменьшиться в размере.
Flex-shrink используется, когда элементы не вмещаются в контейнер.
Вы определяете, какие элементы должны уменьшиться в размерах, а какие - нет. По умолчанию значение flex-shrink для каждого квадрата равно 1. Это значит, что квадраты будут сжиматься, когда контейнер будет уменьшаться.
Зададим flex-grow и flex-shrink равными 1:
Теперь давайте поменяем значение flex-shrink для третьего квадрата на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:
Стоит помнить что flex-shrink основывается на пропорциях. То есть, если у квадрата flex-shrink равен 6, а у остальных он равен 2, то, это значит, что наш квадрат будет сжиматься в три раза быстрее, чем остальные.
Flex
Flex заменяет flex-grow , flex-shrink и flex-basis .
Значения по умолчанию: 0 (grow) 1 (shrink) и auto (basis) .
Создадим два квадрата:
Square#one { flex: 2 1 300px; } .square#two { flex: 1 2 300px; }
У обоих квадратов одинаковый flex-basis . Это значит, что они оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding).
Но когда контейнер начнет увеличиваться в размерах, первый квадрат (с большим flex-grow) будет увеличиваться в два раза быстрее, а второй квадрат (с наибольшим flex-shrink) будет сжиматься в два раза быстрее.
Как вещи растут и сжимаются
Когда увеличивается первый квадрат, он не становится в два раза больше второго квадрата, и когда уменьшается второй квадрат, он не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.
Немного математики
Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding, и у нас останется 600px, как раз для двух квадратов.
Когда ширина контейнера становится равной 430px (потеря в 210px), первый квадрат (flex-shrink: 1) теряет 70px. Второй квадрат (flex-shrink: 2) теряет 140px.
Когда контейнер сжимается до 340px, мы теряем 300px. Первый квадрат теряет 100px, второй - 200px.
Тоже самое происходит и с flex-grow .
Flexbox представляет новый способ отображения блоков в макете с помощью css3 и предназначен для облегчения расположения элементов относительно друг друга. В этой статье мы рассмотрим самый новый синтаксис модели flexbox. В последнее время версии браузеров меняются достаточно быстро, так что вы будете в теме, когда модель flexbox будет поддерживаться широко в реальных проектах.
Для чего нужен Flexbox?
Разработчики на протяжении долгого времени использовали таблицы, float-элементы, inline-block и другие CSS свойства, чтобы придать блокам нужное расположение. Однако ни один из вышеперечисленных инструментов не был предназначен для создания сложных страниц и приложений, которые в настоящее время используются почти в каждом проекте. Простые вещи, как вертикальное центрирование, осуществлялись достаточно сложно. Создание же макета на основе жидких сеток вообще считается верхом профессионализма, вот почему широкое распространение получили CSS-фреймворки на основе сеток. Итак, если множество проектов часто используют жидкие сетки, блоки одинаковой высоты, вертикальное центрирование блоков и т.д., то возникает вопрос: "Почему до сих пор нет свойства, которе позволило бы осуществлять эти вещи быстро и просто?"
Целью Flexbox является решение всех этих проблем!
Статус спецификации и поддержка браузерами
Модель flexbox разрабатывается уже четвёртый год. Браузеры используют разные экспериментальные версии спецификации. В сентябре 2012 года 3-я проверка ситаксиса Flexbox группой разработчиков из W3C достигла статуса W3C Candidate. Это означает, что W3C утверждает текущий синтаксис и даёт добро на использование вендорных префиксов браузерами.
История изменений спецификации по Flexbox:
- Июль 2009 Working Draft (display: box;)
- Март 2011 Working Draft (display: flexbox;)
- Ноябрь 2011 Working Draft (display: flexbox;)
- Март 2012 Working Draft (display: flexbox;)
- Июнь 2012 Working Draft (display: flex;)
- Сентябрь 2012 Candidate Recommendation (display: flex;)
Браузеры получили быструю поддержку Flexbox. Chrome 22+, Opera 12.1+, IE10, Firefox >=16 уже поддерживают Flexbox. Я рекомендую использовать один из этих браузеров для просмотра примеров.
Концепция и терминология
Хотя flexbox и создан для облегчения расположения блоков в макете, что в прошлом часто вызывало трудности, а в некоторых ситуациях большие проблемы, потребуется еще определенное время для решения этих задач с помощью Flexbox в реальных проектах. Нюансы терминологии модели могут затруднить её использование. Давайте рассмотрим как работает Flexbox-модель.
Модель Flexbox включает в себя flex-контейнер (flex container) и flex-пункты (flex items). Flex container должен иметь свойство display со значением flex или inline-flex . Со значением flex контейнер представляет из себя блочный элемент, а с inline-flex - строчный (инлайновый).
Пример объявления flex container:
Flex-container { display: -webkit-flex; display: flex; }
Flex container является родителем по отношению к flex items. Flex-пунктов может быть сколько угодно. Всё что находится вне flex-контейнера и внутри flex-пунктов отображается как обычно. Таким образо, Flexbox определяет, как flex-пункты будут расположены внутри flex-контейнера.
Flex items расположены внутри flex container вдоль flex line (flex линии). По умолчанию во flex-контейнере присутствует только одна flex-линия. Вот пример с двумя пунктами, расположенными по умолчанию вдоль flex-линии слева направо:
Flex-container{ display: -webkit-flex; display: flex; width: 700px; background-color: green; margin: 20px auto; } .flex-item{ background-color: red; width: 100px; height: 100px; margin: 5px; color: #fff; }
Writing modes (режимы отображения содержимого)
Важной частью настройки flexbox является изменение направления flex-линии. По умолчанию направление flex-линии совпадает с направлением текста: слева направо, сверху вниз.
В спецификации появился новый модуль writing modes. Он позволяет менять направление текста справа налево, или даже вертикально.
Данный модуль находтся в стадии разработки, но Chrome поддерживает CSS свойство direction. Если в предыдущем примере установить свойство direction: rtl (справа налево), то изменится не только направление отображения содержимого справа налево, но и direction flex-линии, что приведет к изменению макета.
Body { direction: rtl; } .flex-container { display: -webkit-flex; display: flex; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }
Из данного примера можно сделать вывод, почему терминология Flexbox на данный момент настолько абстрактна. Нельзя просто указать “вправо”, “влево”, “вниз”, “вверх” когда мы не имеем понятия на каком языке написана данная страница (возможно на арабском - стиль письма справа налево!).
Главная и поперечная оси
Чтобы не зависеть от режима отображения содержимого direction, Flexbox использует концепцию главной оси и поперечной оси (Main Axis и Cross Axis). Flex-линия следуют по главной оси. Поперечная ось перпендикулярна главной оси. Имена начальных и конечных точек, а также направления каждой оси:
- Main Start
- Main End
- Main Direction (иногда называется Flow Direction)
- Cross Start
- Cross End
- Cross Direction
Перед тем как продолжить, важно понять терминологию главной и поперечной оси. Всё в модели flexbox расположено относительно этих двух осей. Во всех наших примерах режим наложения writing mode был слева направо, сверху вниз. Но вы должны иметь ввиду, что это может быть не всегда так.
Свойства Flex контейнера:
Flex-direction
Свойство flex-direction позволяет менять оси flex-контейнера. По умолчанию свойство flex-direction имеет значение row. В этом случае flex-пункты располагаются в соответствии с режимом writing-mode. Еще раз напомним, что это означает направление слева направо, сверху вниз (по умолчанию).
Другие возможные значения:
- row-reverse : Main Start И Main End меняются местами. Если даже writing-mode указан ltr (слева налево), то flex-пункты все равно будут расположены справа налево.
- column : Главная ось и поперечная ось меняются местами. Если режим отображения содержимого горизонтальный, то flex-пункты все равно будут располагаться вертикально.
- column-reverse : аналогично column только обратный.
Изменим в предыдущем примере свойство flex-direction на column :
Flex-container { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }
Теперь flex-пункты располагаются вертикально.
justify-content
justify-content регулирует расположение flex-пунктов по главной оси. Возможные значения:
- flex-start (по умолчанию)
- flex-end
- center
- space-between
- space-around
Рассмотрим пример с justify-content: center чтобы flex-пункты центрировались по главной оси:
Flex-container { display: -webkit-flex; display: flex; -webkit-justify-content: center; justify-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }
flex-start , flex-end , и center работают, соединившись вместе по главной оси. А вот space-between и space-around распределяют свободное пространство между flex-пунктами определённым способом. Приведу диаграмму из спецификации, которая показывает распределение justify-content :
align-items
align-items является дополнительным свойством к justify-content . align-items регулирует отображение flex-пунктов относительно перпендикулярной оси. Возможные значения:
- flex-start (по умолчанию)
- flex-end
- center
- baseline
- stretch
Рассмотрим примение свойства align-items:center , которе позволяет flex-пункты вертикально центрировать относительно перпендикулярной оси:
Flex-container { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }
Итак, flex-start , flex-end , и center всегда располагаются соединившись вместе. Значение stretch довольно простое: оно заставляет flex-пункты растягиваться от Cross Start до Cross End, то есть по вертикали относительно flex-контейнера. baseline заставляет flex-пункты располагаться по базовой линии. Базовая линия вычисляется исходя из инлайнового содержимого flex-пунктов. Вот лучшее объяснение работы данных значений:
Flex-wrap
Во всех рассмотренных примерах flex-контейнер имел одну flex-линию. Использование свойства flex-wrap позволит создать flex-контейнер с разным количеством flex-линий. Возможные значения:
- nowrap (по умолчанию)
- wrap-reverse
Если во flex-wrap установлено значение wrap , то во flex-пункты включаются дополнительные flex-линии, но только в том случае, если flex-пунктам не хватает пространства для расположения на одной flex-линии. Дополнительные flex-линии добавляются в направлении перпендикулярной оси.
Пример использования flex-wrap :
Flex-container { display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 300px; height: 100px; margin: 5px; }
Значение wrap-reverse аналогично значению wrap за исключением того, что новые flex-линии добавляются в обратном направлении по перпендикулярной оси.
align-content
align-content изменяет поведение свойства flex-wrap . Это значение аналогично align-items только вместо выравнивания flex-пунктов, оно выравнивает flex-линии. Как и можно было ожидать, значения аналогичные:
- stretch (по умолчанию)
- flex-start
- flex-end
- center
- space-between
- space-around
Принцип работы этих значений аналогичный justify-content и align-items .
Пример align-content: center
flex-flow
Данное свойство компонует в себя свойства flex-direction и flex-wrap .
flex-flow:
Flex-container { -webkit-flex-flow: column nowrap; flex-flow: column nowrap; }
Свойства flex-пунктов (flex items)
Flex-пункт является дочерним блоком по отношению к flex-контейнеру. Содержимое flex-контейнера относится к flex-пункту этого контейнера. Содержимое flex-пункта отображается как обычно. Например, пока действует свойство float, flex-пункты никак на это не реагируют. Плавающие также могут находиться внутри самого flex-пункта.
Как говорят, flex-пункты имеют Main Size и Cross Size. Main Size – это размер flex-пункта в направлении главной оси, а Cross Size - в направлении поперечной оси. Фактически, шириной или высотой flex-пункта могут быть Main Size и Cross Size в зависимости от оси flex-контейнера.
Рассмотрим свойства, которые регулируют поведение flex-пунктов.
Order
Order является простейшим свойством. Порядок расположения flex-пунктов обеспечивается расположением flex-пунктов в HTML. В этом примере мы изменим значение свойства order одного flex-пункта на -1 и посмотрим, как при этом поменяется порядок расположения других flex-пунктов.
Flex-container { display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 300px; height: 100px; margin: 5px; } .first { -webkit-order: -1; order: -1; }
Это свойство может оказаться полезным для доступности, когда порядок следования flex-пунктов в HTML должен быть одним, а вывод flex-пунктов на дисплее другим.
Margin
Наверняка вам знаком эффект margin: auto . Flexbox выполняет нечто подобное, но с еще более широкими возможностями. “auto” поглащает лишнее пространство. Это свойство может использоваться для разнообразного позиционирования flex-пунктов.
Например, объявим margin-right: auto; для первого flex-пункта, при этом он предоставит всё возможное свободное пространство справа от себя:
Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; } .flex-item:first-child{ margin-right: auto; }
Теперь посмотрим на примере как работает margin: auto
Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; } .flex-item:first-child{ margin: auto; }
align-self
Свойство align-self пункта служит для перекрытия свойства align-items flex-контейнера. Возможные значения аналогичные align-items :
- stretch (по умолчанию)
- flex-start
- flex-end
- center
- baseline
В этом примере мы назначим пунктам различные значения свойства align-self:
Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-align-self: flex-start; align-self: flex-start; } .item2 { -webkit-align-self: flex-end; align-self: flex-end; } .item3 { -webkit-align-self: center; align-self: center; } .item4 { -webkit-align-self: baseline; align-self: baseline; } .item5 { -webkit-align-self: baseline; align-self: baseline; padding: 2em 0; } .item6 { -webkit-align-self: stretch; align-self: stretch; }
flex
Наконец-то мы дошли до свойства flex во Flexbox. Flex определяет,как flex-пункты будут использовать свободное пространство по главной оси. Рассмотрим каждое из возможных значений.
Flex:
Такой синтаксис указывает какую часть должен занимать flex-пункт от общей ширины flex-контейнера. В следующем примере первый flex-пункт будет занимать 2/4 свободного места, а остальные два flex-пункта по 1/4:
Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-flex: 2; flex: 2; } .item2 { -webkit-flex: 1; flex: 1; } .item3 { -webkit-flex: 1; flex: 1; }
Часто приходится равномерно распределять элементы по ширине. Для этого достаточно задать значение данного свойства 1 и все flex-пункты распределятся по ширине контейнера.
Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-flex: 1; flex: 1; } .item2 { -webkit-flex: 1; flex: 1; } .item3 { -webkit-flex: 1; flex: 1; }
flex: initial
Flex-пункты с данным значением будет иметь строго фиксированную ширину, но только при наличии свободного пространства (при необходимости уменьшиться в размере - становится резиновым).
flex: auto
Flex-пункты становятся полностью резиновыми вдоль главной оси. Не корректно работает в Chrome 23.0.1271.95, поэтому лучше использовать flex: 1 .
flex: none
flex-пункты становятся фиксированной ширины при всех ситуациях
advanced flex
Свойство flex можно использовать в режиме сокращения для придания спецефичности выбора flex-grow , flex-shrink , и flex-basis в одном объявлении: flex:
В большинтсве случаев не требуется такой синтаксис. Более того, для применения данного сокращения необходимо глубокое понимание модели Flexbox. Вы можете сделать каждое из свойств flex-grow , flex-shrink , и flex-basis специфичным. Я настоятельно рекомендую не использовать данное сокращение: по умолчанию придаются более разумные значения.
visibility
Когда реализуется свойство visibility: collapse; оно будет отличаться от значений visibility: hidden; и display: none; для flex-пунктов. Со значением collapse элемент задействует Cross Size flex-контейнера, но затрагивать пространство главной оси не будет. Это может быть полезным для динамического добавления или удаления flex-пунктов без оказания влияния на Cross Size flex-контейнера.
В настоящее время visibility: collapse; не коррексно работает в браузерах. На данный момент visibility: collapse; выполняет тоже самое что и visibility: hidden; Я уверен, что в ближайшее время ситуация изменится.
Посмотреть, как должно работать значение collapse в спецификации (http://www.w3.org/TR/css3-flexbox/#visibility-collapse)
Заключение
Как вы понимаете, Flexbox представляет мощное средство конструирования макетов. Он требует совершенно нового подхода для отображения блоков. Надеюсь, эта статья стала полезной для вас и вы сможете уже сейчас начать экспериментировать с макетами с помощью Flexbox. Будущее этой модели действительно потрясающее.
Why Flexbox?
For a long time, the only reliable cross browser-compatible tools available for creating CSS layouts were things like floats and positioning . These are fine and they work, but in some ways they are also rather limiting and frustrating.
The following simple layout requirements are either difficult or impossible to achieve with such tools, in any kind of convenient, flexible way:
- Vertically centering a block of content inside its parent.
- Making all the children of a container take up an equal amount of the available width/height, regardless of how much width/height is available.
- Making all columns in a multiple column layout adopt the same height even if they contain a different amount of content.
As you"ll see in subsequent sections, flexbox makes a lot of layout tasks much easier. Let"s dig in!
Introducing a simple example
In this article we are going to get you to work through a series of exercises to help you understand how flexbox works. To get started, you should make a local copy of the first starter file - flexbox0.html from our github repo - load it in a modern browser (like Firefox or Chrome), and have a look at the code in your code editor. You can also.
Flex-direction: column;
You"ll see that this puts the items back in a column layout, much like they were before we added any CSS. Before you move on, delete this declaration from your example.
Note : You can also lay out flex items in a reverse direction using the row-reverse and column-reverse values. Experiment with these values too!
Wrapping
One issue that arises when you have a fixed amount of width or height in your layout is that eventually your flexbox children will overflow their container, breaking the layout. Have a look at our flexbox-wrap0.html example, and try viewing it live (take a local copy of this file now if you want to follow along with this example):
Here we see that the children are indeed breaking out of their container. One way in which you can fix this is to add the following declaration to your element represents a standalone section - which doesn" t have a more specific semantic element to represent it contained within an html document.>
Flex-wrap: wrap; flex: 200px;
Try this now; you"ll see that the layout looks much better with this included:
We now have multiple rows - as many flexbox children are fitted onto each row as makes sense, and any overflow is moved down to the next line. The flex: 200px declaration set on the articles means that each will be at least 200px wide; we"ll discuss this property in more detail later on. You might also notice that the last few children on the last row are each made wider so that the entire row is still filled.
But there"s more we can do here. First of all, try changing your flex-direction property value to row-reverse - now you"ll see that you still have your multiple row layout, but it starts from the opposite corner of the browser window and flows in reverse.
flex-flow shorthand
At this point it is worth noting that a shorthand exists for flex-direction and flex-wrap - flex-flow . So for example, you can replace
Flex-direction: row; flex-wrap: wrap;
Flex-flow: row wrap;
Flexible sizing of flex items
Let"s now return to our first example, and look at how we can control what proportion of space flex items take up. Fire up your local copy of flexbox0.html , or take a copy of flexbox1.html as a new starting point (see it live).
First, add the following rule to the bottom of your CSS:
Article { flex: 1; }
This is a unitless proportion value that dictates how much of the available space along the main axis each flex item will take up. In this case, we are giving each element a value of 1, which means they will all take up an equal amount of the spare space left after things like padding and margin have been set. It is a proportion, meaning that giving each flex item a value of 400000 would have exactly the same effect.
Now add the following rule below the previous one:
Article:nth-of-type(3) { flex: 2; }
Section - article article article - div - button div button div button button button
Let"s look at the code we"ve used for the layout.
Summary
That concludes our tour of the basics of flexbox. We hope you had fun, and will have a good play around with it as you travel forward with your learning. Next we"ll have a look at another important aspect of CSS layouts - CSS Grids.
О том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.
Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian .
Причина, по которой автор использует Flexbox – это большое количество возможностей, которые он предоставляет:
- легкость в создании адаптивных столбцов;
- создание столбцов одинаковой высоты;
- возможность прижатия содержимого к низу контейнера.
Ну, поехали!
1. Начинаем с создания двух столбцов
Создание столбцов при помощи CSS всегда влекло за собой определенные трудности. На протяжении длительного времени для выполнения данной задачи широко использовались (и используются) float’ы и / или таблицы, но каждый из этих методов имел (и имеет) свои недостатки.В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:
Написание более «чистого» кода: от нас лишь требуется создать контейнер с правилом display: flex;
- гибкость: мы можем изменять размер, растягивать и выравнивать столбцы путем изменения пары строк CSS;
- семантическая разметка;
- кроме того, с использованием Flexbox отпадает необходимость отменять обтекание во избежание непредсказуемого поведения лейаута.
Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один - 1/3 его часть.
Здесь присутствуют два элемента:
Контейнер columns;
- два дочерних элемента column
, один из которых имеет дополнительный класс main-column
, который мы используем позже для того, чтобы сделать столбец шире.
Columns {
display: flex;
}
.column {
flex: 1;
}
.main-column {
flex: 2;
}
Поскольку main-column
имеет значение flex равное 2
, то этот столбец займет в два раза больше места, чем второй.
Добавим немного визуального оформления и, в итоге, получим:
Кликните для просмотра в действии
2. Делаем каждый столбец flexbox-контейнером
Каждый из двух столбцов будет содержать несколько вертикально расположенных статей, поэтому из этих двух элементов мы, в свою очередь, также должны сделать flexbox-контейнеры.Итак, нам необходимо, чтобы статьи:
Располагались вертикально внутри столбца-контейнера;
- занимали все доступное место.
Правило flex-direction: column , указанное для контейнера, вместе с правилом flex: 1 , указанным для дочернего элемента, позволяет статье заполнить все свободное место по вертикали, при этом высота первых двух столбцов останется неизменной.
Кликните для просмотра в действии
3. Делаем контейнер из статьи
Теперь, чтобы еще больше расширить наши возможности, давайте представим каждую статью в виде flexbox-контейнера. Каждый такой контейнер будет содержать:Заголовок;
- параграф;
- информационную панель с именем автора и количеством комментариев;
- какую-нибудь адаптивную картинку.
Здесь мы используем Flexbox для того, чтобы «прижать» информационную панель к низу элемента. Вот, посмотрите, какой результат мы ожидаем получить.
А вот и сам код:
.article {
display: flex;
flex-direction: column;
flex-basis: auto; /* Устанавливает начальный размер элемента в зависимости от его содержимого */
}
.article-body {
display: flex;
flex: 1;
flex-direction: column;
}
.article-content {
flex: 1; /* Содержимое заполняет все оставшееся место, тем самым прижимая информационную панель к нижней части */
}
Элементы внутри статьи расположены вертикально благодаря использованию правила flex-direction: column
.
Также мы применили свойство flex: 1 к элементу article-content , тем самым растянув его на все свободное место и прижав article-info к низу. Высота столбцов в этом случае не имеет значения.
Кликните для просмотра в действии
4. Добавляем несколько вложенных столбцов
На самом деле, нам нужно, чтобы левый столбец включал в себя еще несколько столбцов. Поэтому нам необходимо заменить второй элемент, отвечающий за статью, контейнером columns , который мы использовали ранее.
Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс nested-column , а в CSS укажем:
Nested-column {
flex: 2;
}
Теперь этот столбец будет вдвое шире второго.
Кликните для просмотра в действии
5. Делаем первую статью с горизонтальным лейаутом
Первая статья у нас на самом деле большая. Дабы эффективно использовать место на экране монитора, давайте изменим ее ориентацию на горизонтальную.First-article {
flex-direction: row;
}
.first-article .article-body {
flex: 1;
}
.first-article .article-image {
height: 300px;
order: 2;
padding-top: 0;
width: 400px;
}
Свойство order
в данном случае играет большую роль, поскольку оно позволяет изменять очередность HTML-элементов без изменения HTML-разметки. В действительности, article-image
в коде идет перед элементом article-body
, но ведет себя так, будто стоит после него.
Кликните для просмотра в действии
6. Делаем адаптивный лейаут
Теперь все выглядит так, как мы хотели, хотя и немного сплющено. Давайте исправим это, добавив нашему лейауту гибкости.Одной из замечательных вещей в Flexbox является то, что достаточно удалить правило display: flex в контейнере для того, чтобы полостью отключить его (Flexbox), в то время, как остальные его свойства (такие, как align-items или flex ) останутся рабочими.
В результате, мы можем активировать адаптивный лейаут, задействовав Flexbox только тогда, когда в этом будет необходимость.
Итак, мы собираемся удалить display: flex из селекторов .columns и .column , вместо этого «запаковав» их в медиа-запрос:
@media screen and (min-width: 800px) {
.columns,
.column {
display: flex;
}
}
Вот и все! На экранах с маленьким разрешением все статьи будут располагаться друг над другом, а на экранах с разрешением свыше 800 пикселей - в два столбца.
7. Добавляем завершающие штрихи
Для того, чтобы лейаут выглядел более привлекательно на больших экранах, давайте добавим кое-какие CSS-твики: @media screen and (min-width: 1000px) {
.first-article {
flex-direction: row;
}
.first-article .article-body {
flex: 1;
}
.first-article .article-image {
height: 300px;
order: 2;
padding-top: 0;
width: 400px;
}
.main-column {
flex: 3;
}
.nested-column {
flex: 2;
}
}
Содержимое первой статьи выровнено по горизонтали: текст расположен по левой стороне, а картинка - по правой. Также, главный столбец теперь стал шире (75%). То же самое касается и вложенного столбца (66%).
А вот и финальный результат!
Кликните для просмотра в действии