4

I'm trying to work out whether CSS grid is capable of behaving like a table.

So if I have a long piece of "cell data" (col 2) and there's space available elsewhere in the table, I don't want it to wrap as it does in the image below:

enter image description here

What I want to achieve is something like this. Where the column with the longer piece of content grows and the other columns shrink based on the content in that column.

enter image description here

I've uploaded an example here on CodePen: https://codepen.io/anon/pen/WdNJdY

.wrapper {
  display: grid;
  grid-template-columns: 33.33% 33.33% 33.33%;
  background-color: #fff;
  color: #444;
  max-width: 800px;
}

.box {
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
}
<div class="wrapper">
  <div class="box a">col 1</div>
  <div class="box b">col 2</div>
  <div class="box c">col 3</div>
  <div class="box d">short data</div>
  <div class="box e">a really long piece of data</div>
  <div class="box f">short data</div>
</div>

I'm very new to CSS grid so I'm curious if this is possible.

Any help is appreciated. Thanks in advance!

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
realph
  • 4,481
  • 13
  • 49
  • 104
  • 2
    I'm just researching this for you, but one thing that may help you in general would be to replace that `33.33%` with `1fr` - this `fr` unit divides up the free space among columns that use it. `1fr 2fr` would assign 1/3 to the first column and 2/3 to the second, for instance. – Niet the Dark Absol Dec 12 '17 at 17:21
  • 3
    Just a disclaimer for future readers, if it's tabular data you should always try to fit it in an actual table. This will help search engines and screen readers. – René Dec 12 '17 at 17:32

2 Answers2

3

Instead of setting your columns to 33%...

.wrapper {
  display: grid;
  grid-template-columns: 33.33% 33.33% 33.33%;
}

... which sets a fixed width, have each column use available space:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Then, prevent your text from wrapping:

.box { white-space: nowrap; }

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background-color: #fff;
  color: #444;
  max-width: 800px;
}

.box {
  white-space: nowrap;
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
}
<div class="wrapper">
  <div class="box a">col 1</div>
  <div class="box b">col 2</div>
  <div class="box c">col 3</div>
  <div class="box d">short data</div>
  <div class="box e">a really long piece of data</div>
  <div class="box f">short data</div>
</div>

More details here: The difference between percentage and fr units in CSS Grid Layout

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • I'm fairly sure that will still force the columns to be the same width as each other... I'm not too familiar with grid, so I could be wrong - specifically if `fr` calculation is done after laying out the content then this would indeed work. – Niet the Dark Absol Dec 12 '17 at 17:25
  • At a certain amount of text, the grid will exceed the width of the wrapper. Is there a way to give that second column a max value that it can be... and then force it to wrap? – sol Dec 12 '17 at 17:29
  • White-space nowrap might work in some situations, but it's not the same as table-cell or flex-grow where extra space is only gained where other elements allow it. – René Dec 12 '17 at 17:30
  • @NiettheDarkAbsol, see the snippet I posted. In FF you can highlight the grid in dev tools (see the bottom of my answer [here](https://stackoverflow.com/a/45200955/3597276)). You can then see the column widths clearly. – Michael Benjamin Dec 12 '17 at 17:32
  • 1
    @sol, try something like this: `grid-template-columns: 1fr minmax(100px, 300px) 1fr`. https://codepen.io/anon/pen/mpdKeG – Michael Benjamin Dec 12 '17 at 17:35
  • @Michael_B A bit of a follow-up question. But what if d, e, and f were in a div. Is there a way around this? ```
    ```
    – realph Dec 18 '17 at 17:08
  • Hi @realph, can you post a demo (or a new question) with all the details? Thanks. – Michael Benjamin Dec 18 '17 at 17:14
  • 1
    @Michael_B New q here: https://stackoverflow.com/questions/47873687/create-a-table-with-css-grid Thanks! – realph Dec 18 '17 at 17:40
2

The answer turned out to be pretty simple when I stopped thinking about it. The question answered itself, you can use auto as col width instead of percentages or fractions.

Try grid-template-columns: repeat(3, auto);

See: https://codepen.io/anon/pen/baGKYb (tested in chrome)

Oh grid, is there anything you can't do?

René
  • 6,006
  • 3
  • 22
  • 40
  • If all columns can be content-width, then your answer works. But if all columns should have the same width, except for the ones with longer text, then your answer doesn't work and fraction units come in handy. – Michael Benjamin Dec 12 '17 at 18:33
  • With regard to your question, maybe you can figure these out: – Michael Benjamin Dec 12 '17 at 18:34
  • @Michael_B In this specific question other columns are allowed to shrink without specifying that the other columns are the same. Asking that seems unreasonable since every column can have either longer or shorter text. You can, if needed, use `minmax(300px, auto)` or similar. Also, you can still set 1 column to auto if you know your data. – René Dec 12 '17 at 18:46
  • I think the desired size of the short-text columns is not entirely clear from the question. But I get your point. – Michael Benjamin Dec 12 '17 at 18:50
  • In regards to your linked questions, I guess it turns out grid can't do all. Although the huge-span-hack in the 2nd question seems to work in the latest firefox(of course it's not ideal but makes sense that it works as long as you don't define a fixed heights to remaining rows). For the first question, if it wasn't just theoretical, you probably already have some non-grid solution or hackfix with js. – René Dec 12 '17 at 20:02
  • In the "last row" question, the huge-span-hack is very risky and something I would never use in production. In the question about wrapping, you're right, the real-world solution is to use flexbox. – Michael Benjamin Dec 12 '17 at 20:05
  • 1
    I agree. Regular production sites should only use anything as intended by the spec so that you can blame the browser if something breaks after an update ;) Only in case of old tricks you can use those but that doesn't really apply to anything css3.(haven't used grid on any production site yet.. need to understand all the quirks and bugs first) – René Dec 12 '17 at 20:17