My top-level layout is n columns, all of which are of fixed width (sidebars) except for the central one (mainbar) that should automatically fill up the remaining space.
So, I have this tricky wide table in the mainbar. It has a wrapper with overflow-x: auto
, however instead of triggering the scrolling on the wrapper, it prefers to stretch everything up to the top-level flex container. This can be solved by adding width: calc(100% - {sum of widths of other columns}px)
to the mainbar, but I'm looking for a more flexible solution that would allow adding more columns and resizing the existing ones without touching this calc
rule.
Any ideas? Is there any way to say to a flex item: fill up the remaining space, but don't allow your content to stretch you?
UPD: Managed to do it by wrapping the content of the mainbar in a table with table-layout: fixed
(the code is here), but I feel bad about it. Does anyone know of a more flexboxy solution? Or is this one okay?
// this JS generates placeholder text, ignore it
for (const el of document.querySelectorAll(".lorem")) {
el.innerHTML = Array(Number(el.getAttribute("p")) || 1)
.fill()
.map(() => `<p>${chance.paragraph()}</p>`)
.join("");
}
body {
margin: 0;
}
.outer {
display: flex;
}
.sidebar {
flex: 0 0 300px;
background: #eef;
}
.mainbar {
background: #ffe;
/* width: calc(100% - 500px); */
}
.rightbar {
flex: 0 0 200px;
background: #fef;
}
.table-wrapper {
width: 100%;
overflow-x: auto;
background: pink;
}
.table-wrapper td {
min-width: 400px;
}
<script src="https://unpkg.com/[email protected]/chance.js"></script>
<div class="outer">
<div class="sidebar">
<div class="lorem" p="4"></div>
</div>
<div class="mainbar">
<div class="table-wrapper">
<table>
<tr>
<td class="lorem"></td>
<td class="lorem"></td>
<td class="lorem"></td>
<td class="lorem"></td>
</tr>
</table>
</div>
<div class="lorem" p="10"></div>
</div>
<div class="rightbar">
<div class="lorem" p="3"></div>
</div>
</div>
If I understand you correct, add flex: 1; min-width: 0;
to your .mainbar
rule and it should behave.
The flex: 1
will make it take available space and min-width: 0
will allow a flex item to be smaller than its content, which you can read more about here:
Stack snippet
// this JS generates placeholder text, ignore it
for (const el of document.querySelectorAll(".lorem")) {
el.innerHTML = Array(Number(el.getAttribute("p")) || 1)
.fill()
.map(() => `<p>${chance.paragraph()}</p>`)
.join("");
}
body {
margin: 0;
}
.outer {
display: flex;
}
.sidebar {
flex: 0 0 300px;
background: #eef;
}
.mainbar {
background: #ffe;
flex: 1;
min-width: 0;
/* width: calc(100% - 500px); */
}
.rightbar {
flex: 0 0 200px;
background: #fef;
}
.table-wrapper {
width: 100%;
overflow-x: auto;
background: pink;
}
.table-wrapper td {
min-width: 400px;
}
<script src="https://unpkg.com/[email protected]/chance.js"></script>
<div class="outer">
<div class="sidebar">
<div class="lorem" p="4"></div>
</div>
<div class="mainbar">
<div class="table-wrapper">
<table>
<tr>
<td class="lorem"></td>
<td class="lorem"></td>
<td class="lorem"></td>
<td class="lorem"></td>
</tr>
</table>
</div>
<div class="lorem" p="10"></div>
</div>
<div class="rightbar">
<div class="lorem" p="3"></div>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With