Even/odd row styling with CSS Grid and subgrid, is this a good idea?

For work, I needed some table styling and decided to use CSS Grid. Because I need even/odd row styling, I used subgrid. When searching online I couldn't find many solutions going this direction. I wrote a short post about it: https://appjeniksaan.nl/posts/table-row-styling-with-css-grid/
<div class="table">
<div class="row">
<div>Programming Language</div>
<div>Creator</div>
<div>First Release</div>
</div>
<div class="row">
<div>C</div>
<div>Dennis Ritchie</div>
<div>1972</div>
</div>
<!-- [...additional rows] -->
</div>
<div class="table">
<div class="row">
<div>Programming Language</div>
<div>Creator</div>
<div>First Release</div>
</div>
<div class="row">
<div>C</div>
<div>Dennis Ritchie</div>
<div>1972</div>
</div>
<!-- [...additional rows] -->
</div>
.table {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 columns of even width */
}
.row {
display: grid;
grid-template-columns: subgrid; /* Every row is a subgrid */
grid-column: 1 / -1; /* Spans from the first to the last column */
}
.row:first-of-type {
font-weight: bold;
}
.row:nth-of-type(even) {
background-color: white; /* Even rows get alternative background-color */
}
.table {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 columns of even width */
}
.row {
display: grid;
grid-template-columns: subgrid; /* Every row is a subgrid */
grid-column: 1 / -1; /* Spans from the first to the last column */
}
.row:first-of-type {
font-weight: bold;
}
.row:nth-of-type(even) {
background-color: white; /* Even rows get alternative background-color */
}
But now I am wondering, are there any disadvantages to styling it this way that I am overlooking? Or is the fact that subgrid is relatively new the reason that there aren't many descriptions for this solution? Btw, I know that this is technically already a solved problem, since the code above works. But if there are some disadvantages to it that I am overlooking, or a solution that would be even better, I would really like to know about them.
Table row styling with CSS Grid
My personal software development shop which lets me create sites and apps that I think are delightful or just fun to build
8 Replies
Jochem
Jochem10mo ago
why are you using a div styled to look like a table instead of just using a table? your example is 100% tabular data and should be represented using the <table> tag basically you're reinventing the wheel and running into issues because of that the disadvantages of this approach (using divs over tables) is that it's not as accessible and semantically meaningless despite there being a tried and true semantically correct solution
appjeniksaan
appjeniksaanOP10mo ago
The main reason is that you get full Flexbox layout support inside the CSS Grid based table. This means that you can use all the well known styling properties, while in a traditional table you have to use different properties with different limitations. With the CSS Grid based approach you also get a very flexible way of sizing columns based on their content. So one column can be max-content while 2 others have the same width based on 1fr. This is not really possible in table.
Jochem
Jochem10mo ago
I guess, but that's a very narrow use case when usually percentages do just fine this is probably going to be a nightmare for people using assistive tech though
appjeniksaan
appjeniksaanOP10mo ago
I agree that this choice should not be made without careful consideration, since keeping it standard and simple should always be your first choice. But in the situation I came up with this solution, I have other considerations to weigh as well and there the "standard" table is not really offering a solution that allows building to business requirements.
capt_uhu
capt_uhu10mo ago
genuinely curious: do the standard table tags (th, td, tr) not allow the use of display:grid; or display:flex;.
appjeniksaan
appjeniksaanOP10mo ago
I think a th or td has display: table-cell, if you override it with flex that will break the table layout. You can put an element inside the the table cell. But there are some limitations with that. The situation gets even trickier if you want to have a absolute position to a relative of the cell, I think the specifications do not describe this situation and the rendering is different between different browsers.
Kevin Powell
Kevin Powell10mo ago
You can, but it strips the semantics of it. But, it does work well. This is a really nice article on creating a responsive table, using a table: https://adrianroselli.com/2017/11/a-responsive-accessible-table.html And if you do use flex and/or grid with a table, he also has a very simple JS script to add the semantics back in: https://adrianroselli.com/2018/05/functions-to-add-aria-to-tables-and-lists.html I'm curious what the standard table wasn't able to do, that you accomplished here, because the organization of it looks like you'd expect with a table... and the issue with not using a table to organize content like this, is the DOM order doesn't make any sense. Assistive tech, as well as Google bots, will have no idea what this represents. The styling of it makes a lot of sense, and I think it's a good use of subgrid... but I'd probably make it an actual table, with that exact same styling on it (plus a few extra lines to remove the original table styling), and use Adrian's script to bring in the aria-roles to keep the original semantics.
appjeniksaan
appjeniksaanOP10mo ago
The prime reason for me to switch to this way of styling was to get flexbox sizing to the columns. Because we have a lot of columns and want to have some columns have as much space as possible, it is nice to have some min-width: max-content columns and then give the most important columns the space the need. With a traditional table I would have to introduce width calculation based on content, which I think is a bad idea. But I like the idea of resetting the style of the table elements and re-using them to keep it "standard". I will dive into those posts from Adrian Roselli, they seem really helpful, thanks. What is interesting to consider when replacing the elements, the browser will add a tbody. So then the table element could become display: block with a thead and tbody that are both display:grid. The other option is that both thead and tbody have to also be a subgrid, I first thought this might not be such a good solution, but it is very minimal. Example HTML would then be:
<table>
<thead>
<tr>
<th>Programming Language</th>
<th>Creator</th>
<th>First Release</th>
</tr>
</thead>
<tbody>
<tr>
<td>C</td>
<td>Dennis Ritchie</td>
<td>1972</td>
</tr>
<!-- [...additional rows] -->
</tbody>
</table>
<table>
<thead>
<tr>
<th>Programming Language</th>
<th>Creator</th>
<th>First Release</th>
</tr>
</thead>
<tbody>
<tr>
<td>C</td>
<td>Dennis Ritchie</td>
<td>1972</td>
</tr>
<!-- [...additional rows] -->
</tbody>
</table>
With the CSS:
table {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
thead, tbody, tr {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
}
thead tr, tbody tr:nth-of-type(even) {
background-color: white;
}
th {
font-weight: bold;
}
table {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
thead, tbody, tr {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
}
thead tr, tbody tr:nth-of-type(even) {
background-color: white;
}
th {
font-weight: bold;
}
I am going to try it together with the suggestions from Adrian Roselli and see if it works in all modern browsers or if I run into any issues.
Want results from more Discord servers?
Add your server