CSS. Flexbox верстка

05.02.2019

Теги: CSSHTMLWeb-разработкаВерстка

Модель flexbox-разметки связана с определенным значением CSS-свойства display родительского элемента (flex-контейнер), содержащего внутри себя дочерние блоки (flex-элементы).

.flex-container {
    display: flex; /* контейнер как блочный элемент */
}
.flex-container {
     display: inline-flex; /* контейнер как строчный элемент */
}

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

<section>
    <div>Lorem ipsum</div>
    <div>Lorem ipsum dolor sit amet</div>
    <div>Lorem ipsum</div>
    <div>Lorem ipsum dolor sit amet</div>
    <div>Lorem ipsum</div>
</section>
section {
    display: flex;
    padding: 10px;
    background: #eee;
    width: 800px;
    height: 300px;
}
    section > div {
        box-sizing: border-box;
        padding: 10px;
        color: #fff;
    }
    section > div:nth-child(odd) {
        background: #9f9;
    }
    section > div:nth-child(even) {
        background: #f99;
    }

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

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

.flex-container {
    display: flex;
    flex-direction: row; /* по умолчанию — row (вправо) */
}

Другие значения свойства flex-directionrow-reverse (влево), column (вниз), column-reverse (вверх).

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

Чтобы разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии):

.flex-container {
    display: flex;
    flex-wrap: wrap; /* по умолчанию — nowrap, перенос запрещен */
}

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

.flex-container {
    display: flex;
    flex-flow: row wrap;
}

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

Выравнивание элементов вдоль главной оси

Свойство justify-content помогает распределить лишнее свободное пространство, когда все элементы имеют фиксированный размер или достигли своего максимального размера.

.flex-container {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start; /* по умолчанию — flex-start, относительно начала оси */
}

Другие значения свойства justify-content:

  • flex-end — элементы выравниваются относительно конца оси
  • center — элементы выравниваются по центру контейнера
  • space-between — равномерно, с одинаковым расстоянием между элементами
  • space-around — равномерно, с добавлением половины пространства перед первым элементом и после последнего

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

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

.flex-container {
    display: flex;
    flex-flow: row wrap;
    align-items: stretch; /* по умолчанию — stretch, растягиваются по всей длине поперечной оси */
}

Другие значения свойства align-items:

  • flex-start — относительно начала поперечной оси
  • flex-end — относительно конца поперечной оси
  • baseline — относительно базовой линии
  • center — по центру

Свойство align-self, заданное для определенного элемента, позволяет перезаписать свойство align-items, заданное для всех элементов в контейнере:

.flex-container {
    display: flex;
    flex-flow: row wrap;
    align-items: flex-start;
}
    .flex-container > div:last-child {
        align-self: flex-end;
    }

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

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

.flex-container {
    display: flex;
    flex-flow: row wrap;
    align-content: stretch; /* по умолчанию — stretch, растягиваются по всей длине поперечной оси */
}

Другие значения свойства align-content:

  • flex-start — относительно начала поперечной оси
  • flex-end — относительно конца поперечной оси
  • center — по центру
  • space-between — равномерно, с одинаковым расстоянием между линиями
  • space-around — равномерно, но с добавлением половины пространства перед первой линией и после последней

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

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

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

<div class="flex-container">
    <div id="flex-element-1">1</div>
    <div id="flex-element-2">2</div>
    <div id="flex-element-3">3</div>
    <div id="flex-element-4">4</div>
</div>
.flex-container {
    display: flex;
}
/* переместим 2-ой элемент в конец */
#flex-element-2 {
    order: 1;
} 
/* переместим 4-ый элемент в начало */
#flex-element-4 {
    order: -1;
}

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

Свойство flex-basis

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

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

Свойство flex-grow

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

<div class="flex-container">
    <div>1</div>
    <div>2</div>   
</div>
.flex-container {
    display: flex;
    width: 600px;
}
    .flex-container > div {
        flex-basis: 30%;
    }
