I'm working on a layout using CSS flexbox and facing an issue where I want my flex items to behave in a specific way when the browser window is resized:
Desired Behaviour:
When the window width decreases, the flex items should wrap until their combined height reaches the container's height
.
Once the container's height
is reached, the items should stop wrapping and start shrinking instead.
Current Issue:
Right now, the items continue wrapping and overflow the parent container's height.
Here is an example code showcasing my issue: Link to Flems.io
.container {
font-family: arial, sans-serif;
margin: 0;
padding: 0;
list-style-type: none;
border: 2px dashed red;
display: flex;
align-items: flex-start;
height: 120px;
flex-wrap: wrap;
}
.flex {
background: #6ab6d8;
padding: 10px;
border: 3px solid #2e86bb;
color: white;
font-size: 20px;
text-align: center;
width: 400px;
flex: 0 1 auto;
min-width: 0;
}
.flex2 {
width: 300px;
}
<ul class="container">
<li class="flex flex1">1: some flex item</li>
<li class="flex flex2">2: some flex item</li>
<li class="flex flex3">3: some flex item</li>
<li class="flex flex4">4: some flex item</li>
<li class="flex flex5">5: some flex item</li>
</ul>
I tried adding min-width: 0
to the flex items because I learned that flexbox sets min-width
to auto
by default, unlike other block-level elements where min-width
is typically 0
. However, this change didn’t solve the problem.
Maybe with container queries? We can detect the overflow event with the known widths of the children. A bit hacky, but is there a more natural way to do this without javascript?
* { box-sizing: border-box; min-width: 0; min-height: 0; }
.container {
font-family: arial, sans-serif;
margin: 0;
padding: 0;
list-style-type: none;
border: 2px dashed red;
display: flex;
align-items: flex-start;
height: 120px;
flex-wrap: wrap;
container-type: inline-size;
}
.flex {
background: #6ab6d8;
padding: 10px;
border: 3px solid #2e86bb;
color: white;
font-size: 20px;
text-align: center;
width: 400px;
flex: 0 1 auto;
}
.flex2 {
width: 300px;
}
@container (max-width: 1100px) {
.flex1 { flex-basis: calc(400 / 1100* 100%); }
.flex2 { flex-basis: calc(300 / 1100* 100%); }
.flex3 { flex-basis: calc(400 / 1100* 100%); }
.flex4 { flex-basis: calc(400 / 1100* 100%); }
.flex5 { flex-basis: calc(400 / 1100* 100%); }
/* Debug color change */
.flex {
background-color: aqua;
}
}
<!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="stylesheet.css">
</head>
<body>
<ul class="container">
<li class="flex flex1">1: some flex item</li>
<li class="flex flex2">2: some flex item</li>
<li class="flex flex3">3: some flex item</li>
<li class="flex flex4">4: some flex item</li>
<li class="flex flex5">5: some flex item</li>
</ul>
</body>
</html>
P.S: To do this without container queries, it can also be done with grid
. Its suggested and explained as a fallback in the documentation.