You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[selectors-4] Grid-structural selectors like :nth-col(): having pseudo-classes for rows e.g. :nth-row() is needed for CSS to cope with tables and rowSpan
#8352
Open
DavidJCobb opened this issue
Jan 23, 2023
· 5 comments
The current Selectors 4 draft introduces the :nth-col() and :nth-last-col() selectors, as a way to select grid elements (including table cells) that exist within a given column. However, no similar pseudo-classes exist for rows. The draft justifies this on the grounds that tables and similar grid structures are typically row-major; however, that doesn't account for things like the rowSpan attribute on table cells.
Consider the following table:
<table><tbody><tr><tdrowSpan="2"> A </td><td> B </td></tr><tr><td> C </td></tr></tbody></table><!-- layout: A B A C-->
In this scenario, there is no way to tell that the "A" cell extends to the bottom of the table. Tables are row-major, but we can only tell what row "A" starts in; there's no way to tell what row it ends in. This causes a few problems:
Setting a border-radius on a table will round off the table's corners, but not the corners of its corner cells; the cells remain rectangular and are drawn overtop the table's rounded corners. To give a table proper rounded corners, we must set border-top-left-radius and friends on the top-left, top-right, bottom-left, and bottom-right cells. However, we can't reliably identify the bottom-left cell in the above table using selectors alone.
Setting border-collapse on a table will prevent you from using border-radius, and may additionally prevent other effects that rely on separated borders to work. In order to work around this, you have to leave the borders separated, and then emulate border-collapse by selectively setting some border widths to zero in order to manually collapse those borders. However, if a cell is rowspanned from a non-bottom row down into the bottom row, you can't reliably detect this, and so you can't collapse its bottom border into the table's bottom border.
Typically, we would detect when a cell is on any edge of the table using the following selectors:
/* Top edge: */table>:is(thead,tbody,tfoot):first-child>tr:first-child>:is(td,th) {}
/* Bottom edge: */table>:is(thead,tbody,tfoot):last-child>tr:last-child>:is(td,th) {}
/* Left edge: */table>:is(thead,tbody,tfoot) >tr>:is(td,th):first-child {}
/* Right edge: */table>:is(thead,tbody,tfoot) >tr>:is(td,th):last-child {}
The selectors above fail for rowspanned cells, and for cells adjacent to them (i.e. "B" in our example above would wrongly test as a leftmost-column cell).
With the column pseudo-classes introduced in Selectors 4, I believe the syntax would now be:
/* Top edge: */table>:is(thead,tbody,tfoot):first-child>tr:first-child>:is(td,th) {}
/* Bottom edge: */table>:is(thead,tbody,tfoot):last-child>tr:last-child>:is(td,th) {}
/* Left edge: */table:is(td,th):nth-col(0) {}
/* Right edge: */table:is(td,th):nth-last-col(0) {}
This fixes the "B" case; however, the rowspanned "A" cell in our example table above still won't test as being on the bottom edge. We would need :nth-row() and :nth-last-row() counterparts in order to cope with rowSpan.
I offer a more detailed breakdown of use cases, including links to examples, in the issue I originally opened in the WHATWG HTML repo by mistake. Those examples were written before I was aware of the yet-to-be-implemented :nth-col() and :nth-last-col() selectors, but I believe they still adequately demonstrate the utility of row-based selectors.
The text was updated successfully, but these errors were encountered:
I don't know about this, because elements could have display values changing their semantic, too. Is this suppose to work only for well-formed html tables? If so, this should maybe be specified in html.
Like || and :nth-col(), row membership would be determined based on the semantics of the document language only: whether and how the elements are presented is not considered.
The current Selectors 4 draft introduces the
:nth-col()
and:nth-last-col()
selectors, as a way to select grid elements (including table cells) that exist within a given column. However, no similar pseudo-classes exist for rows. The draft justifies this on the grounds that tables and similar grid structures are typically row-major; however, that doesn't account for things like therowSpan
attribute on table cells.Consider the following table:
In this scenario, there is no way to tell that the "A" cell extends to the bottom of the table. Tables are row-major, but we can only tell what row "A" starts in; there's no way to tell what row it ends in. This causes a few problems:
border-radius
on a table will round off the table's corners, but not the corners of its corner cells; the cells remain rectangular and are drawn overtop the table's rounded corners. To give a table proper rounded corners, we must setborder-top-left-radius
and friends on the top-left, top-right, bottom-left, and bottom-right cells. However, we can't reliably identify the bottom-left cell in the above table using selectors alone.border-collapse
on a table will prevent you from usingborder-radius
, and may additionally prevent other effects that rely on separated borders to work. In order to work around this, you have to leave the borders separated, and then emulateborder-collapse
by selectively setting some border widths to zero in order to manually collapse those borders. However, if a cell is rowspanned from a non-bottom row down into the bottom row, you can't reliably detect this, and so you can't collapse its bottom border into the table's bottom border.Typically, we would detect when a cell is on any edge of the table using the following selectors:
The selectors above fail for rowspanned cells, and for cells adjacent to them (i.e. "B" in our example above would wrongly test as a leftmost-column cell).
With the column pseudo-classes introduced in Selectors 4, I believe the syntax would now be:
This fixes the "B" case; however, the rowspanned "A" cell in our example table above still won't test as being on the bottom edge. We would need
:nth-row()
and:nth-last-row()
counterparts in order to cope withrowSpan
.I offer a more detailed breakdown of use cases, including links to examples, in the issue I originally opened in the WHATWG HTML repo by mistake. Those examples were written before I was aware of the yet-to-be-implemented
:nth-col()
and:nth-last-col()
selectors, but I believe they still adequately demonstrate the utility of row-based selectors.The text was updated successfully, but these errors were encountered: