Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS grid where one column shrinks to fit content, the other fills the remaning space

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:

  1. The large block should fill all available space even if short
  2. The small blocks should fit their content
  3. The large block (usually a text label) may be a single word larger that the available space, so it should be truncated in this case
  4. The large block should not wrap if multi-word
  5. The small blocks should not wrap (though in the case of multiple buttons or icons, this can be solved by making one block per component)
  6. Support multiple rows (i.e. columns should be aligned)

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/

like image 775
Andrea Avatar asked Nov 07 '13 23:11

Andrea


People also ask

How do I make CSS grid take up my remaining space?

Just use width: 100% and height: 100% in the CSS class of the item you want to fill the grid. Join a max-width property and a max-height property if you don't want a grid item inside a grid container to grow more than some size.

What is autofill in CSS grid?

1. Auto-fill: The auto-fill property fills the rows with as many columns as it can fit. The newly added column may be empty but it will still occupy a space in the given row. It is an important property in the CSS grid that make a responsive layout without writing a media query for each grid.

How do I stop the grid from stretching?

Grid items have an initial size of min-width: auto and min-height: auto . You can override this behavior by setting grid items to min-width: 0 , min-height: 0 or overflow with any value other than visible .

How do I use Auto-fit grid in CSS?

auto-fit behavior: “make whatever columns you have fit into the available space. Expand them as much as you need to fit the row size. Empty columns must not occupy any space. Put that space to better use by expanding the filled (as in: filled with content/grid items) columns to fit the available row space.”


1 Answers

You need to use grid-template-column and set the size of column you want to shrink-to-fit as auto, and specify the size of at least one other column using 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 used for fixed layouts with longer content. See this question for more details: Why does minmax(0, 1fr) work 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.


Context: I bumped into this question recently while learning to use grid in my app. With some help from ilyaigpetrov's answer, I was able to get a shrink-to-fit column sizing to work. Their answer doesn't give much explanation though, so I thought I'd add this:

like image 186
kumarharsh Avatar answered Sep 19 '22 10:09

kumarharsh