I was once on Zeldman's semantic CSS bandwagon - Designing with Web Standards was the Bible for me. Not anymore. Now I think it is a huge mistake that creates unmaintainable CSS. Here's why:

Let's say I want to style a box to hold an image and a caption that goes in a blog post. Semantic CSS would have me do something like this:

div.post div.picture {
border: 1px solid #ccc; background: #eee; padding: 8px; font: 11px/15px georgia, sans-serif;
}

This is OK, except this style is almost the same as a newsletter subscribe box in the sidebar, and I'm duplicating all those style here. DRY - no problem, I'll just stack the selectors:

div.post div.picture, div.moreinfo div.newsletter-subscribe {
border: 1px solid #ccc; background: #eee; padding: 8px;
}

div.post div.picture {
font: 11px/15px georgia, sans-serif;
}

But wait, that border style is being used in the nav too, so...

div.post div.picture, div.moreinfo div.newsletter-subscribe, div.nav {
border: 1px solid #ccc;
}

div.post div.picture, div.moreinfo div.newsletter-subscribe {
background: #eee; padding: 8px;
}

div.post div.picture {
font: 11px/15px georgia, sans-serif;
}

We can continue with this, but you see where it is going: a huge stack of selectors followed by a declaration of one or two properties. This is obviously bad: the style for any given element is spread out in lots of different parts of the stylesheet file, or even multiple files. If I want to add a new element, I have to copy my selector into all those different points, every single time. Even if my new element has the exact same style and the only difference is that it has a different semantic meaning. Obviously, this is too much of a pain, so Semantic CSS encourages defining independent components with lots of redundancy.

If you're using a CSS preprocessor (which were not around when Designing with Web Standards was published), mixins partly mitigate this problem. All my rules can inherit shared styles. But there is still a problem: every time I want to use a style, I have to edit a CSS file. With Bootstrap, the process for using a zebra table is copy and paste the boilerplate HTML from the component library - done. The Semantic CSS way is to come up with a new semantic class name (".users-table" or whatever), find out where in the CSS the zebra table is defined, add the selector and now I can start using it. So now the whole dev team is constantly checking in changes to a shared CSS library for no purpose other than to register the fact that they are using the component, and the CSS files get bloated with hundreds of meaningless selectors.

This blog post cleverly proposes a separate CSS file to map semantic CSS names to style definitions - ".users-table { .table-zebra }" - adding an extra level of unnecessary indirection. Or worse, a line of javascript. Why? On the off-chance that you might want to switch to another CSS framework that just so happens to use Bootstrap's markup, but not its class names?

The only thing Semantic CSS gets right is that classes shouldn't be descriptions of the properties. But there is nothing wrong with .span6 instead of .feature, or .btn-primary instead of .editUserFormSaveBtn.

tl;dr - Semantic CSS is a red herring that creates more problems than it solves. These problems weren't noticed because it was invented and promoted by people working on very small marketing websites without much code reuse, and is totally inappropriate for web applications of any size.