.flex-container > div:first-child {
        flex-grow: 1;
    } 
    .flex-container > div:last-child {
        flex-grow: 4;
    }

В этом примере flex-элементы расположены на одной линии и в ней есть свободное пространство 240px. После установки значений для свойства flex-grow:

  • ширина первого элемента будет увеличена на 1/5 часть свободного пространства
  • ширина первого элемента будет увеличена на 4/5 части свободного пространства

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

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

Свойство flex-shrink

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

<div class="flex-container">
    <div>1</div>
    <div>2</div>   
</div>
.flex-container {
    display: flex;
    width: 400px;
}
    .flex-container > div {
        flex-basis: 300px;
        flex-shrink: 0; /* запрет на уменьшение ширины */
    }
.flex-container > div:first-child {
        flex-shrink: 1;
    } 
    .flex-container > div:last-child {
        flex-shrink: 3;
    }

Ширина flex-контейнера 400px, для отображения flex-элементов необходимо 600px, не хватает 200px. После установки значений больше нуля, уменьшаться могут оба элемента:

  • ширина первого элемента будет уменьшена на 1/4 от тех 200px, которых не хватает
  • ширина второго элемента будет уменьшена на 3/4 от тех 200px, которых не хватает

Значение свойства по умолчанию равно единице. Нулевое значение запрещает уменьшение ширины элемента.

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

.flex-element {
    flex: 0 1 auto; /* flex-grow: 0; flex-shrink: 1; flex-basis: auto; */
}

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

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Макет Flexbox</title>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <header>
            <p>Header</p>
        </header>
        <main>
            <article>
                <h1>Lorem Ipsum</h1>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor...</p>
            </article>
            <nav>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
            </nav>
            <aside>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
            </aside>
        </main>
        <footer>
            <p>Footer</p>
        </footer>
    </body>
</html>
/* Верстка по принципу mobile first, для больших экранов медиа-запрос */

* {
    box-sizing: border-box;
}
html, body {
    padding: 0;
    margin: 0;
}

body {
    /* flex-контейнер для <header>, <main> и <footer> */
    display: flex;
    /* flex-элементы <header>, <main> и <footer> выстаиваются по вертикали */
    flex-direction: column;
    /* вся высота viewport браузера */
    min-height: 100vh;
}
    header {
        /* не может увеличиваться или уменьшаться, всегда 100px */
        flex: 0 0 100px;
    }
    main {
        /*
        может как увеличиваться, так и уменьшаться, чтобы вместе с
        <header> и <footer> занять всю высоту viewport браузера
        */
        flex: 1 1 auto;
        /* flex-контейнер для <article>, <nav> и <aside> */
        display: flex;
        /*
        на маленьких экранах flex-элементы <article>, <nav> и <aside> выстаиваются
        по вертикали; для больших экранов отдельный media-запрос
        */
        flex-direction: column;
    }
        article {
            /* базовый размер 50%, может увеличиваться или уменьшаться */
            flex: 2 2 50%;
        }
        nav, aside {
            /* базовый размер 25%, могут увеличиваться или уменьшаться */
            flex: 1 1 25%;
        }
        nav {
            /* будет первым, хотя в html-коде идет вторым */
            order: -1;
        }
    footer {
        /* не может увеличиваться или уменьшаться, всегда 100px */
        flex: 0 0 100px;
    }

@media screen and (min-width: 800px) { /* медиа-запрос для больших экранов */
    main {
        /* на больших экранах <article>, <nav> и <aside> выстаиваются по горизонтали */
        flex-direction: row;
    }
        article {
            /* отступ слева и справа, чтобы отделить левую и правую колонки */
            padding: 0 1em 0 1em;
        }
}

Дополнительно

Поиск: CSS • HTML • Web-разработка • Верстка • Flexbox • flex-direction • justify-content • align-items • align-self • align-content • order • flex-basis • flex-grow • flex-shrink • Контейнер • Элемент

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.