In a grid row with three tracks, I would like to have the left and right tracks exactly equally sized, while respecting the larger min-content of the two, and the middle track to take up the remaining space, no matter the size of its contents. The following HTML+CSS illustrates the problem:
nav {
display: grid;
grid-template-columns: 1fr auto 1fr;
/* grid-template-columns: minmax(min-content, 1fr) auto minmax(min-content, 1fr); */
background: green;
align-items: center;
overflow: hidden;
}
.box {
box-sizing: border-box;
overflow: hidden;
}
.scroll-container {
position: relative;
}
ul {
display: flex;
border: 1px solid black;
border-radius: 4px;
list-style: none;
padding: 0;
overflow-x: auto;
position: relative;
li {
padding: 8px 16px;
white-space: nowrap;
&:not(:last-child) {
border-inline-end: 1px solid black;
}
}
}
.edge {
padding: 8px;
white-space: nowrap;
}
.right {
justify-self: end;
}
<nav>
<div class="box edge left">
<h3 class="title">Super Cool App</h3>
</div>
<div class="box centre">
<div class="scroll-container">
<ul class="links">
<li>First Link Item</li>
<li>Second Link Item</li>
<li>Third Link Item</li>
<li>Fourth Link Item</li>
<li>Fifth Link Item</li>
<li>Sixth Link Item</li>
<li>Seventh Link Item</li>
<li>Eighth Link Item</li>
<li>Ninth Link Item</li>
<li>Tenth Link Item</li>
</ul>
</div>
</div>
<div class="box edge right">
<button>X</button>
</div>
</nav>
grid-template-columns: 1fr auto 1fr;
sort of describes pretty well what I want to achieve, but does not work. Instead, as 1fr
is essentially equivalent to minmax(auto, 1fr)
as others have noted elsewhere, the edge tracks are reduced to 0 width and the middle track will take up the entire space. Something like grid-template-columns: minmax(min-content, 1fr) auto minmax(min-content, 1fr);
yields a somewhat better result but is not what I want either, because it will reduce the edges to min-content
, which is different for each one of them, i.e. they will not be equal width.
Short ans: No, it cannot be done without some compromises.
What you are asking for does not make sense, you want all three columns to fill "the remaining space" which is impossible to calculate as you don't specify the "occupied space".
Basically you want to give any sense of occupied space so that the browser can calculate how much to offer the others.
nav {
display: grid;
grid-template-columns: 1fr minmax(auto, 80%) 1fr;
/* grid-template-columns: minmax(min-content, 1fr) auto minmax(min-content, 1fr); */
background: green;
align-items: center;
overflow: hidden;
}
.box {
box-sizing: border-box;
overflow: hidden;
}
.scroll-container {
position: relative;
}
ul {
display: flex;
border: 1px solid black;
border-radius: 4px;
list-style: none;
padding: 0;
overflow-x: auto;
position: relative;
li {
padding: 8px 16px;
white-space: nowrap;
&:not(:last-child) {
border-inline-end: 1px solid black;
}
}
}
.edge {
padding: 8px;
white-space: nowrap;
}
.right {
justify-self: end;
}
<nav>
<div class="box edge left">
<h3 class="title">Super Cool App</h3>
</div>
<div class="box centre">
<div class="scroll-container">
<ul class="links">
<li>First Link Item</li>
<li>Second Link Item</li>
<li>Third Link Item</li>
<li>Fourth Link Item</li>
<li>Fifth Link Item</li>
<li>Sixth Link Item</li>
<li>Seventh Link Item</li>
<li>Eighth Link Item</li>
<li>Ninth Link Item</li>
<li>Tenth Link Item</li>
</ul>
</div>
</div>
<div class="box edge right">
<button>X</button>
</div>
</nav>
nav {
display: grid;
grid-template-columns: minmax(min-content, 1fr) minmax(auto, 80%) minmax(min-content, 1fr);
background: green;
align-items: center;
overflow: hidden;
}
.box {
box-sizing: border-box;
overflow: hidden;
}
.scroll-container {
position: relative;
}
ul {
display: flex;
border: 1px solid black;
border-radius: 4px;
list-style: none;
padding: 0;
overflow-x: auto;
position: relative;
li {
padding: 8px 16px;
white-space: nowrap;
&:not(:last-child) {
border-inline-end: 1px solid black;
}
}
}
.edge {
padding: 8px;
white-space: nowrap;
}
.right {
justify-self: end;
}
<nav>
<div class="box edge left">
<h3 class="title">Super Cool App</h3>
</div>
<div class="box centre">
<div class="scroll-container">
<ul class="links">
<li>First Link Item</li>
<li>Second Link Item</li>
<li>Third Link Item</li>
<li>Fourth Link Item</li>
<li>Fifth Link Item</li>
<li>Sixth Link Item</li>
<li>Seventh Link Item</li>
<li>Eighth Link Item</li>
<li>Ninth Link Item</li>
<li>Tenth Link Item</li>
</ul>
</div>
</div>
<div class="box edge right">
<button>X</button>
</div>
</nav>
nav {
display: grid;
grid-template-columns: 10rem auto 10rem;
background: green;
align-items: center;
overflow: hidden;
}
.box {
box-sizing: border-box;
overflow: hidden;
}
.scroll-container {
position: relative;
}
ul {
display: flex;
border: 1px solid black;
border-radius: 4px;
list-style: none;
padding: 0;
overflow-x: auto;
position: relative;
li {
padding: 8px 16px;
white-space: nowrap;
&:not(:last-child) {
border-inline-end: 1px solid black;
}
}
}
.edge {
padding: 8px;
white-space: nowrap;
}
.right {
justify-self: end;
}
<nav>
<div class="box edge left">
<h3 class="title">Super Cool App</h3>
</div>
<div class="box centre">
<div class="scroll-container">
<ul class="links">
<li>First Link Item</li>
<li>Second Link Item</li>
<li>Third Link Item</li>
<li>Fourth Link Item</li>
<li>Fifth Link Item</li>
<li>Sixth Link Item</li>
<li>Seventh Link Item</li>
<li>Eighth Link Item</li>
<li>Ninth Link Item</li>
<li>Tenth Link Item</li>
</ul>
</div>
</div>
<div class="box edge right">
<button>X</button>
</div>
</nav>
nav {
display: grid;
grid-template-columns: 1fr 5fr 1fr;
background: green;
align-items: center;
overflow: hidden;
}
.box {
box-sizing: border-box;
overflow: hidden;
}
.scroll-container {
position: relative;
}
ul {
display: flex;
border: 1px solid black;
border-radius: 4px;
list-style: none;
padding: 0;
overflow-x: auto;
position: relative;
li {
padding: 8px 16px;
white-space: nowrap;
&:not(:last-child) {
border-inline-end: 1px solid black;
}
}
}
.edge {
padding: 8px;
white-space: nowrap;
}
.right {
justify-self: end;
}
<nav>
<div class="box edge left">
<h3 class="title">Super Cool App</h3>
</div>
<div class="box centre">
<div class="scroll-container">
<ul class="links">
<li>First Link Item</li>
<li>Second Link Item</li>
<li>Third Link Item</li>
<li>Fourth Link Item</li>
<li>Fifth Link Item</li>
<li>Sixth Link Item</li>
<li>Seventh Link Item</li>
<li>Eighth Link Item</li>
<li>Ninth Link Item</li>
<li>Tenth Link Item</li>
</ul>
</div>
</div>
<div class="box edge right">
<button>X</button>
</div>
</nav>
There may be other syntax to achieve similar results like getting col-span involved etc but these are basically you options to logically build your grid.