NeuroAgent

How to Create 4 Blocks with Equal Spacing in Flexbox

Solving unequal spacing issues between blocks in Flexbox. Learn the correct methods for creating 4 elements with equal gaps and responsive design.

Question

How can I create 4 blocks with equal spacing between them using Flexbox?

I have the following HTML code:

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="Amount must be a multiple of 100 and greater than 900" value="" inputmode="numeric">
    </label>
</div>

I’m using the following CSS:

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); /* half of gap +1px, as it will wrap on small screens */
    margin-top: 0;
}

However, the spacing between the blocks is uneven. I have 13px and 11px between the first blocks, and 10px between the third block and the input field. What is the error in my code?

NeuroAgent

Creating 4 Blocks with Equal Spacing Using Flexbox

To create 4 blocks with equal spacing between them using Flexbox, you need to properly configure the styles and structure. The main problem in your code lies in the incorrect combination of properties and inaccurate calculation of element widths.

Table of Contents

Common Errors in Your Code

  1. Incorrect Structure: You have 3 list items + 1 input field, but you’re trying to style only the list while ignoring the overall container.

  2. Property Conflict: Using both justify-content: space-between and gap: 10px simultaneously creates conflicting results in space distribution.

  3. Incorrect Width Calculation: width: calc(33% - 6px) is designed for 3 elements, but you need 4 blocks.

  4. Double Margin: Both the container and list have gap: 10px, which doubles the spacing.

As explained in the Flexbox Guide, the gap property is the preferred method for creating uniform spacing between elements.

Correct Solution for 4 Blocks

Here’s the corrected code for creating 4 blocks with equal spacing:

html
<div class="modal__box-nominal-list">
    <a href="javascript:void(0);" class="nominal-item active_nominal">10 000 ₽</a>
    <a href="javascript:void(0);" class="nominal-item">30 000 ₽</a>
    <a href="javascript:void(0);" class="nominal-item">100 000 ₽</a>
    <div class="input-container">
        <input id="free_nominal" name="free_nominal" class="input" type="text" 
               placeholder="Amount must be a multiple of 100 and greater than 900" 
               value="" inputmode="numeric">
    </div>
</div>
css
.modal__box-nominal-list {
    width: 100%;
    display: flex;
    gap: 10px; /* Equal spacing between all elements */
    flex-wrap: wrap; /* Wrap on small screens */
}

.nominal-item {
    flex: 1 1 calc(25% - 10px); /* Equal width accounting for gaps */
    min-width: calc(25% - 10px);
    text-align: center;
    padding: 10px;
    /* Other styles for buttons */
}

.input-container {
    flex: 1 1 calc(25% - 10px); /* Same width as other elements */
    min-width: calc(25% - 10px);
}

.input {
    width: 100%;
    /* Styles for input field */
}

This approach uses the modern method with the gap property, as recommended by modern CSS standards. The calculation calc(25% - 10px) accounts for 25% width minus half the gap on each side.

Alternative Approaches

1. Using justify-content with Equal Margins

css
.modal__box-nominal-list {
    width: 100%;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
}

.nominal-item, .input-container {
    width: calc(25% - 7.5px); /* 25% minus 3/4 of the gap */
}

2. Responsive Solution with flex-basis

css
.modal__box-nominal-list {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.nominal-item, .input-container {
    flex: 0 0 calc(50% - 5px); /* 2 per row on large screens */
}

@media (min-width: 768px) {
    .nominal-item, .input-container {
        flex: 0 0 calc(25% - 7.5px); /* 1 per row on small screens */
    }
}

As noted in the article on Flexbox, this approach ensures automatic space distribution between elements.

Solution for Responsive Design

For full responsiveness, you can use the following solution:

css
.modal__box-nominal-list {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: stretch;
}

.nominal-item, .input-container {
    flex: 1 1 calc(50% - 5px); /* 2 per row on mobile */
    min-width: calc(50% - 5px);
}

@media (min-width: 600px) {
    .nominal-item, .input-container {
        flex: 1 1 calc(33.333% - 6.66px); /* 3 per row on tablets */
        min-width: calc(33.333% - 6.66px);
    }
}

@media (min-width: 992px) {
    .nominal-item, .input-container {
        flex: 1 1 calc(25% - 7.5px); /* 4 per row on desktop */
        min-width: calc(25% - 7.5px);
    }
}

Common Problems and Their Solutions

Problem: Uneven spacing between elements

Cause: Conflict between gap and justify-content
Solution: Use only gap for equal spacing in modern browsers

Problem: Elements wrapping to new lines unevenly

Cause: Incorrect min-width calculation
Solution: Ensure min-width equals flex-basis

Problem: Input field has different height

Cause: Different content in elements
Solution: Add align-items: stretch to equalize height

As explained by Er Raj Aryan, the modern approach using the gap property solves most spacing issues in Flexbox and Grid layouts.


Sources

  1. CSS Flexbox Guide — design.dev
  2. CSS Flexbox: The Power of Flexible Box Layouts - DEV Community
  3. Basic CSS 02 — CSS Layouts (Flexbox, Positioning, Margin/Padding) - Medium
  4. Self Gap: Customizing Spacing Between Specific Flex or Grid Items in CSS - Medium

Conclusion

  • Main problem in your code is conflicting properties and incorrect structure for 4 elements
  • Correct approach uses the gap property for equal spacing and flex: 1 1 calc(25% - 10px) for equal width distribution
  • Modern browsers fully support gap, making it the preferred method for creating spacing
  • For responsive design, use media queries to change the number of items per row
  • Avoid simultaneous use of justify-content and gap for the same container, as this creates conflicting results

Apply the proposed solutions, and you’ll get 4 blocks with perfectly equal spacing between them on all devices.