Using Bootstrap the Semantic Way
ostraining.comStill the most comprehensive rebuttal to this common (and I feel, badly mistaken) complaint:
"About HTML semantics and front-end architecture" (from March 2012):
http://nicolasgallagher.com/about-html-semantics-front-end-a...
It's all well worth reading, but the conclusion is particularly to the point:
"The experience of many skilled developers, over many years, has led to a shift in how large-scale website and applications are developed. Despite this, for individuals weaned on an ideology where “semantic HTML” means using content-derived class names (and even then, only as a last resort), it usually requires you to work on a large application before you can become acutely aware of the impractical nature of that approach. You have to be prepared to disgard old ideas, look at alternatives, and even revisit ways that you may have previously dismissed.
...
When you choose to author HTML and CSS in a way that seeks to reduce the amount of time you spend writing and editing CSS, it involves accepting that you must instead spend more time changing HTML classes on elements if you want to change their styles. This turns out to be fairly practical, both for front-end and back-end developers – anyone can rearrange pre-built “lego blocks”; it turns out that no one can perform CSS-alchemy."
That's no rebuttal, just an opinion. Oh we got this huge app and are to lazy to do everything properly.
Saying "do everything properly" is an opinion too. Why is semantic markup more "proper" than Bootstrap's <div> and class names? The idea that semantic markup is a beautiful paradise is unsubstantiated. If you want non-humans to understand your markup you can use microformats, http://schema.org/ markup, or another form of microdata. Making "semantic" class names doesn't change how your users or search engines parse your content.
I'm not convinced you read the link, rather than just the bits I quoted.
Also, laziness is one of the three great virtues of a programmer according to Larry Wall. People are getting things done with Bootstrap every day.
> People are getting things done with Bootstrap every day.
That is not an argument for correctness of approach. If there arose a cult of builders who decided to pour foundations with wheelbarrows and bags of concrete rather than a mixer, I'd tell them they're doing it wrong no matter how many houses they built this way.
The problem is that you can demonstrably point out objective flaws with using wheelbarrows and bags of concrete (or I assume you can - I know nothing about pouring foundations).
With the cult of semantic HTML, the flaws in using class names to describe presentation are almost always not explained beyond some vague notion of "correctness", and possibly an example that bears to relation to reality when you take into account that almost all HTML is being generated by some sort of templating engine anyway.
The problem with using wheelbarrows is that it will take a really really long time to get anything done.
"Semantic" css is like a cult of builders who sort the stones in their concrete by hand, and will only use the bluish stones for the foundation and the reddish stones for stairs. You point out to them that it simply doesn't matter, and they are shocked that you're not doing things the "right" way.
We need a better word for this than "semantic". We're just passing the complexity back and forth between the HTML and the CSS, and the only "semantics" or meaning that arise are to the author/editor. Users don't care, machines don't care, and I've never, ever seen a large-scale site design that doesn't involve some reworking of both the HTML and the CSS.
Exactly. I think web devs want to believe that their HTML is purely content and CSS should fully drive appearance but that's never the case. It makes sense to create classes when you can come up with patterns and want to make sure that you aren't repeating yourself everywhere but simply moving the grid system into CSS just adds an extra layer of abstraction that makes it more difficult to read. Also, CSS doesn't support mixins (yet) so you end up with a lot more generated CSS than if you just use the classes.
Fair point. "Abstract" might be better. It embodies the information-/implementation-hiding goal of this technique.
Abstractions still require names, and the names should be meaningful (not easy: "naming things is one of the hardest things to do in software development"), at least to the development team (hate to keep rattling off platitudes, but "you should write code for humans first, computers second"). Rather than "semantic", "descriptive" seems to fit the bill.
"Abstract and descriptive". Doesn't quite roll off the tongue, but I tried :)
I was at Balisage this summer, a markup conference (XML). The opening talk was on semantics. The summary basically read, what the hell does this word even mean anyway.
(paper - http://www.balisage.net/Proceedings/vol10/html/Usdin01/Balis...)
That's because you aren't blind.
In this case we're not talking about ARIA or native elements vs. styled ones, though, we're talking about CSS classes.
The point of using bootstrap is a reusable set of classes. I really dont care wether class names are semantic or not,it doesnt change anything,except for pedantic people looking at your source code.
SEO doesnt care , users dont care, accessibility doesnt care either. Using new HTML5 tags is good enough and was designed for that specific purpose. If i want semantics I use nav,aside,section instead of div,and so on.
Not going to waste my time and wrap bootstrap mixins in more LESS mixins and loose theme portability and modularity,because semantics...
It's like inobstrusive javascript, trends that make little sense today in the webapp era.
Couldn't disagree more with your statement. What if you have a sidebar that appears 20+ times throughout your application in different contexts. You might decide it is too wide. Are you going to go through all your templates and change class="col-md-blah" or are you going to change one mixin?
Also, if you are providing a theme, I don't see how you lose portability. Your mixins will be relying on base bootstrap anyway?
For pretty much anything anyone could describe as a "web application" if you have the HTML for your sidebar copied around 20+ pages instead of stored in a common template somewhere, you have bigger problems than whether your HTML is semantic.
The example was contrived to prove the point. I agree that the specifics of the Scenario would be indicative of poor practice in other areas, but that doesn't change the fact that the markup should be semantic.
This is what is great about decorators (the most awesome part of Web Components that probably will never be implemented):
You will start caring the day you want to update to Bootstrap 9000 and need to change the class names of all the properties that have changed. A counterargument could be that one could stick with the version already deployed, and that's fine too I guess.
For me it's about being in control of the situation. I will find myself changing things just for them to look as they are supposed to look like, and soon realizing that is not CSS anymore, just another framework being in between and making the work sometimes easier and sometimes harder. Using LESS at least gives you a bit more of control on the hidden spots, and opens room for sane customization.
I do personally prefer to not use a CSS framework at all, but if Bootstrap is a requisite on a project, using LESS is a no brainer.
Bootstrap already depends on the markup structure, which makes your point moot.
I do not really get your point, care to elaborate? Unless you mean that 'div' is subject to change over time…
A span2 div needs to reside in a row or row-fluid div for it to make sense. You can create your own classes that inherit from these, but you still need to nest them. Which means you can't change the structure of the markup willy-nilly. Thus, not using boostrap classes won't get you far.
This sounds exactly like the complaints lodged against structured programming[1] by traditional GOTO-based programmers.
Except, that the idea of semantic web is the traditional approach, whereas composable cross-browser classes controlled with LESS variables is the new and more pragmatic approach.
Sounds like you're confusing Semantic HTML with Semantic Web. "Semantic" HTML is a style of writing HTML where the document exposes the meaningful structure and data in the document instead of the visual layout. The idea is that HTML is just a structured data representation, a la XML, and CSS is then used to transform it into a particular layout.
You are right, I meant to write "HTML". Nevertheless I question the usefulness of this approach. Semantic XML vs. pragmatic JSON tells a similar story.
Semantic structures are never perfect, because they are not controlled by the recipient, but by the sender. I love the idea, but I think it will never come true. We will always have to mine the data ourselves.
I can see the value of providing semantic markup for screen readers or for some Google SERP extension, but I do not see how semantic class names provide any value at all.
Separation of concerns is a nice saying, but as other comments already mentioned, is just not possible to the full extend yet as CSS and browsers are to limited.
I think we should acknowledge these shortcomings and real world circumstance, do our best to work around them, but in the end just move on and be productive.
Perhaps the term "semantic" is overloaded, but there are good reasons why presentational classnames are bad, even though users don't care and machines don't care. Your fellow developers should care. When done well, semantic markup is much easier to maintain and reason about. There's far less duplicated template logic and design changes are much easier because it's easier to understand where your changes will have an effect. The generated CSS might be slightly heavier, but possibly not. Poorly architected CSS tends to get very bloated and heavy very quickly. And there are better preprocessors like Sass or Stylus give you more options for keeping you generated CSS to a minimum. Less is really the worst preprocessor out there.
Every non-semantic bootstrap site I've seen has far more templates than would be necessary the templates only spit out minimal markup with classes that say what each element is instead of what it looks like.
But now we have tons of developers whose primary skill is backend development that are able to mash together a reasonable looking site without understanding how to create maintainable front end code. When the design changes, they just keep piling on more markup and more classes. This works for a while, but as designs get iteratively tweaked and changed, and kludges pile on top of kludges, the markup and CSS become a huge tangled mess. Making changes can have unpredictable effects on other parts of the site.
And then the back end developers throw up their hands and say, "CSS is stupid." But users don't care if the code is a mess, right? Machines don't care either. But the front end dev -- the one who's tasked with getting the new design to work without breaking anything else on the site -- he cares. And he's gonna have a bad time.
Insert an anecdote about the carpenter and the quality of the back of the cabinet there. Except in this case it matters a bit more as others pointed out already.
I appreciate the comparison to the ancient Web, but this article doesn't say much more that I can't find in Bootstrap's documentation.
Anyone who has used Bootstrap's mixins with semantics in mind knows there are some bigger issues to address than the layout. Some questions off the top of my head:
* How do you build semantic forms with Bootstrap without going to markup fluff hell?
* How can you avoid the unsemantic class names for components that are tied too closely with child components (I'm looking at you, .panel)?
* What is the semantic purpose of a row element? It seems purely presentational to me.
* How do I add icons without peppering span.glyphicon.glyphicon-X's all over my markup?
* How should I organize/maintain all of my LESS files as my stylesheets scale? I'm not looking for any one "right" way, but suggestions are always nice.
* Are there any optimizations I can consider when I'm only using a bit of Bootstrap's functionality?
* How can I extend Bootstrap's mixins for my own needs?
I'm hardly a pro at using bootstrap, but we have been dealing with a few of these things, and I can tell you how we've handled some of these questions:
* How do I add icons without peppering span.glyphicon.glyphicon-X's all over my markup?
This one's fairly simple--you still need to add a class to the span, but you can extend the glyphicon.glyphicon-X bit into a particular icon and call it a day:
* How should I organize/maintain all of my LESS files as my stylesheets scale?.foo-icon { &:extend(.glyphicon); &:extend(.glyphicon-foo); }I'm not sure there is a "right" way, but I'd suggest keeping like things together. You're going to end up with a number of rules that are either dependent upon each other, or at least similar in goal, and they can live near each other. In theory, future refactorings will be easier that way.
* Are there any optimizations I can consider when I'm only using a bit of Bootstrap's functionality?
http://getbootstrap.com/customize/
^ Do that :)
Good luck. If you find answers to the rest of those questions, pass them to me!!
questions 1-4: "Semantic" css is a waste of time. Either you're putting information into the html or you're putting it in the css. Use what works well.
question 5: I'll usually put bootstrap into its own folder, have a style.less outside of the folder that imports bootstrap.less, import stylesheets with custom mixins after bootstrap.less, and import straight up custom styles after that.
question 6: go into bootstrap.less and comment out the stuff you're not using. For the js, use something like gulp-include to concatenate.'
question 7: Load my-mixins.less after bootstrap.less, copy and paste mixins from bootstrap into there, and modify them.
I think this would be more semantic (with or without the classes)
<section>
<main> </main>
<aside> </aside>
<section>This deeply nested descendent selector stuff is a terrible idea. It's the css equivalent of jquery dom traversal spaghetti. Don't overthink things. Css should be good enough, and no better.
Sure, but what if you have more than another section that should be styled differently? Classes can help differentiate same-name elements with different contexts, so you don't need unwieldy structure-specific CSS selectors like
justmain > section > mainmain.semantic-classYou'll also get major specificity issues when using element selectors with other class/id type selectors. My rule of thumb is classes and only classes for styling, it really makes life a lot easier. (Even if you have a unique element on the page, don't use the ID in your selector to style it.)
<section class="body"> <main class="content"></main> <aside class="sidebar"></aside> </section>Totally agreed. And more generally, specificity is by far the most difficult challenge in large-scale CSS. Without discipline and some well-defined conventions for selector construction, you will end up with the equivalent of spaghetti code and late-nights deciphering unexpected cascading from other people's styles.
Since large projects will inevitably have to rely on non-semantic HTML and class names anyway (e.g. to differentiate between sibling <p> tags), a simple rule of thumb would be to only use class names in selector construction. HTML elements can still be semantic for other purposes, but the CSS should not care about it.
The other half of the specificity problem is nesting. I advocate strongly against the descendant combinator ` ` in favor of the child combinator `>`. E.g. `.body > .content` is much more robust than `.body .content`. However, an alternate approach would be:
Either way, don't leave it up to individual developers. This has to be adopted by the team.<section class="body"> <main class="body-content"></main> <aside class="body-sidebar"></aside> </section>I have as a rule that if you are in a situation where there can only be 1 element with those properties (it would make no sense at all to have more), I should use the id.
The top elements are one example. It makes no sense to include them inside any other element, and if that ever changes, all the styling will need to change anyway.
What if you had a requirement to create variation styles of those elements? How would you do that? Would you add you base style in your id selector, and then variations with classes? Again, you'll face specificity issues with that approach. Keeping things simple is the best approach here IMO. I've done a heck-load of CSS and have seen how hacky a stylesheet can become because of specificity issues. Sticking with classes and keeping selectors short will make your stylesheet easier to follow and more maintainable, but this is just my approach!
> I have as a rule that if you are in a situation where there can only be 1 element with those properties (it would make no sense at all to have more), I should use the id.
Not a good idea: IDs take massive priority over classes in the cascade.
As someone who often has to override an enormous stylesheet which is all styled to IDs, this is a serious pain point.
Simple example: http://jsfiddle.net/B7tSz/
Agree that structure-specific CSS is unwieldy. However, it's robustness is still a worthy benefit. If you use a white-space sensitive CSS preprocessor, it is not unwieldy, and actually quite maintainable and elegant, since it's structure reflects nicely-formatted HTML. E.g.
Thus, things that are easy to change in HTML structure (cutting, pasting, and changing indentation) are similarly easy to change in CSS.main > section > main text-decoration blink
We do div soup because CSS is still not good enough to do all of your styling there. When you can trivially make an element 6 columns in CSS we'll all stop treating Bootstrap like this. Maybe Flexbox version 6 (or whatever we are on now) finally fixes this but who can keep up and find out.
> When you can trivially make an element 6 columns in CSS
As demonstrated in the article you can trivially make an element 6 columns in LESS (or SASS, which has a bootstrap port also)
Nicer looking div soup is still div soup. <div class="container"> != semantic.
no, but <section> or <div class="products"> are semantic, and there's no reason you couldn't use those instead of <div class="container"> by using the features of LESS or SASS.
In my experience, really trying to be semantic ends up requiring gargantuan leaps of creativity trying to come up with semantic meaning for elements that are there purely for presentational reasons (wrapper classes, clearfixes, etc.)
It is certainly hard, and impossible in some cases. But not as many as you would think. Wrappers can be a problem (although not as much as they used to be). Clearfix is not a problem at all, as it does not require an element only a css mixin[1]
Still, it's very possible to be almost entirely semantic with a few minor exceptions using a css preprocessor.
[1] http://compass-style.org/reference/compass/utilities/general...
That still wouldn't be semantic. Their only reason for existing is for layout. If html/css were semantic you could write all of your html first without thinking about style or layout and then go do the css after, but that's simply not possible today.
I think you are using a different definition of "Semantic" - please provide a snippet of html you feel is semantic and I'll show how this approach can be used with it.
Be very wary, though, if you are using mixins to define these columns in a case-by-case basis, as this could lead to huge generated CSS (the properties of the column will be defined in each class the mixin has been used).
Alternatively use SASS (and the bootstrap SASS port[1]) which doesn't has this problem, as it instead rewrites selectors.
i.e. if you have:
And you do:.column { width: 100px; display: inline-block; }
Then the generated css will be something like:.cool-sidebar { @extend .column; }
[1] https://github.com/twbs/bootstrap-sass.column, .cool-sidebar { width: 100px; display: inline-block; }Less has the same feature: http://lesscss.org/features/#extend-feature
Thank you so much for pointing this out, Moretti! It drives me crazy when people talk about the extend feature like only SASS has it. People are always underestimating how similar Less and SASS are.
To be fair, Sass did have it about 3 years before LESS
Then, in Bootstrap terms and since the grid syntax is offered in mixins, should it be used as follows
instead of using the mixin?.foo-class { &:extend(.col-md-4, .col-md-offset-8) }.foo-class { make-md-column(4); make-md-column-offset(8); }
a rule of thumb I've been following when using Sass/LESS: If your mixin doesn't take arguments, you probably want `@extend`
I build web "apps". I don't treat HTML and CSS like a semantic document; it's just a declarative layout engine. Yes, I often use HTML elements and structure to define layout instead of CSS classes. My CSS class names often have little "semantic" meaning outside their single purpose, that is to define layout and style. Am I doing something wrong? We don't have these discussions when building native GUIs.
Perhaps if I were building a CMS or some other document-oriented site I would approach things differently.
Here is a LESS mixin that will go a long way in making semantic Bootstrap easy to actually do:
.make-column(@large, @medium, @small, @tiny: 12) { .make-xs-column(@tiny); .make-sm-column(@small); .make-md-column(@medium); .make-lg-column(@large); }
Then use it with: section#main-content { .make-column(8,8,9,12); }
I've used Bootstrap and been forced to use it on existing projects already engulfed in it. It isn't pretty on a large project. I've sworn off using Bootstrap in any new project that isn't a prototype for a hack day. The only things I borrow from Boostrap these days are some of the JavaScript niceties like modal, tooltip, and scrollspy. And when I do that I'm very explicit in what code I pull in to use those.
Build the CSS for your next project using mixin libraries like Bourbon/Neat or Compass/Susy. You'll be glad you did.
> I've sworn off using Bootstrap in any new project that isn't a prototype for a hack day.
I believe initially Bootstrap was intended for just this use case—make it easier to do a quick mock-up in markup. Once your design is relatively stable, you would naturally spend some time custom-fitting markup and stylesheets (enhancing source code readability, accounting for those who can't see, basic SEO optimization, etc.). This whole ‘front-end framework’ thing seems to me like a wrong direction to take.
Frontend is my bread and butter, and I used to be such an artiste that I shunned Bootstrap too.
But you know what's worse than Bootstrap? The hand-rolled framework that rises out of the muck on a large project. At least Bootstrap is always the same. It's a lingua franca, and a decent one at that.
This is one of the main reasons I like AngularJS directives. If used properly (huge caveat) they allow your template markup to take on far more semantic meaning.
I also agree with the idea that we should use Mixins to allow for more semantic meaning in our plain HTML. As an added bonus, this can make things a lot more maintainable down the road.
I just noticed that this article is laid out with a table, with a single td. Glasshouses, stones etc.
One of the strengths of BS is mobile-first responsive design. You can chain classes like this: class-name="col-xs-6 col-md-3"
If you try this with the method outlined by the OP, you'll end up with a giant css file.
What are current options to optimize LESS files and remove unused mixins? And for the generated CSS, what are current options to merge shared rules and remove unused classes reported against a sample HTML?
>What are current options to optimize LESS files and remove unused mixins?
Kolega, use parametric mixins without parameters: http://lesscss.org/features/#mixins-parametric-feature
For unused css I'd try this: https://github.com/addyosmani/grunt-uncss
I got this recommended for handling shared rules: http://zmoazeni.github.io/csscss/
This increases the number of css styles dramatically, which affects page speed on large sites.
Nicolas Gallagher addresses and deflects this point specifically with real numbers: http://nicolasgallagher.com/about-html-semantics-front-end-a... The link came from an earlier poster. Once you compress the HTML, the savings are insignificant compared to the likely 10s or 100s of kilobytes of images and JavaScript on a modern web page. Given how tiny the savings are, there are other places more worth your time to save bytes.