#TIL: Display table and inline are incompatible with container queries

I had a table in a web component and needed to hide some unimportant columns on small widths. If you’re curious, this is how you’d hide the second and third columns in a table (for both table headings and normal cells): :is(th, td):is(:nth-child(2), :nth-child(3)) { display: none; } And this is how I tried to use container queries to only do that in narrow places (less than 600px in this case): table { /* ! this part doesn’t actually work */ container-type: inline-size; } /* hide 2nd and 3rd columns when small */ :is(td, th):is(:nth-child(2), :nth-child(3)) { @container (width

Jan 23, 2025 - 01:42
 0
#TIL: Display table and inline are incompatible with container queries

I had a table in a web component and needed to hide some unimportant columns on small widths.

If you’re curious, this is how you’d hide the second and third columns in a table (for both table headings and normal cells):

:is(th, td):is(:nth-child(2), :nth-child(3)) {
    display: none;
}

And this is how I tried to use container queries to only do that in narrow places (less than 600px in this case):

table { /* ! this part doesn’t actually work */
  container-type: inline-size;
}

/* hide 2nd and 3rd columns when small */
:is(td, th):is(:nth-child(2), :nth-child(3)) {
  @container (width < 600px) {
    display: none;
  }
}

The problem was that these are the only display values actually compatible with container queries:

  • block
  • inline-block
  • flex
  • inline-flex
  • grid
  • inline-grid
  • flow-root

Among the ones that are not are some that make sense:

  • inline

Some that are obvious:

  • contents
  • none

A few I’ve never used:

  • ruby
  • ruby-base
  • ruby-text
  • ruby-base-container
  • ruby-text-container

And all of the table ones:

  • table
  • table-row-group
  • table-header-group
  • table-footer-group
  • table-row
  • table-cell
  • table-column-group
  • table-column
  • table-caption

I had never considered this.

The solution is to put the container on the parent element of the table, and the reason I mentioned at the start that this was inside a web component (which is the table’s direct parent) is that web components are, by default, display: inline.

But, unlike with a table, there’s no problem changing a component’s display to block.

This works (and doesn’t break any of the table’s semantics):

:host {
  container-type: inline-size;
  display: block;
}

/* hide 2nd and 3rd columns when small */
:is(td,th):is(:nth-child(2),:nth-child(3)) {
  @container (width < 600px) {
    display: none;
  }
}

I’m using :host as the selector above, because I’m doing it from inside the Shadow DOM (and the scope of container queries is limited to the shadow DOM bound), but you can use your component’s hyphenated tag name if you’re using Light DOM.

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow