Hacker News new | past | comments | ask | show | jobs | submit login
WTF, HTML and CSS? (wtfhtmlcss.com)
485 points by nreece on March 24, 2014 | hide | past | favorite | 111 comments

> Internet Explorer 9 and below have a max of 4,096 selectors per stylesheet.

The reason for that is a rather cute implementation explained here:


(...and IMHO 4K selectors is a lot more than any sane page should use...)

> (...and IMHO 4K selectors is a lot more than any sane page should use...)

I don't think this is a problem with hand-coded CSS files. But since the trend nowadays is to generate CSS from a bunch of LESS or SASS files, minify the whole thing, and stuff it into a single HTTP request, it's not impossible for large and complicated apps to end up with over 4K selectors. When you're living in SASS fairyland you don't always remember that your beautifully nested rules and mixins will compile into dozens of CSS selectors.

Ran into this problem when doing some crazy silly CSS, ended up using bless[1] to fix this issue.

[1] http://blesscss.com/

I've run into this before with a large app: bootstrap + font awesome + plugins + custom css in a single blob put me well over 4096 selectors. Fortunately, bless (via grunt-bless) and a simple IE conditional comment fixed it for good. Bless is a great project.

Isn't @Import a bad idea? At least if you write multiple <link>s for css they can download in parallel. @Import will always have to wait for the first sheet to download AND Execute. Which isn't so bad with CSS but still.

You should be using a IE conditional just for bless. :)

it's not impossible for large and complicated apps to end up with over 4K selectors

Is that 4K of selectors that are all actually used, or are most of them just taking up space? If it's the former, then I can see the concern, but if it's the latter, then maybe the 4K limit is perfectly reasonable after all, and instead we should be rethinking how we generate our CSS (a quick search shows plenty of tools that will find and remove unused selectors.)

Or put another way, it's the difference between complaining about some system not having enough RAM instead of trying to rewrite your application to be more efficient so it can stay within the limits; and I think most recently there's been far too much of the former and not enough of the latter.

Sure, you could remove unused selectors, but then you'll end up with different CSS files for different pages. That's a lot of extra HTTP requests for a first-time visitor who wants to look around your website.

Whether or not the extra HTTP requests are worth the time and RAM saved by removing unused selectors will probably depend on your specific needs and priorities. For the time being, though, I suspect that modern computers take less time parsing a few thousand unused CSS selectors than the time it takes to fetch an uncached HTTP resource from a few thousand miles away. Moreover, devices with less RAM and computing power tend to be connected to even slower networks (e.g. 3-year-old phone on a 3G network).

> (...and IMHO 4K selectors is a lot more than any sane page should use...)

Open gmail, do this in the console:

As of today I see "7343". It's possible they only do that in browsers other than IE9, of course.

In any case, for large sites with site-wide stylesheets that have styles for everything on the site, it's easy to end up with thousands of rules. A simple example is github, which on the front page has this as of today:

    <link href="https://github.global.ssl.fastly.net/assets/github-b836a3967c04ec8b8bfdd101d2226064cb18f45d.css" media="all" rel="stylesheet" type="text/css" />
    <link href="https://github.global.ssl.fastly.net/assets/github2-91575e4b8f601c887ca6b13c6f78d06f03af775f.css" media="all" rel="stylesheet" type="text/css" />
Guess why? The first sheet has 2878 rules, the second has 2865. So together they're over the 4096 limit.

Yes, but gmail is a nightmare of an application. I use it because it works, for various values of "works", but it has a lot of insanity inside of it.

Is github a nightmare too?

The paragon of wondrous design that is the Huffington Post has a bit over 4k rules, spread over 5 stylesheets.

msnbc.com also has a bit over 4k rules, spread over 5 stylesheets.

It's pretty easy to find sites with 2-4k rules (Outlook Web Access, BBC front page, CNN front page, twitter, Google docs, whitehouse.gov, the Facebook login page, officedepot.com, washingtonpost.com, youtube, I'm sure I could find plenty more).

All of which is to say, your typical website has more CSS than most people think.

Uhm, are these supposed to be arguments against me?

