Hacker News new | past | comments | ask | show | jobs | submit login
Styling Tables the Modern CSS Way (piccalil.li)
76 points by speckx 45 days ago | hide | past | favorite | 31 comments



Alright, shameless plug. I spend a ton of time trying to style this table of city data I had as nicely as I could. Getting CSS tables to not overflow in containers is a nightmare. I had to use a bit of Javascript to get the scroll shadows working using Intersection Observers.

I like HTML tables but getting them to do what you want can really be tricky.

Check out my table: https://caldwell.org/projects/data/city-index


HTML tables don't necessarily make this easy but but when you have numbers as tabular data, the "subcolumns" should line up when numbers have the same meaning. So if the number 17,000 is directly above 9,000, the 9 and 7 should be in same horizontal space.

A lot of fonts include tabular number variants (or just use them by default) which also makes them visually line up when you get this part correct. Not necessary but keeps the look cleaner, a real concern with dense numeric tables.

I got everything I know & believe about formatting data from edward tufte who has basically spent his entire career thinking and writing about it. But a really solid usable summary of this specific thing is on matthew butt­erick's site. https://practicaltypography.com/grids-of-numbers.html


This is quite good, so as a fellow frontend person I'll give some deeper notes, including accessibility.

1. There is perceptible lag when sorting.

2. Sortable headers are interactive yet are `div` elements: they can't be focused or used by screen readers. Instead, change them to `<button type="button>` elements and ensure `:focus` styles look OK.

3. When the table's sorted, consider applying an `aria-sort` attribute to the `th`. This informs a screen reader what order things are in.

4. As a sibling mentioned, consider text-aligning numbers to the right. It makes visual comparison of numbers with differing digit counts easier (with a similar aim, some pair this with, `font-variant-numeric: tabular-nums`)

5. On my small phone, the two stickied columns take up 50% of the screen. May not be worth the squeeze (perhaps just sticky the rank at tiny viewports?).

6. Also on my small phone, the horizontal shadows occlude all the content, making it hard to read.

7. I don't personally love the "click to select a row" feature. I double click to select text as I read it, or to copy, and that distractingly toggles the color on and off. Perhaps this makes more sense when there are actions that can be performed on a selected row?

8. Speaking of, clicking the rank cells do not select the row.

For an example on the a11y work, I'd recommend checking out WAI-ARIA's Sortable Table: https://www.w3.org/WAI/ARIA/apg/patterns/table/examples/sort...

These are pretty small asides; kudos overall.


This is literally the smoothest, most fluid table scrolling I’ve ever seen on the web (Mobile Safari). The scaling to viewport bounds, the shadow hinting at additional content… this is almost distractingly good.

Is this all one-off code, or have you packaged it for broader use?


> Getting CSS tables to not overflow in containers is a nightmare.

Is this because the total width/height consumed by a <table> isn't as simple as the normal content/padding/border/margin model?

That table you've created is lovely, nice work!


> CSS tables > HTML tables

may i assume that you mean the same thing?

> I had to use a bit of Javascript to get the scroll shadows working using Intersection Observers.

everybody that is not a frontender: please don't


A nasty problem I've seen with overflow:auto on a table inside a container is that Windows mouse users have to scroll to the bottom of the page in order to find the horizontal scrollbar and use it to scroll around the table. This is a bad UX, but I've not yet found a good solution for it.

(Trackpad users can use a gesture instead.)

The closest I've come to a solution is using JavaScript to try and mirror the bottom scrollbar at the top of the table as well, but it's pretty cludgy and hard to implement well.


A solution I've used is to limit the number of table rows displayed to fit vertically within the browser viewport. This way the horizontal scrollbar at the bottom of the table is always visible without having to scroll vertically.

This does require:

0. Pagination.

1. Each table row must have the same height.

