Safari, CSS Grid, Tables, and Quirks Mode

Or, How I spent 2 hours arguing with myself over Safari
profile photo
Ryan Duffy
Over at replay.io, we’re creating a new way to understand your software and fix bugs by recording the execution so you can play it back, debug it, and share it with others. Once you try it, you’ll create a bunch of recordings and so you’ll need a Library view to manage them.
Good news: We created one!
Bad news: It didn’t render correctly in Safari
Image without caption
An HTML table using CSS Grid in Safari in quirks mode
HTML Tables are (now and forever) a great way to render tabular data on the web. They’re more accessible than <div> soup and provide basic formatting out of the box. They can be challenging to style but that story has improved with CSS Grid. After running into the issue above, we discovered we were missing an important piece required for them to render as expected in Safari.

Styling Tables with CSS Grid

Converting a <table> from using its native layout (display: table) to use CSS Grid (display: grid) is pretty straightforward. The trick is excluding <thead><tbody>, and <tr> from the grid using display: contents which leaves only <th> and <td> elements to be laid out in the grid.
plain text
table { display: grid; grid-template-columns: repeat(5, 1fr); }thead, tbody, tr { display: contents; }

Safari and Quirks Mode

Turns out it there was one more trick for Safari and the codepen above was the first hint to the solution (though it took me a little while to realize it).
The Library view is a pretty typical React component and its CSS is similar to that of the codepen so it wasn’t immediately obvious to me why all of the <th> elements were lined up vertically and all the <td> element were lined up horizontally rather than as a nice table.
I spent quite a bit of time trying to track down what was happening:
  1. Removing all the grid styles from the table allowed it to render as a native table so the markup was probably okay.
  1. Selectively disabling various style rules up the component tree didn’t seem to fix it.
  1. Removing other components in the React tree until just the table was rendered didn’t fix it.
  1. Copying the rendered HTML of the table and replacing the root app node with it didn’t fix it.
Finally, I created a bare test.html with the HTML and CSS from the codepen and served it up with serve. Lo and behold … it still didn’t work …
And then I looked at the source of both the codepen and the test file and noticed a small difference:
Image without caption
Comparing the test file and codepen source code
The codepen included <!DOCTYPE html> but my test file did not. The application’s index.html did not include it either.
After a couple hours of debugging, I discovered that Safari handles this scenario differently than Chrome and Firefox when in Quirks Mode. Adding the <!DOCTYPE html> instruction switches it over to standards mode and everything rendered correctly!
Image without caption
Fixed table with CSS Grid in Safari

And now, the fallout

While switching to standards mode fixed the table layout, it also broke a few other layouts in all the browsers. I won’t go into them all here but if you make this change to switch to standards mode, beware! Here be dragons!
Related posts
post image
In this failure, we look into a bug where a React component calls Math.round and gets a different value when the test passes and fails!
post image
This week we’re excited to share Elements Panel V3, which brings one second element loads.
post image
Today we’re excited to share an entirely new version of React DevTools which Brian Vaughn wrote from scratch.
Powered by Notaku