One key aspect is how to calculate the height for the <main>
element and utilize the flex
property, especially flex-grow
and flex-shrink
.
The Importance of <header>
, <main>
, and <footer>
In the second row, it's not necessary for all the remaining pale green space to be filled. The height can be flexible.
If your goal is to keep the <header>
and <footer>
at the top and bottom consistently, setting explicit heights for them as well as for the <main>
section is recommended over the standard absolute positioning approach.
HTML Markup
<header>header</header>
<main class="container-fluid"></main>
<footer>footer</footer>
CSS Styling
$custom-header-height: 3rem;
$custom-footer-height: 2rem;
header, footer {
background-color: var(--gray);
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
header {
height: $custom-header-height;
}
footer {
height: $custom-footer-height;
}
main {
height: calc(100vh - #{$custom-header-height} - #{$custom-footer-height});
background-color: var(--teal);
}
Visual Outcome
https://i.sstatic.net/RmgBt.png
This setup provides a foundation for further development.
The First Row Scenario
The first row should expand based on its contents but without taking up any extra free space. By setting flex-grow: 0;
you prevent it from expanding unnecessarily. Similarly, setting flex-shrink: 0;
ensures that cards within don't spill over when window size reduces. Using the shorthand flex: 0 0 auto;
achieves these settings efficiently.
To enable this behavior, both the first and second rows need to be children elements of a flex container. Therefore, we apply display:flex;
on the parent element - <main>
.
Updated HTML Structure
<header>header</header>
<main class="container-fluid">
<div class="row first-row">
<div class="col-6">
<div class="card">...</div>
</div>
<div class="col-6">
<div class="card">...</div>
</div>
</div>
</main>
<footer>footer</footer>
Additional SCSS Styling
main {
display: flex;
flex-flow: column nowrap;
}
.first-row {
background-color: var(--yellow);
flex: 0 0 auto;
}
Outcome
https://i.sstatic.net/jEaTm.png
The Second Row Adjustment
To maintain the growth/shrink behavior within the <card>
elements in the second row, use the default setting of flex: 0 1 auto;
. Ensure the parent also has display: flex;
applied, like the col-6
grid system provided by Bootstrap.
Updated HTML Content
<header>header</header>
<main class="container-fluid">
<div class="row first-row">
<div class="col-6">
<div class="card">...</div>
</div>
<div class="col-6">
<div class="card">...</div>
</div>
</div>
<div class="row second-row">
<div class="col-6">
<div class="card">
...
...
...
</div>
</div>
</div>
</main>
<footer>footer</footer>
Extra CSS Styling Details
.second-row {
background-color: var(--blue);
[class*="col-"] {
display: flex;
flex-flow: column nowrap;
min-height: 0;
.card {
.card-body {
overflow-y: auto;
}
}
}
}
Result Overview
The second row doesn't have to fill in all remaining pale green place. It's height can be flexible.
https://i.sstatic.net/a9JDt.png
An illustration of what I'd like to achieve
https://i.sstatic.net/tmWxm.png
The page should only have scrollbars if the second row is already "fully compressed" (0 height) and still the header + first row + footer can't fit in the viewport
https://i.sstatic.net/7RVoL.png
Wrap-Up Notes
An issue remains when the second row is fully compressed with the scrollbar persisting, an optimal solution is still pending.
Simplifying the code could be explored further, potentially eliminating the bootstrap grid system dependency.
Live Demonstration
https://codepen.io/anon/pen/XBqyxZ
Thank you for reading through this detailed explanation. For more insights into flexbox
, check out this comprehensive guide: https://css-tricks.com/snippets/css/a-guide-to-flexbox/