I'm building a carousel inside a flex container which has flex-direction: column. I thought this would be trivial, and it probably is. I've built carousels by hand before but not in this exact circumstance.
My problem is that the content is a carousel, a scrolling list of items that is in a parent with overflow: hidden, but its size is not being constrained by its flex item parent so it is occupying the full width of all its child items. Normally a parent like that has its size constrained in some way, causing it to be smaller than its content, a very common design pattern.
Consider this snippet, with two columns in the outer layout, a Left panel (yellow) wants to be 30% width and Right panel (green) wants to be 60% width. Inside the left panel, I want a horizontal carousel, which contains many items, only a few of which will be visible because there isn't space to display them all (I would add proper scrolling mechanics later).
.container { display: flex;}.left-panel { flex: 0 0 33%; display: flex; flex-direction: column; background-color: yellow;}.right-panel { flex: 1 0 auto; flex-basis: 66%; background-color: green;}.items { flex: 1; overflow-x: hidden;}.items-wrapper { display: flex; flex-wrap: nowrap; gap: 1rem;}.item { width: 8rem; height: 8rem; background-color: red;}<div class="container"><div class="left-panel"><div class="title">Left Panel, this panel is supposed to be only 30% the width of the parent, but is being pushed wider by the children below.</div><p>I want the .items div to be the same width as the 33% wide .left-panel, and I'll deal with the scroll/overflow once that is working.</p><div class="items"><div class="items-wrapper"><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div></div></div></div><div class="right-panel"> Right Panel Here</div></div>See equivalent codepen https://codepen.io/neekfenwick/pen/QWRQrVL
I've told the left panel to be flex: 0 0 33% which I thought would force it to be 33% the width of its parent (the document), since flex-grow is 0 and flex-basis is 33%, and any content inside would be sized accordingly.
I understand that the content is physically larger than this requested 33%. How can I make the .items element respect the size requested by its parent?
Perhaps what's tripping me up is that the .left-panel has flex-direction: column which means the main axis is vertical, so the effect of flex-basis, flex-grow etc becomes confusing, but the flex axis of the outer .container is the default row so I can't narrow down what's going wrong.
I've found advice at Overflow and contain flex-child of a flex-child advising flex-basis: 0 which doesn't help.
This is not helped by having a bit of a stinker of a cold right now. Help would be hugely appreciated :)
For clarification, here is an example that achieves what I'm trying to do but without using Flexbox. Here, the left and right panels are divs with display: inline-block and fixed widths. See how the .items carousel is constrained within the width of .left-panel, so you cannot see the items that overflow its width.
https://codepen.io/neekfenwick/pen/JjqpZQz
.container { /* Container has no flex layout, children have fixed width */}.left-panel { display: inline-block; vertical-align: top; width: 33%; ffflex-direction: column; background-color: yellow;}.right-panel { display: inline-block; vertical-align: top; width: 66%; background-color: green;}.items { flex: 1; overflow-x: hidden;}.items-wrapper { display: flex; flex-wrap: nowrap; gap: 1rem;}.item { flex: 0 0 8rem; width: 8rem; height: 8rem; background-color: red;}<div class="container"><div class="left-panel"><div class="title">An example based on <a href="https://codepen.io/neekfenwick/pen/QWRQrVL">This Codepen https://codepen.io/neekfenwick/pen/QWRQrVL</a> but without using Flexbox, Left Panel, this panel is set to 33% the width of the parent.</div><p>The .items div is therefore the same width as the 33% wide .left-panel.</p><div class="items"><div class="items-wrapper"><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div><div class="item">Item</div></div></div></div><div class="right-panel"> Right Panel Here</div></div>