col – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Tue, 10 Jan 2023 15:11:24 +0000 en-US hourly 1 https://wordpress.org/?v=6.2.2 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 col – CSS-Tricks https://css-tricks.com 32 32 45537868 Faking Min Width on a Table Column https://css-tricks.com/faking-min-width-on-a-table-column/ https://css-tricks.com/faking-min-width-on-a-table-column/#comments Tue, 10 Jan 2023 15:11:20 +0000 https://css-tricks.com/?p=376307 The good ol’ <table> tag is the most semantic HTML for showing tabular data. But I find it very hard to control how the table is presented, particularly column widths in a dynamic environment where you might not know how …


Faking Min Width on a Table Column originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The good ol’ <table> tag is the most semantic HTML for showing tabular data. But I find it very hard to control how the table is presented, particularly column widths in a dynamic environment where you might not know how much content is going into each table cell. In some cases, one column is super wide while others are scrunched up. Other times, we get equal widths, but at the expense of a column that contains more content and needs more space.

But I found a CSS tricks-y workaround that helps make things a little easier. That’s what I want to show you in this post.

The problem

First we need to understand how layout is handled by the browser. We have the table-layout property in CSS to define how a table should distribute the width for each table column. It takes one of two values:

  • auto (default)
  • fixed

Let us start with a table without defining any widths on its columns. In other words, we will let the browser decide how much width to give each column by applying table-layout: auto on it in CSS. As you will notice, the browser does its best with the algorithm it has to divide the full available width between each column.

If we swap out an auto table layout with table-layout: fixed, then the browser will merely divide the full available space by the total number of columns, then apply that value as the width for each column:

But what if we want to control the widths of our columns? We have the <colgroup> element to help! It consists of individual <col> elements we can use to specify the exact width we need for each column. Let’s see how that works in with table-layout: auto:

I have inlined the styles for the sake of illustration.

The browser is not respecting the inline widths since they exceed the amount of available table space when added up. As a result, the table steals space from the columns so that all of the columns are visible. This is perfectly fine default behavior.

How does <colgroup> work with table-layout: fixed. Let’s find out:

This doesn’t look good at all. We need the column with a bunch of content in it to flex a little while maintaining a fixed width for the rest of the columns. A fixed table-layout value respects the width — but so much so that it eats up the space of the column that needs the most space… which is a no-go for us.

This could easily be solved if only we could set a min-width on the column instead of a width. That way, the column would say, “I can give all of you some of my width until we reach this minimum value.“ Then the table would simply overflow its container and give the user a horizontal scroll to display the rest of the table. But unfortunately, min-width on table columns are not respected by the <col> element.

The solution

The solution is to fake a min-width and we need to be a bit creative to do it.

We can add an empty <col> as the second column for our <colgroup> in the HTML and apply a colspan attribute on the first column so that the first column takes up the space for both columns:


<table>
  <colgroup>
    <col class="col-200" />
    <col />
    <col class="col-input" />
    <col class="col-date" />
    <col class="col-edit" />
  </colgroup>
  
  <thead>
    <tr>
      <th colspan="2">Project name</th>
      <th>Amount</th>
      <th>Date</th>
      <th>Edit</th>
    </tr>
  </thead>
  
  <!-- etc. -->
</table>

Note that I have added classes in place of the inline styles from the previous example. The same idea still applies: we’re applying widths to each column.

The trick is that relationship between the first <col> and the empty second <col>. If we apply a width to the first <col> (it’s 200px in the snippet above), then the second column will be eaten up when the fixed table layout divides up the available space to distribute to the columns. But the width of the first column (200px) is respected and remains in place.

Voilà! We have a faux min-width set on a table cell. The first cell flexes as the available space changes and the table overflows for horizontal scrolling just as we hoped it would.

(I added a little sticky positioning to the first column there.)

Accessibility

Let’s not totally forget about accessibility here. I ran the table through NVDA on Windows and VoiceOver on macOS and found that all five columns are announced, even if we’re only using four of them. And when the first column is in focus, it announces, “Column one through two”. Not perfectly elegant but also not going to cause someone to get lost. I imagine we could throw an aria-hidden attribute on the unused column, but also know ARIA isn’t a substitute for poor HTML.


I’ll admit, this feels a little, um, hacky. But it does work! Let me know if you have a different approach in the comments… or know of any confusions this “hack” might bring to our users.


Faking Min Width on a Table Column originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/faking-min-width-on-a-table-column/feed/ 5 376307
Preventing a Grid Blowout https://css-tricks.com/preventing-a-grid-blowout/ https://css-tricks.com/preventing-a-grid-blowout/#comments Mon, 01 Oct 2018 21:17:51 +0000 http://css-tricks.com/?p=276814 Say you have a very simple CSS grid layout with one column fixed at 300px and another taking up the rest of the space at 1fr.

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

That’s somewhat robust. That 1fr


Preventing a Grid Blowout originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Say you have a very simple CSS grid layout with one column fixed at 300px and another taking up the rest of the space at 1fr.

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

That’s somewhat robust. That 1fr column will take up any remaining space left behind by the fixed 300px column. It’s true that the auto value would do the same, but auto isn’t quite as robust since it’s size is based on the content inside. So, if you had too little content, then your column might not fill the entire space you want it to. But while 1fr is slightly more robust, it won’t quite protect you from content that is too big!

Here’s the grid behaving just fine with some text content:

Now, watch that right column get blown off the page when we drop a gigantic image in that column:

That one is easy to fix — and you may never even have it happen to you, because this snippet is so common in our stylesheets:

img {
  max-width: 100%;
}

But some elements aren’t so friendly. Take the notorious <pre> tag. Say we toss one of those in our 1fr column with a long string of text. We’re back to wrecked:

This time, things aren’t so easily fixed! Even attempting to limit the width and hide the overflow of <pre> isn’t going to help:

pre {
  max-width: 100%;
  overflow: hidden;
}

The real fix isn’t all that difficult — we only need to understand what is happening. I can’t promise I’m explaining this 100% accurately, but the way I understand it, the minimum width of a grid column is auto. (The same is true for flex items, by the way.)

And since auto is entirely based on content, we can say it is “indefinitely” sized, its dimensions flex. If we were to put an explicit width on the column, like 50% or 400px, then we would say it is “definitely” sized.

To apply our fix, we need to make sure that there is the column has a definite minimum width instead of auto.

So, we can either fix it like this:

.grid {
  /* auto minimum width, causing problem */
  grid-template-columns: 1fr 300px;

  /* fix: minimum width of 0 */
  grid-template-columns: minmax(0, 1fr) 300px;
}

Or, we put an actual min-width on the element that occupies that grid column. In our simple demo, the <main> element automatically places itself in that first column as it is the first child of the grid.

That give us this:

main {
  min-width: 0;
}

I think it’s a bit more robust to do this at the grid definition level. Anyway, it does the trick! See how the <pre> tag now respects the width of the column and can overflow as expected?

Nice.


Preventing a Grid Blowout originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/preventing-a-grid-blowout/feed/ 8 276814