НейроАгент

Равные отступы в Flexbox: полное руководство

Узнайте, как создать равные отступы между блоками в Flexbox. Решение проблем с неравномерными интервалами и лучшие практики для адаптивного дизайна.

Вопрос

Как создать равные отступы между четырьмя блоками с помощью Flexbox?

У меня есть следующий HTML-код:

html
<div class="modal__box-nominal-list">
    <ul>
        <li><a href="javascript:void(0);" class="active_nominal">10 000 ₽</a></li>
        <li><a href="javascript:void(0);">30 000 ₽</a></li>
        <li><a href="javascript:void(0);">100 000 ₽</a></li>
    </ul>
    <label class="input-container" for="free_nominal">
        <input id="free_nominal" name="free_nominal" class="input" type="text" placeholder="Сумма должна быть кратной 100 и больше 900" value="" inputmode="numeric">
    </label>
</div>

Я использую следующий CSS для Flexbox:

css
.modal__box-nominal-list {
    width:100%;
    display: flex;
    gap: 10px;
    flex-direction: column;
}

ul {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;    
}

li {
    display:block;
    width:calc(33% - 6px); //половина от gap +1px, так как на малых экранах будет перенос
    margin-top:0;
}

Проблема: расстояния между блоками получаются неравномерными. Между первыми блоками у меня 13px и 11px, а между третьим блоком и инпутом - 10px. В чем заключается ошибка в моем коде?

НейроАгент

Ваш код содержит несколько распространенных ошибок, которые приводят к неравномерным отступам. Основные проблемы связаны с неправильным расчетом ширины элементов и конфликтом между justify-content: space-between и flex-wrap: wrap.

justify-content: space-between создает неравномерные отступы при переносе элементов на новую строку, так как он пытается распределить пространство между всеми элементами ряда, включая крайние, что приводит к разным интервалам.

Для создания равных отступов между четырьмя блоками лучше использовать современные подходы с gap свойством и правильным расчетом ширины элементов.

Содержание

Решение с использованием gap

Самый современный и надежный способ использует свойство gap для создания равных интервалов:

css
.modal__box-nominal-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

ul {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

li {
    flex: 1 1 calc(50% - 10px); /* 2 элемента в ряд с учетом gap */
    min-width: calc(50% - 10px);
}

Почему это работает:

  • gap: 10px создает равные интервалы между элементами
  • flex: 1 1 calc(50% - 10px) автоматически распределяет пространство, учитывая отступы
  • Нет необходимости в сложных расчетах с justify-content

Альтернативные методы

Метод с отрицательными отступами

css
.modal__box-nominal-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

ul {
    display: flex;
    flex-wrap: wrap;
    margin: 0 -5px; /* отрицательный отступ для компенсации */
    padding: 0;
    list-style: none;
}

li {
    width: calc(50% - 10px); /* 50% - 10px (2 по 5px margin) */
    margin: 5px; /* равные отступы с двух сторон */
}

Этот подход упоминается в источниках как надежный способ для создания равных интервалов источник.


Оптимизация вашего кода

Основные ошибки в вашем исходном коде:

  1. Неправильный расчет ширины: calc(33% - 6px) не учитывает реальное количество gap
  2. Конфликт space-between с flex-wrap: Эти свойства не работают хорошо вместе
  3. Отсутствие сброса стилей списка: margin и padding по умолчанию нарушают макет

Правильный расчет для 3 элементов в ряд с gap:

css
li {
    flex: 1 1 calc(33.333% - 6.666px); /* 100% / 3 - (2 * 10px) / 3 */
    min-width: calc(33.333% - 6.666px);
}

Полный исправленный пример

html
<div class="modal__box-nominal-list">
    <ul>
        <li><a href="javascript:void(0);" class="active_nominal">10 000 ₽</a></li>
        <li><a href="javascript:void(0);">30 000 ₽</a></li>
        <li><a href="javascript:void(0);">100 000 ₽</a></li>
    </ul>
    <label class="input-container" for="free_nominal">
        <input id="free_nominal" name="free_nominal" class="input" type="text" placeholder="Сумма должна быть кратной 100 и больше 900" value="" inputmode="numeric">
    </label>
</div>
css
.modal__box-nominal-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

ul {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

li {
    flex: 1 1 calc(33.333% - 6.666px);
    min-width: calc(33.333% - 6.666px);
}

li a {
    display: block;
    padding: 10px;
    text-align: center;
    background: #f5f5f5;
    border-radius: 4px;
    text-decoration: none;
    color: #333;
}

.input-container {
    margin-top: 0; /* убираем дополнительный отступ от gap */
}

Советы по адаптивности

Для лучшей адаптивности используйте медиа-запросы:

css
@media (max-width: 768px) {
    li {
        flex: 1 1 calc(50% - 10px);
        min-width: calc(50% - 10px);
    }
}

@media (max-width: 480px) {
    li {
        flex: 1 1 100%;
        min-width: 100%;
    }
}

Важно: Современные браузеры хорошо поддерживают свойство gap, но для старых браузеров может потребоваться использовать отрицательные отступы или таблицы стилей с префиксами.

Источники

  1. Gap — светлое будущее для отступов в Flexbox (как в Grid)
  2. Простой способ задать отступы между flexbox элементами
  3. Вертикальное расстояние между элементами в Flexbox: решение
  4. Гайд по flexbox — CSS — Дока

Заключение

  • Основная проблема: Конфликт между justify-content: space-between и flex-wrap: wrap приводит к неравномерным отступам
  • Лучшее решение: Использовать свойство gap для создания равных интервалов
  • Правильный расчет: Ширина элементов должна учитывать количество gap между ними
  • Адаптивность: Используйте медиа-запросы для изменения количества элементов в ряду на разных экранах
  • Совместимость: gap хорошо поддерживается в современных браузерах, для старых используйте отрицательные отступы

Ваш макет будет работать корректно, если отказаться от justify-content: space-between и использовать современный подход с gap и автоматическим распределением пространства через flex property.