That it's common for all of these sites, who have massive surveillance and SEO structures built into them, to have gigantic stylesheet collections doesn't change the fact that they are bloated nightmares of code.

If I said, "filing taxes is a nightmare", and you said, "oh yeah, but what about all the other people who file taxes, some of them even more complex than yours?" That wouldn't change the fact that filing taxes is a convoluted, intentionally obfuscated, Lovecraftian construct, summoned forth from the depths of Hades itself.

The large stylesheets have nothing to do with the SEO bits.

They have to do with having a site with a wide variety of different-looking pages and wanting to have a single site-wide stylesheet, instead of having dozens or hundreds of smaller stylesheets. Whether that's a useful thing to do or not obviously depends on how your maintenance for the site is set up, how your CDN works, and probably other things I have no idea about; design of this sort of site is not my area of expertise.

And while I agree that all of these sites have a lot of complicated styles and scripts going on, I have a hard time believing that a site of the sort I just described can be created without ending up with a fairly complicated stylesheet.

If your position is that having such a site (variety of different kinds of pages) should be a non-goal, I can't agree with that: there are plenty of reasons to want a site like that. If the argument is that having a single stylesheet to rule them all in that situation is bad for maintainability, I don't have a good response: as I said I've never maintained such a site, so I don't have a good feel for what the maintenance tradeoffs are.

Fully agreed on the taxes. ;)

> and IMHO 4K selectors is a lot more than any sane page should use

... especially since it'll be hard to fit more than that into the 640k of memory I have. ;)

I know your comment was meant as a joke but 640k would seem to be sufficient for a web browser of some form:


