Как создать равные отступы между четырьмя блоками с помощью Flexbox?
У меня есть следующий 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:
.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
Самый современный и надежный способ использует свойство gap для создания равных интервалов:
.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
Альтернативные методы
Метод с отрицательными отступами
.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; /* равные отступы с двух сторон */
}
Этот подход упоминается в источниках как надежный способ для создания равных интервалов источник.
Оптимизация вашего кода
Основные ошибки в вашем исходном коде:
- Неправильный расчет ширины:
calc(33% - 6px)не учитывает реальное количество gap - Конфликт
space-betweenсflex-wrap: Эти свойства не работают хорошо вместе - Отсутствие сброса стилей списка:
marginиpaddingпо умолчанию нарушают макет
Правильный расчет для 3 элементов в ряд с gap:
li {
flex: 1 1 calc(33.333% - 6.666px); /* 100% / 3 - (2 * 10px) / 3 */
min-width: calc(33.333% - 6.666px);
}
Полный исправленный пример
<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>
.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 */
}
Советы по адаптивности
Для лучшей адаптивности используйте медиа-запросы:
@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, но для старых браузеров может потребоваться использовать отрицательные отступы или таблицы стилей с префиксами.
Источники
- Gap — светлое будущее для отступов в Flexbox (как в Grid)
- Простой способ задать отступы между flexbox элементами
- Вертикальное расстояние между элементами в Flexbox: решение
- Гайд по flexbox — CSS — Дока
Заключение
- Основная проблема: Конфликт между
justify-content: space-betweenиflex-wrap: wrapприводит к неравномерным отступам - Лучшее решение: Использовать свойство
gapдля создания равных интервалов - Правильный расчет: Ширина элементов должна учитывать количество gap между ними
- Адаптивность: Используйте медиа-запросы для изменения количества элементов в ряду на разных экранах
- Совместимость:
gapхорошо поддерживается в современных браузерах, для старых используйте отрицательные отступы
Ваш макет будет работать корректно, если отказаться от justify-content: space-between и использовать современный подход с gap и автоматическим распределением пространства через flex property.