Расчет ширины flex-элементов: объяснение работы формулы в CSS

Общая структура кода

Представленный код демонстрирует адаптивную flexbox-систему с использованием CSS custom properties (переменных) для точного расчета ширины дочерних элементов с учетом gap между ними.

Пример работы кода можно сразу посмотреть на CodePen

HTML структура с комментариями

HTML
<div class="page">          <!-- Основная страница-обертка -->
    <div class="container"> <!-- Контейнер для центрирования -->
        <div class="fx">    <!-- Flex-контейнер с 4 элементами -->
            <!-- Дочерние элементы с классом "i" (items) -->
            <div class="i">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque ea odio amet molestias nam exercitationem.</div>
            <div class="i">Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore, libero.</div>  
            <div class="i">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nobis quidem quam, modi quas totam deserunt dolores accusantium fuga nostrum placeat.</div>
            <div class="i">Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae, optio!</div>
        </div>
    </div>
</div>

CSS код с комментариями

CSS
.fx {
    --count: 4;         /* Переменная: количество элементов в ряду */
    --gap: 16px;        /* Переменная: размер промежутка между элементами */
    
    display: flex;      /* Включаем flexbox */
    border: 2px dotted #00000033;  /* Визуальная граница контейнера */
    padding: 16px;      /* Внутренние отступы */
    border-radius: 8px; /* Скругление углов */
    flex-wrap: wrap;    /* Разрешаем перенос элементов на новую строку */
    gap: var(--gap);    /* Устанавливаем промежутки между элементами */
}

.i {
    /* Главная формула расчета ширины элемента */
    --width: calc((100% - ( (var(--count) - 1 ) * var(--gap) ) ) / var(--count));
    
    border: 1px dashed #00000099;  /* Визуальная граница элемента */
    border-radius: 4px;            /* Скругление углов */
    flex-basis: var(--width);      /* Базовая ширина flex-элемента */
    width: var(--width);           /* Дублирование ширины для надежности */
}

Подробный алгоритм расчета ширины дочернего элемента

Формула расчета:

--width: calc((100% - ((var(--count) - 1) * var(--gap))) / var(--count))

Пошаговый разбор формулы:

1. Определяем количество промежутков между элементами

var(--count) - 1 = 4 - 1 = 3 промежутка

Если у нас 4 элемента, то между ними будет 3 промежутка.

2. Вычисляем общую ширину всех промежутков

(var(--count) - 1) * var(--gap) = 3 * 16px = 48px

3. Находим доступную ширину для самих элементов

100% - 48px = оставшаяся ширина для контента

4. Делим доступную ширину на количество элементов

(100% - 48px) / 4 = ширина одного элемента

Практический пример расчета:

При ширине контейнера 800px:

  • Общая ширина промежутков: 3 × 16px = 48px
  • Доступная ширина для элементов: 800px - 48px = 752px
  • Ширина одного элемента: 752px ÷ 4 = 188px

Принципы работы flex-basis и width

Почему используются оба свойства?

  1. flex-basis — определяет базовый размер flex-элемента до распределения свободного пространства
  2. width — служит резервным значением для большей совместимости с браузерами

Приоритет свойств:

content → width → flex-basis (ограничено max-width & min-width)

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

Преимущества данного подхода

1. Гибкость и переиспользование

  • Легко изменить количество элементов в ряду, изменив --count
  • Простая настройка размера промежутков через --gap

2. Точность расчетов

  • Элементы всегда помещаются в один ряд без переноса
  • Учитывается каждый пиксель промежутков

3. Адаптивность

CSS
/* Пример адаптивного использования */
@media (max-width: 768px) {
    .fx {
        --count: 2;  /* На мобильных устройствах - 2 элемента в ряду */
    }
}

Заключение

Данный код демонстрирует профессиональный подход к созданию гибкой grid-системы на flexbox с использованием математически точного расчета ширины элементов. Формула учитывает все промежутки между элементами и обеспечивает идеальное размещение без переполнения контейнера.