(Whether they support CSS, and if so, what the limits are, I don't know.)

I never had this problem and wasn't aware of it, but I'm glad to know it, because it sounds like something awfully hard to debug if you don't know what's up.

I haven't run into that limitation yet, but I've had a client site which suddenly had started looking broken in IE. It turned out that it had exceeded the 31 stylesheets/style tag limit. This was a site where the CMS theme/template set a few styles, but then was packed with extra widgets loading up to 10 styles each.

The solution was of course to simply join the CSS files where possible. But it definitely was a bit of a WTF moment.

>The root of the limitations is that Internet Explorer uses a 32bit integer to identify, sort, and apply the cascading rules. The integer’s 32bits are split into five fields: four sheetIDs of 5 bits each, and one 12bit ruleID

Is there a reason for this? Why not just use 3 shorts?

Because a single integer is much faster and easier to operate on than 3 separate pieces, and doing a single array sort to compute cascade order is a great idea because of how simple it is.

It seems they didn't expand the limits to 64-bit, as that could vastly increase them: e.g. a (5x4):24 split, meaning 16M rules per sheet.... and if you have 16 million rules in a single CSS file, I think it's safe to say the CSS rule limit is the least of your problems. (But then whoever came up with the 4K limit probably thought the same thing...!)

Does anyone happen to know what WebKit/Gecko/Presto does? I've been thinking of writing my own HTML/CSS layout engine and these sorts of things make for interesting decisions on the algorithms to use.

Is there a reason for 3 shorts? Why not use a 64-bit integer, etc.

There is always some level of arbitrariness when you represent data structures this way for performance reasons. It's all about what maximum values you think are good enough.

Presumably this also leads to an upper limit on the number of stylesheets.

Its 32.

> Table rows, trs, cannot be styled unless you set border-collapse: separate; on the parent table.

I don't recall any trouble applying styles to tr elements without having to do anything special to the parent table.

Setting the border-collapse to "collapse" explicitly just to test:


What am I missing here?

Apologies for this, I was trying to be brief and lost most of the meaning in that one last night. I've updated it to better communicate the potential problem folks can run into.

Aha! Your clarification makes a lot of sense. Thanks!

It looks like Chrome's default user agent stylesheet defaults table border-collapse to separate. So you don't necessarily have to set it, but it's required and will potentially confound you if you use a css reset that changes this.

The initial value of 'border-collapse' in the absence of any user/document/UA styles is "separate". See http://www.w3.org/TR/CSS21/tables.html#propdef-border-collap...

If you have a "CSS reset" that resets it to a non-initial value, that seems like a bug in that "CSS reset", no?

Ah. Well I hadn't checked the spec; I just meant that in my 5 minute testing it appeared that chrome set border-collapse to separate by default, which would explain why the parent commenter didn't ever have to set it to see table styles.

Awesome list! Thanks for providing it.

It would be nice to add a bit more of an explanation for some of these things. eg:

- There's a bold warning about float elements with display: block set - "Do not set both". Why is this so important?

- "Skipping the doctype can cause issues with malformed tables, inputs, and more" - some examples of what could go wrong would be really handy here. Or a link to a more in-depth explanation?

In general some more links would be great.

> some examples of what could go wrong would be really handy here.

One small example that I've seen go wrong, elements don't center with CSS if you skip the doctype. Seems to ignore margin-left and margin-right.

Omitting the doctype basically sends the browser into "quirks mode" and then the page is rendered with old browser rendering bugs.


A partial list of the random bugs you'll find in Quirks Mode: http://quirks.spec.whatwg.org/

It's a bad scene. Avoid it at all costs.

Good insights into voodoo problems. Slightly unsure about the sweary angle though, I love a swear up as much as the next man, but in this it feels unnecessary.

Agreed. It's a shame that swearing has to spoil a potentially good resource. I won't be able to share this will my little brother, who could benefit from this while learning to code, purely because of the amount of swearing.

What amount of swearing? There is exactly one "wtf", exactly one "fuck" and the rest is polite.

If you do not want to show it to brother, more power to you and you got my respect for thinking about what language he picks up. Really. However, the resource has exactly two impolite words in it, so it is hardly huge amount.

There's 2 "shit"s too.

Maybe the author feels obliged to curse a little bit, and mostly in jest / for its own sake because the domain name includes a simulacrum of obscenity (WTF) in it.

Fair comment, it's not a "huge" amount of swearing. But I didn't say that it was.

It's just too strong for me to feel comfortable sharing it with younger ones. I guess a more accurate way to describe the issue for me would be to say it's because of the "strength" of the swearing rather than the quantity.

However, I will be sharing this with co-workers! It's a good document for reference.

You guys are being too harsh on it. Or apparently I failed to see how one "wtf" in the title and one "fucked" in the header could spoil such good resource. I'm sure there are many ways to go around these two if you want to point it to your little brother.

Maybe, but it's hard not to forgive swearing in any piece mentioning ie6.

Wait, wait! Just fork the repo and send your brother an edited version!

Ditching a resource just because a bit of swearing? You all can't be serious...

Swearing for the sake of swearing is never appropriate. I agree with you.

Are you kidding?!? Do you know how much swearing solving voodoo html/css problems has caused? This is but a ghost of the blight of cuss they've brought on the world.

Instead of fixes to fundamentals we get HTML5 feature creep. I think there should be way, way more swearing. An email should be sent to each member of WWWC each time this website is opened by someone.

Maybe there should be an Accept-Vulgarity http header, which some HN readers would keep set to "scatology;q=1.0, obscenity;q=0.9, banality;q=0.1"?

Submit a PR, Mark seems like a reasonable guy I'm sure he'll oblige.



Isn't this the guy whose ego is so great he crapped all over Douglas Crockford when that man so generously spent time trying to help improve Twitter Bootstrap? The very same Douglas Crockford who has contributed so much to building the JS/frontend community to what it is today.

This pairs well with his HTML and CSS Code Guide: http://mdo.github.io/code-guide/

That's more of a style guide rather than a list of gotchas.

Excellent resource! Thanks for pointing it out.

Thank you mdo - wish more people wrote up best practices / gotchas like this in HTML / CSS like folks do for code.

(Or perhaps they do and I'm just not running into them or they are buried underneath the W3Schools sewage?)

I haven't seen much in the way of HTML/CSS best practices articles either, it would be helpful if other commenters could post such articles that they have run into.

If you like this, you might like my Code Guide: http://mdo.github.io/code-guide.

None of it is new (some are over a decade old), but it's a nice resource for CSS/HTML noobs who learnt their craft in Google Chrome and never had to memorize the horrors at http://www.positioniseverything.net

About the problem with `rem` in media queries, see http://stackoverflow.com/q/12201003/449288 . It contains a description of the problem and links to the relevant bugs.

Let's not forget absolute positioned elements inside table cell in Firefox:


Good point. Headsup: this issue should be gone from the Trunk build of Firefox after July 2014; relevant bug [0] is resolved and fix shipped to Nightlies already. [0] https://bugzilla.mozilla.org/show_bug.cgi?id=63895

June, actually. The fix landed for Firefox 30.

Border-box is great, but whenever I have to use 3rd party code all hell breaks lose. You can mix both, but only applying border-box to your own code is tricky and the mental overhead is quite annoying. Even then some minor glitches can occur which you might not even spot in most cases. For example nanoScroller.js exposes Firefox's scrollbars when zooming because there is no way to hide them via CSS and the code to hide them underneath other elements breaks when using border-box.

Not even sure how to handle such problems.

I'm surprised this didn't mention stacking contexts, which threw me for a loop a couple times:



Does "tidy" catch these problems or is it out of date by now? Is there another lint tool that is recommended for HTML (and CSS)?

HTML Tidy only catches structural issues with HTML (e.g, mismatched or missing start/end tags, invalid attributes, etc). It barely knows about CSS at all, and it certainly doesn't try to do any validation on it.

Its an ok start. As a collaborative effort it could actually be useful. Clearfix doesn't need a space character. content: "" is sufficient. Edit - on the github page he encourages contributions. https://github.com/mdo/wtf-html-css/

He links to the guy who came up with that particular clearfix technique, and there is documentation on why and when that space is necessary.

> Fun fact: Years ago, we had to set display: inline; for most floats to work properly in IE6 to avoid the double margin bug. However, those days have long passed.

I wish those days were long passed. There are definitely still a lot of IE6 users. I recently worked on a project which services the Chinese market. http://www.modern.ie/ie6countdown

Agree, but those days may pass soon. The overall trend seems to be all versions of IE losing market share: http://gs.statcounter.com/#browser-CN-monthly-201302-201402

If 4.4% IE6 usage rate in China is accurate, that doesn't seem worth the effort.

It's 4.4% usage rate worldwide. China is 22%.

Acording to Wikipedia: As of 2012, China had 568,192,066 internet users. 4.4% of that would be 25,000,450 users. Depending on what you're doing, leaving out 25M potential users might not be a good idea (again, depends on what you're doing).

Well, it's not like a double margin would prevent them from seeing your text at all. They only lose out on pixel perfection.

Leaving a few million users out of pixel perfection doesn't sound so bad. (And out of those millions, how many will actually stumble upon your web site anyway?)

I keep hearing this argument, and in most cases, it's invalid. For the average page, it's not 25M users but 4.4% of whatever the user base is.

These 4.4% more might still matter, but the cost-benefit tradeoff looks much different now.

Interesting reading. However, I don't like non-semantic CSS class names - parent, float and clearfix. There are better names like used here: http://stackoverflow.com/questions/14874341/how-to-clearfix-...

IMO that just leads to less reusable CSS and more stylesheet spaghetti. I see a class "clearfix" in HTML and I know what it's doing; I see ".clearfix {" and I know what it's doing; but I look at "article:after, .article:after, .group:after, col-2:after, {" and have to figure out what's going on. In terms of code, I think you should be semantic from a developer's perspective.

To be clear, those are just example class names so you know exactly what element I'm referring to and where it resides in the markup.

Hopefully this will work as a means to beating my W3Schools education to death once and for all.

The portability of the web. Write once, debug in every single browser version.

Great tips, but it seems like a fairly random selection with basics about positioning and good gotcha tips like <tr> styling. I feel like there could be a whole page dedicated to floats.

This is great. Even if you're familiar with most of the items it's nice to have such clear and concise problem descriptions and solutions.

Would love to have the list of all the conditions under which a vertical margin will collapse.


I don't know if that's the whole story, but at least it's official.

a fun one that i ran into yesterday, that maybe is basic but i hadn't known before: z-index can only be applied to positioned elements. if you need to z-index something, it can't be position:static

Thanks. Some are exactly what I found annoying most of the time.

CSS sucks

It would behoove the author of this list to learn HTML and CSS so such things are not so shocking and mysterious to him.

I should start a blog about the horrors or C where mysteries are explained such as "You must declare variables before you use them!!" followed by appropriate horror music.

The author, @mdo, also wrote Bootstrap.

Funny how the comment author hasn't replied yet eh?

Didn't really see the need to honestly :).


Is so hard not to use the "F" word for some people?

"float" is a perfectly cromulent layout technique.

On our project there are some guys who're always using float to position elements (other than images in text columns, which kind of works) and then running into horrific edge cases. I tell them "look, use position: absolute and forget about it". And after struggling with edges cases for months they eventually give up.

Then the next case comes along.

Please don't tell them that anymore. Floats are the correct way.

Unfortunately, the correct way is terrible.

Seriously, there are many times when I miss the days of nested tables.

ugh, position:absolute is much worse than floats.

You only dislike that word because someone told you to dislike it. Get over it.

I don't know about the grandparent, but I dislike the word in many contexts because it makes other people extremely uncomfortable. It was probably more frequent than "the" or "a" in my casual speech while I was in the military, but I'm not in the military at the moment, and other people matter.

the key is to not give a shit about those people

No, the key is not to offend people who don't particularly need to be offended. You aren't talking about "freedom", you're talking about being abrasive for no good reason. There are rude words that you may freely use to describe that sort of person, should you wish.

No, I dislike it because it is not necessary to communicate effectively. It is a lazy way to punctuate your language, taking advantage of the fact that people dislike it to cheaply draw an emotional response.

From the fucking lovely Stephen Fry

"The sort of twee person who thinks swearing is in any way a sign of a lack of education or a lack of verbal interest is just a fucking lunatic."

Profanity is an essential and rich part of the English language. It's really only prudes and people who need to feel morally superior have a problem with it, and they can fuck right off, frankly.


I like Mr. Fry and agree with part of your and his message. What bothers me, though, is that it sounds as if you are trying to say that there is only one type of word, and that there is really no such thing as "profanity". But that robs profanity of its usefulness (for example, some recent research shows that swearing can actually alleviate physical pain - but if no words are considered "bad," this probably wouldn't work any more).

The whole idea of a swear word is that it's supposed to be strong, and, yes, offensive in some way. That means that there will be contexts in which profanity will be inappropriate, and there is nothing prudish about knowing this. Good writing means using the right word for the right purpose, and sprinkling swears inside a technical article usually comes off as cheap and lazy.

Your attitude changes when you have children. I used to use more colorful language more routinely. But there are various reasons you don't want to hear those words coming out of your little ones' mouths, yet.

Stephen Fry doesn't just curse. He curses well. He curses (most importantly) when appropriate. Unlike you, and unlike most of the rubbish that gets posted.

> It's really only prudes and people who need to feel morally superior have a problem with it, and they can fuck right off, frankly.

Kinda like how you need to feel superior to them about this particular issue?

Yes, I am a prude. And I have no problem with Stephen Fry thinking poorly of me.

Without the prudes the word would lose its power, so maybe we should keep them around.

The word is only used because people dislike it.

Other side: why does everything need to be watered down, emotionless, PR speak?

There's lots of ways to use language expressively without swearing.

There are a lot of ways to express yourself without referring to kittens, too. But when appropriate, one should feel free to refer to kittens.

Usually I would agree with you. However, when referring to the HTML+CSS+JavaScript atrocity the description is well fucking earned.

You make the assumption that "people" are trying to censor themselves and failing. Not sure how you came to that conclusion, but I doubt the name of this page just "slipped out": I'm betting it was intentional.

It's marketing. Trying to be edgy will get more social media shares. Wouldn't be as popular titled "A List of Things That Frustrate HTML/CSS Developers, and How to Fix Them"

Can't blame him.

Spend some time around people where swearing is in their culture.

One example: sailors.

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