2. Use of javascript to calculate the max number of rows that will fit vertically in the viewport (and don't forget to include the height of the table header and pagination buttons in the calculation).

3. Send ajax request with row limit to server to retrieve and render the data.

You can see an example here: https://wee.domains


Not that's its a commonly used but can't you middle mouse click and scroll around? And shift or alt (which I have actually forgotten) mouse wheel as well.


Those do work, but I don't think most people know about them. Also, I think the middle mouse click scrolling ("autoscrolling") is disabled by default in firefox, potentially in chrome too.


It doesn't appear to be disabled by default in Firefox on Windows for me, I use it all the time.

You are correct though, that a lot of users never discover it.


On Windows you can Shift+Scroll to scroll horizontally, so getting the scrollbar into the viewport is not necessary (if it's obvious that the container scrolls that way).


It irks me when tutorials recommend the use of logical properties for stuff that will never be translated. The direction-agnostic properties are longer and harder to understand with the only upside being that you’ll have less work when you ship traditional Mongolian as a language option.


I learnt a few things from that and I have been writing HTML and tables since before they were famous! B^>


> Whatever you do, don’t be tempted to change the table’s display property value to grid, just to make styling easier. You’ll break the baked-in accessibility that browsers provide for free, rendering your table inaccessible to users of assistive technologies.

Is this accurate? The accessibility for things like screen readers comes from the HTML tags, not CSS afaik.


From MDN[1]:

> In some browsers, changing the display value of a <table> element to block, grid, or flex will alter its representation in the accessibility tree. This will cause the table to no longer be announced properly by screen reading technology.

1. <https://developer.mozilla.org/en-US/docs/Web/CSS/display#tab...>


I'm sure there are Very Important Reasons but seems like a poor design. Maybe "display: none" makes some sense, but the rest are visual.


CSS can impact screen reader accessibility. Most obviously ‘display: none’ will remove the element from the outline

From a quick google it appears the article is correct: https://www.tpgi.com/short-note-on-what-css-display-properti...

You can return the structure with judicious use of role attributes, but it’s surely easier to just keep a table a table.


This reminded me of a web dev competition's task I saw once where the instructions said both "Always use semantic HTML for proper accessibility" and "In this exercise, you must create the table using grid and flexbox".

I thought that was weird, but now I think you might be right - if you use <table> and add display: grid to it then it might preserve the default role="row" and similar accessibility things.


border-block (and border-inline) are new ones for me!

Also it might be worth mentioning position sticky on table rows/sections don't work yet in Firefox unfortunately :( but hopefully soon...


Works for me.


What I want in html:

text-align:number

<td unit="mm">

<th name="temprature">Mean temperature change (°C)</th>

t = myTable.data.Australia.temprature

(if the header name is just a single word use that)

myTable.data.Australia.temprature = t

<th sort="nummeric">

table{ auto-rowspan:5; } if the nth cell of up to 5 rows has the same value make them into one large cell.


It's ironic I have to say. The "sticky" CSS property should only be used for table headers. Yet it is never used anywhere for tables, but instead misused on almost every website for navigation and clutter.


Sticky text headers are cool too, as long as your text isn't divided in too many levels.

I'm sure there are other good use cases. The fact that almost every site out there makes a point of using it on the worst possible way doesn't justify the "should only be used for table headers", even though, yeah, your sentiment is correct.


When it comes to standard text and image content, I'm against scrolling and pro pagination. There is a reason why text scrolls were replaced by books about 700 years ago. We have the technique today to dynamically reflow content to enable pagination. It would be a much improved user experience on all devices, including computers and phones.


What’s the correct way to do sticky nav? Assume we’re skipping the arguments about whether sticky nav just shouldn’t exist.


That was my only argument.

I think the step forward is to let website navigation become part of the browser chrome. There's space for a menu item for the website, or a dedicated button.

Maybe even on-site search could become part of the browser chrome?


We should break the clean separation between browser chrome and websites, a crucial component of the current web's UX and trust model, just to resolve a newly invented problem of arbitrarily avoiding always-accessible sticky navs?


You didn't understand and jumped straight into hacker mode. It's not really about sticky headers, it's about accessibility and serving users. Any implementation would need to take security into consideration.

This kind of integration would also be an improvement for web apps.


Can you cite any reputable source where it is claimed that `position:sticky` should only be used for table headers?


Yes, for example Cicero wrote this in his letter to Quintus.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: