There was a fun little trend toward the end of last year where companies were posting their approach to CSS. The tools involved, the methodologies, the thinking, and the data and numbers behind it. Mark Otto kicked it off, best I can tell. I mostly just wanted to post a list of them here, since that’s perfect fodder for CSS-Tricks. I ended up slapping it into a table with a few bits of data that are easy to compare, just for fun.
Company:
Github
Preprocessor:
SCSS
Prefixing:
Custom @mixins
# Source files:
100+
# Selectors:
7,000
Style enforcement:
SCSS-lint, styleguide
Notes:
2 final stylesheets, because of IE selector limit
Company:
Buffer
Preprocessor:
LESS
Prefixing:
Autoprefixer
# Source files:
93
# Selectors:
5328
Style enforcement:
LESS lint
Notes:
2 final stylesheets
Company:
CodePen
Preprocessor:
SCSS
Prefixing:
Autoprefixer
# Source files:
171
# Selectors:
1186
Style enforcement:
.editorconfig
Notes:
Asset pipeline
Company:
Ghost
Preprocessor:
SCSS (libsass)
Prefixing:
Autoprefixer
# Source files:
36
# Selectors:
1609
Style enforcement:
General guidelines
Notes:
Open source
Company:
Groupon
Preprocessor:
Sass (syntax unclear)
Prefixing:
Compass
# Source files:
?
# Selectors:
?
Style enforcement:
SMACSS
Notes:
Toolstrap
Company:
Lonely Planet
Preprocessor:
Sass
Prefixing:
Autoprefixer
# Source files:
150+
# Selectors:
1527
Style enforcement:
Rizzo, no linting
Notes:
BEM / OOCSS, Normalize.css, SVG icons
Company:
Medium
Preprocessor:
LESS
Prefixing:
Custom @mixins
# Source files:
50-100
# Selectors:
?
Style enforcement:
Guidelines
Notes:
No nesting, custom methodology for naming
Company:
Trello
Preprocessor:
LESS
Prefixing:
Custom @mixins
# Source files:
44
# Selectors:
2,426
Style enforcement:
Preprocessor
Notes:
1 final stylesheet, namespacing
Another really common theme: .js-
class prefixes for not mixing JavaScript hooks and styling hooks.
Also I tried to make that table responsive…
I wanted it to:
- Be a normal-looking table when there is room.
- Collapse down to blocks on small screens.
- Still work with no CSS whatsoever (emails, rss)
Here’s the results:

The root of the concept was the start with “normal” HTML elements (section, div, p, span) and force them to be a table. I named things a bit differently, but you could just use helper classes:
.table { display: table }
.tr { display: table-row }
.thead { display: table-header-group }
.tbody { display: table-row-group }
.tfoot { display: table-footer-group }
.col { display: table-column }
.colgroup { display: table-column-group }
.td, .th { display: table-cell }
.caption { display: table-caption }
Then at a certain media query, you force them back to their normal state:
@media (max-width: 700px) {
.table { display: block }
.tr { display: block }
.thead { display: block }
.tbody { display: block }
.tfoot { display: block }
.col { display: none }
.colgroup { display: none }
.td, .th { display: inline-block }
.caption { display: block }
}
But all that gets you is really weird looking sentences, so I mixed in a bunch of <br>
tags to space things out as needed, that are hidden with CSS. I also used a <span>
to title each cell, also hidden with CSS, so that if there is no CSS, you see that title for each bit of data.
It’s redundant and messy. Made worse by needing to put it into WordPress, where the auto-p behavior adds extra paragraphs you have to be careful about. I just did the whole thing in a Pen, then compressed the HTML here.
For every case I’ve had to use responsive tables, I usually make them with some entirely different elements. It’s a really nice approach you had taken here. You may want to isolate this as a post on styling responsive tables
Ya I’ve done the exact same thing. Putting two elements on a page and hiding/showing them as required isn’t a show-stopper for me.
I can’t see many situations where it would be anyways… because if you are displaying a table that is so large that it hinders page rendering you miiiight wanna rethink how you load your data anyways. Maybe there is more bad times because of this approach than I realize but I’ve yet to hear anger from users about it.
I just viewed the source of the page and I realized this wasn’t done with table elements as well.
I’m curious to know why you used “normal” elements (section, div, p, span) and forced them to act like a table at a certain breakpoint? Since this is tabular data, wouldn’t a table element makes sense? You can use the same media query to set the thead, tbody, th, td, tr elements as block for smaller screens.
I realize it’s the same result, but
<span class="th">
seems a little nutty to me. :)I have to second this…I think using the appropriate semantic element in this case would be the better approach…and then use CSS or JSS to change the content layout for smaller devices…
I prefer the
<table>
-first approach as well in general. But see the third bullet point. It has to work without an CSS at all. A table still “works”, but there is a 100% chance that it would smurf up the formatting of the email that happens from this blog post. And who knows what will come through people’s RSS readers. This was just a challenge to myself to start with HTML that will be totally resilient to those situations, yet have the format I want on my own site for the standard desktop user.+1 for an article on styling responsive tables (if there already isn’t one). This is something I have been dealing with a bit lately, trying to communicate lots of data in a responsive layout, and the result wasn’t too dissimilar to what you have there. Except I used an actual
<table>
after all it is tabular data displayed as a table.Chris the “table” came out a little nonsensical in Feedly’s presentation of the feed.
Bummer. Screenshot?
Chris, here is a screenshot [tinypic] of the Feedly table rendering.
That’s just what I was hoping for! Spaced out, readable, doesn’t break layout.
Feedly on desktop as well.
Relevant screenshot: http://i.imgur.com/4O1tCEQ.png
I enjoyed reading these posts so much so that I collected them in a GitHub repo. Looks like I missed the Ghost post. I think there’s a few on my list that you are missing as well. Cheers..
Thanks @chriscoyier for this comment about why you used native blocks/inline-block elements.
I was about to say that I prefer to use
<
table> in this case.
Finally, I feel you’re right about emails. I even didn’t think about the RSS…
This is the mobile-first approach, here.
The extra CSS is usefull only on large screen, which is good because we don’t want to overload website size with low bandwidth networks.
I also suggest you this CSS survey that @LeaVerou pointed out on twitter : https://twitter.com/LeaVerou/status/555859362670202880
Bit of a mashup of a post, but really good information about the various CSS approaches.
This may be a dumb question, but what does it mean when you say “final stylesheets.” Googling that term didn’t turn up anything that seemed relevant.
It means that in the end, after all the preprocessing, they end up with one or two final css files, github splits theirs in two files because IE has a selector limit.
And that’s about it, since most of those use less or sass they split their styling in different relevant files, to add some structure.
Thanks Rodrigo – that makes sense. I guess I was over-analyzing that phrase.
Hey Chris! Nice list there, and great-looking table. I do my best to avoid all tables these days, they’re such a pain.
And by the way, I wrote about CSS structure as well (for Noodles) :)
I do not understand the use of
<br>
in the responsibe table. Could you elaborate?Br tags are used to have manual line breaks between words.
Buzzfeed made an article too: http://www.buzzfeed.com/erakor/i-am-all-about-that-sass#.yqq2Dxwne (:
Really neat experiment with the html tables! I’ve always wanted a table system that was dynamic and could fit and be read easily on small screens, and this is what I’ve been looking for! My problem is that my site currently uses a outdated system for styling content for all screen sizes. I’ve been using @media only screen for styling content for smaller screens, when I should use that to lay base styles that have nothing to do with width and whatnot, and using media queries for changing layout and size. Your CSS has made me understand my error, so thank you Chris.
Hi there! Why is it impossible to count selectors in some companies?
Friendly manual trackback: http://meiert.com/en/blog/20150122/deterioration-of-practices/.
The no-css-requirement is a bummer, there are such nice possibilities with
:after
andattr()
that may reduce the need for many such things.For pure html, I would perhaps make it into a bit more semantical like
per cell, and then hide all dt’s in the table display (except the top row of course). That might help to get rid of the breaks and extra classes I think, and would format nicely without css.
With my tables, I ran into some ordering problems (not wanting the leftmost column appearing first in responsive ofr example.) And I still don’t know if an item (row) in such a list should be marked as
<article>
or<section>
or<div>
.Btw, interesting aggregation of css workflows.