I need to create a horizontal layout where one block takes all available space and the other ones shrink to fit their content.
For example:
<div class="grid">
<div class="expand">Long text label</div>
<div class="shrink">Button</div>
</div>
A more complex example with two rows (an actual grid):
<div class="grid">
<div class="row">
<div class="shrink">...</div>
<div class="expand">...</div>
<div class="shrink">...</div>
<div class="shrink">...</div>
</div>
<div class="row">
<div class="shrink">...</div>
<div class="expand">...</div>
<div class="shrink">...</div>
<div class="shrink">...</div>
</div>
</div>
My requirements:
I am targeting Android and iOS smartphones.
I have tried to adapt the code from this answer but I could not make it work for multiple rows. Also, the source code must be out of order, which is confusing (though not blocking for my use case). Here's a jsfiddle: http://jsfiddle.net/k3W8L/
I bumped into this question recently while learning to use grid in my app. With the ilyaigpetrov's answer's help, I was able to get an shrink-to-fit column sizing to work. Although the answer doesn't give much explanation, so I thought I'd add this:
What you need to do is use grid-template-column
and set the size of column you want to shrink-to-fit as auto
, and at least one other column in the fr
unit.
Example: To recreate the sidebar-content layout, where the sidebar is collapsible,
-------------------------------
| Sidebar | Content |
-------------------------------
you can create the grid as:
.grid {
display: grid;
...
grid-template-columns: auto minmax(0, 1fr); // see note below
grid-template-areas: "sidebar content";
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
See the codepen here for a demo & code: https://codepen.io/khs/pen/vegPBL You can click on the navbar to see auto-sizing in action.
Note: One thing I've learnt since writing this answer is that in most cases, and especially in a fixed-height/fixed-width layout, you should use minmax(0, 1fr)
instead of 1fr
. The reason is that 1fr
is actually a shorthand for minmax(auto, 1fr)
. This breaks when fixed layouts with longer content. See this question for more details: How come minmax(0, 1fr) works for long elements while 1fr doesn't?
Hence I've updated my answer to reflect the fact. The minmax
might be a little verbose, but it's almost always what you want for this kind of layout.