skip to Main Content

I have the following HTML/CSS code, whenever I toggle the display: flex in .cards-container the height of the .card div seems to shrink (when display: flex is not present) and grow (when display: flex is present).

I was wondering what’s the reason for this behaviour, I thought that flexbox didn’t affect the size of inner divs.

When display: flex is present in .cards-container:

* {
    font-family: sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.cards-container {
    display: flex;
    background-color: #e8e8e8;
}


.card {
    width: 250px;
    height: fit-content;
    border-radius: 30px;
    background-color: white;
}

.card > .card-bottom-container {
    margin: 1rem;
    gap: 1rem;
}

.card > .card-bottom-container > .card-tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.card > .card-bottom-container > .card-tags-container > .card-tag {
    background-color: red;
    border-radius: 10px;
    padding: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
</head>
<body>
    <div class="cards-container">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

When display: flex is NOT present in .cards-container (note: that’s the only thing that has changed, everything else remains the same):

* {
    font-family: sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.cards-container {
    background-color: #e8e8e8;
}


.card {
    width: 250px;
    height: fit-content;
    border-radius: 30px;
    background-color: white;
}

.card > .card-bottom-container {
    margin: 1rem;
    gap: 1rem;
}

.card > .card-bottom-container > .card-tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.card > .card-bottom-container > .card-tags-container > .card-tag {
    background-color: red;
    border-radius: 10px;
    padding: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
</head>
<body>
    <div class="cards-container">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

2

Answers


  1. When you set a container to display: flex, these are the things you need to keep in mind

    • the default alignment of flex items is along the main axis (horizontally by default).
    • Flex items will try to fit their content based on their size and the available space in the flex container.
    • But if the content’s size exceeds the container’s available space, flex items may grow or shrink respectively.
    • The height of .card is influenced by its contents and flex properties. As the .card is a flex item, it may stretch or shrink based on the flex container’s rules and the content inside it.

    The default behavior is block layout, which means the .card will take its height based on its content without any flex rules affecting its size.

    The use of height: fit-content; means that the height of the .card will adjust based on its contents.
    This might lead to a difference in visual height when switching between flex and block layouts, especially if the content changes or has varying sizes.
    The flex items might stretch to fill the container based on their content and flex properties.

    if you haven’t applied display: flex
    The .card behaves like a block-level element, taking height based solely on its content without flex properties coming into play.
    This could result in a different visual height depending on the arrangement and size of inner elements.
    If you want the .card to maintain a specific height, you can set a fixed height (e.g., height: 300px;) instead of fit-content.and you can Use flex properties like align-items on the .cards-container to control how items are aligned and sized. For example:

    .cards-container {
        display: flex;
        align-items: flex-start; /* or center, or stretch */
    }
    

    If you want to ensure the cards don’t shrink below a certain height, consider using
    min height

       .card {
           min-height: 200px;
       }
    
    Login or Signup to reply.
  2. The reason for the height difference is that in some scenarios the top and bottom margins on .card-bottom-container will collapse, and in other circumstances they will not. Here is a snippet to demonstrate some scenarios.

    .cards-container {
      background-color: #e8e8e8;
      margin-bottom: 1em;
    }
    
    .cards-container.with-flex {
      display: flex;
    }
    
    .card {
      width: 250px;
      background-color: yellow;
    }
    
    .cards-container.with-border .card {
      border: 1px solid blue;
    }
    
    .card > .card-bottom-container {
      margin: 1em;
      gap: 1em;
    }
    
    .card > .card-bottom-container > .card-tags-container {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5em;
      border: 1px solid magenta;
    }
    
    .card > .card-bottom-container > .card-tags-container > .card-tag {
      background-color: red;
      border-radius: 10px;
      padding: 10px;
    }
    
    .cards-container.with-padding-instead-of-margin .card {
      padding: 1em;
      box-sizing: border-box;
    }
    
    .cards-container.with-padding-instead-of-margin .card > .card-bottom-container {
      margin: 0;
    }
    
    code {
      background: #ddd;
      padding: 0 5px;
    }
    <p>First <strong>without</strong> <code>display: flex</code> on <code>.cards-container</code>. The top and bottom margins of <code>.card-bottom-container</code> extend outside <code>.card</code>, resulting in <code>.card</code> being only as high as the red dots. You can’t see these margins because they collapse with the margins of the neighbouring elements.</p>
    
    <div class="cards-container">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>
    
    <p>Next <strong>with</strong> <code>display: flex</code> on <code>.cards-container</code>. The top and bottom margins of <code>.card-bottom-container</code> are now contained within <code>.card</code>.</p>
    
    <div class="cards-container with-flex">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>
    
    <p>Next with a border around <code>.card</code>. The top and bottom margins of <code>.card-bottom-container</code> are contained within <code>.card</code>.</p>
    
    <div class="cards-container with-border">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>
    
    <p>Finally without any margin around <code>.card-bottom-container</code>, and instead with padding inside <code>.card</code>. This is the most straight-forward layout, and thus the recommended one.</p>
    
    <div class="cards-container with-padding-instead-of-margin">
        <div class="card">
            <div class="card-bottom-container">
                <div class="card-tags-container">
                    <a href="/path-1" class="card-tag"></a>
                    <a href="/path-2" class="card-tag"></a>
                    <a href="/path-3" class="card-tag"></a>
                    <a href="/path-4" class="card-tag"></a>
                    <a href="/path-5" class="card-tag"></a>
                </div>
            </div>
        </div>
    </div>

    I suggest you review this material on collapsing margins to help you understand how margins behave. Then I suggest you change your code to use padding instead of margins, as per my last example.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search