Перейти к содержанию

Управление элементами. flex-basis, flex-shrink и flex-grow

Кроме свойств, устанавливающих выравнивание элементов относительно границ flex-контейнера, есть еще три свойства, которые позволяют управлять элементами:

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

flex-basis

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

Это свойство может принимать следующие значения:

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

Например:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Flexbox в CSS3</title>
        <style>
            .flex-container {
                display: flex;
                border:1px #ccc solid;
            }
            .flex-item {
                text-align:center;
                font-size: 1em;
                padding: 1.2em;
                color: white;
            }
            .item1 {background-color: #675BA7; flex-basis: auto; width:150px;}
            .item2 {background-color: #9BC850; flex-basis: auto; width:auto;}
            .item3 {background-color: #A62E5C; flex-basis: 200px;width:150px;}
        </style>
    </head>
    <body>
        <div class="flex-container">
            <div class="flex-item item1">Flex Item 1</div>
            <div class="flex-item item2">Flex Item 2</div>
            <div class="flex-item item3">Flex Item 3</div>
        </div>
</html>

Управление элементами. flex-basis, flex-shrink и flex-grow

У первого элемента у свойства flex-basis установлено значение auto. Поэтому первый элемент в качестве реального значения для ширины будет использовать значение свойства width.

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

У третьего элемента свойство flex-basis имеет конкретное значение, которое и используется. А свойство width в этом случае уже не играет никакой роли.

flex-shrink

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

В качестве значения свойство принимает число. По умолчанию его значение 1.

Рассмотрим действие этого свойства на примере:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Flexbox в CSS3</title>
        <style>
            .flex-container {
                display: flex;
                border:1px #ccc solid;
                width:400px;
            }
            .flex-item {
                text-align:center;
                font-size: 1em;
                padding: 1.2em;
                color: white;
            }
            .item1 {background-color: #675BA7; flex-basis: 200px; flex-shrink:1;}
            .item2 {background-color: #9BC850; flex-basis: 200px; flex-shrink:2;}
            .item3 {background-color: #A62E5C; flex-basis: 200px; flex-shrink:3;}
        </style>
    </head>
    <body>
        <div class="flex-container">
            <div class="flex-item item1">Flex Item 1</div>
            <div class="flex-item item2">Flex Item 2</div>
            <div class="flex-item item3">Flex Item 3</div>
        </div>
</html>

Управление элементами. flex-basis, flex-shrink и flex-grow

В данном случае начальная ширина каждого элемента равна 200px, то есть совокупная ширина составляет 600px. Однако ширина flex-контейнера составляет всего 400px. То есть размер контейнера недостаточен для вмещения в него элементов, поэтому в действие вступает свойство flex-shrink, которое определено у элементов.

Для усечения элементов браузер вычисляет коэффициент усечения (shrinkage factor). Он вычисляется путем перемножения значения свойства flex-basis на flex-shrink. Таким образом, для трех элементов мы получим следующие вычисления:

// первый элемент
200px * 1 = 200
// второй элемент
200px * 2 = 400
// третий элемент
200px * 3 = 600

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

flex-grow

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

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

Итак, используем свойство flex-grow:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Flexbox в CSS3</title>
        <style>
            .flex-container {
                display: flex;
                border:1px #ccc solid;
            }
            .flex-item {
                text-align:center;
                font-size: 1em;
                padding: 1.3em;
                color: white;
            }
            .item1 {background-color: #675BA7; flex-grow:0;}
            .item2 {background-color: #9BC850; flex-grow:1;}
            .item3 {background-color: #A62E5C; flex-grow:2;}
        </style>
    </head>
    <body>
        <div class="flex-container">
            <div class="flex-item item1">Flex Item 1</div>
            <div class="flex-item item2">Flex Item 2</div>
            <div class="flex-item item3">Flex Item 3</div>
        </div>
</html>

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

Управление элементами. flex-basis, flex-shrink и flex-grow

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

Управление элементами. flex-basis, flex-shrink и flex-grow

Так как у первого элемента свойство flex-grow равно 0, то первый элемент будет иметь константные постоянные размеры. У второго элемента flex-grow равно 1, а третьего - 2. Таким образом, в сумме они дадут 0 + 1 + 2 = 3. Поэтому второй элемент будет увеличиваться на 1/3 дополнительного пространства, на которое растягивается контейнер, а третий элемент будет получать 2/3 дополнительного пространства.

Свойство flex

Свойство flex является объединением свойств flex-basis, flex-shrink и flex-grow и имеет следующий формальный синтаксис:

flex: [flex-grow] [flex-shrink] [flex-basis];

По умолчанию свойство flex имеет значение 0 1 auto.

Кроме конкретных значений для каждого из подсвойств мы можем задать для свойства flex одно из трех общих значений:

  • flex: none: эквивалентно значению 0 0 auto, при котором flex-элемент не растягивается и не усекается при увеличении и уменьшении контейнера
  • flex: auto: эквивалентно значению 1 1 auto
  • flex: initial: эквивалентно значению 0 1 auto

Так, применим свойство flex:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Flexbox в CSS3</title>
        <style>
            .flex-container {
                display: flex;
                border:1px #ccc solid;
                width: 600px;
            }
            .flex-item {
                text-align:center;
                font-size: 16px;
                padding: 10px 0;
                color: white;
            }
            .item1 {background-color: #675BA7; width: 150px; flex: 0 0 auto }
            .item2 {background-color: #9BC850; width: 150px; flex: 1 0 auto;}
            .item3 {background-color: #A62E5C; width: 150px; flex: 0 1 auto;}
            .item4 {background-color: #2A9FBC; width: 150px; flex: 1 1 auto;}
        </style>
    </head>
    <body>
        <div class="flex-container">
            <div class="flex-item item1">Flex Item 1</div>
            <div class="flex-item item2">Flex Item 2</div>
            <div class="flex-item item3">Flex Item 3</div>
            <div class="flex-item item4">Flex Item 4</div>
        </div>
</html>

Управление элементами. flex-basis, flex-shrink и flex-grow

Здесь каждый элемент имеет начальную ширину в 150 пикселей, так как у всех элементов свойство flex-basis имеет значение 0, что в целом для всех элементов будет составлять 600 пикселей.

При сжатии контейнера будут уменьшаться 3-й и 4-й элементы, так как у них свойство flex-shrink больше нуля. И так как у обоих элементов это свойство равно 1, то оба элемента будут уменьшаться в равных долях.

При растяжении контейнера будут увеличиваться 2-й и 4-й элементы, так как у этих элементов свойство flex-grow больше нуля. И также, так как это свойство равно 1, то эти элементы будут увеличиваться в равных долях.