Reputation: 1350
I have a container #container
with a fixed width which has three children .item
. Each have a flex-basis of 100px but the middle one .item-grow
should grow so that all width of #container
is used. This works like expected.
The .item-grow
element has another children #too-big
which could be wider than the available parent's width so its wrapped inside a #scroll
container with overflow: scroll
and max-width: 100%
.
The problem is, that #scroll
ignores max-width: 100%
and forces the parent .item-grow
to grow which foces the container #container
to grow.
If I set max-width: 296px
instead of max-width: 100%
it works but I am looking for a dynamic (and CSS only) solution.
In the embedded code you can find a slider which changes the size of #too-big
, you can clearly see that its growing the parents and not using the scrollbars.
function setSize (newValue) {
let elem = document.getElementById("too-big");
elem.setAttribute("style",`width:${newValue}px; height:${newValue}px`);
}
#container {
background-color: red;
display: flex;
width: 500px;
height: 200px;
}
.item {
display: flex;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 100px;
border: solid black 1px;
background-color: gray;
}
.item-grow {
flex-grow: 1;
align-items: center;
}
.center-wrapper {
margin: auto;
display: table-cell;
}
.scroll {
overflow: scroll;
max-width: 100%; /* I want this respect the current parents width */
/* max-width: 296px; */
max-height: 100%; /* I want this respect the current parents height */
/* max-height: 200px; */
}
#too-big {
background-color: green;
width: 100px;
height: 100px;
}
<input type="range" min=100 max=500 value=100 oninput="setSize(this.value)" onchange="setSize(this.value)">
<div id="container">
<div class="item"></div>
<div class="item item-grow">
<div class="center-wrapper">
<div class="scroll">
<div id="too-big"></div>
</div>
</div>
</div>
<div class="item"></div>
</div>
Upvotes: 1
Views: 3022
Reputation: 87191
To make that work you can drop the center-wrapper
and set margin: auto
on the scroll
.
Then the item
need min-width: 0
to allow it to be smaller than its content.
And for the max-height: 100%
to work (cross browser), the item-grow
need a height.
Fiddle demo (with overflow: auto
instead)
Stack snippet
function setSize (newValue) {
let elem = document.getElementById("too-big");
elem.setAttribute("style",`width:${newValue}px; height:${newValue}px`);
}
#container {
background-color: red;
display: flex;
width: 500px;
height: 200px;
}
.item {
display: flex;
flex-basis: 100px;
border: solid black 1px;
background-color: gray;
box-sizing: border-box; /* added */
min-width: 0; /* added */
}
.item-grow {
flex-grow: 1;
align-items: center;
height: 100%; /* added */
}
.scroll {
margin: auto; /* added */
overflow: scroll;
max-width: 100%;
max-height: 100%;
}
#too-big {
background-color: green;
width: 100px;
height: 100px;
}
<input type="range" min=100 max=500 value=100 oninput="setSize(this.value)" onchange="setSize(this.value)">
<div id="container">
<div class="item"></div>
<div class="item item-grow">
<div class="scroll">
<div id="too-big"></div>
</div>
</div>
<div class="item"></div>
</div>
Upvotes: 2