Hacker News new | past | comments | ask | show | jobs | submit login
Twitter Bootstrap without all the debt (coderwall.com)
197 points by kissgyorgy on Nov 15, 2013 | hide | past | favorite | 71 comments



After hand-crafting CSS with semantic markup for years, using the techniques suggested here, I've started liberally sprinkling Bootstrap classes in my markup. It's not clear to me that it's any less maintainable than the alternative.

My primary way of achieving reuse, as a developer, is through templating and partials and helpers; they're what I use to avoid runaway repetition of styles, which means that redundant Bootstrap class usage isn't often a pain point. But keeping classes inline does make it easier for me to debug layout problems at a glance, where relationships between elements are clear. Those classes might not have semantic value to the consumer of the page, but they certainly have semantic value to me. And most of the time, I care more.

Large CSS files, even semantic ones, are difficult to maintain, and often give you little feedback on the meaningful relationships that elements have with each other. Pure semantic markup is a myth: web pages are structured documents, and that structure has an impact on style, which is constrained by the limited descriptive power of CSS itself.


I'm in the same camp. I know everyone is gung-ho on separation of the presentation layer, but I believe styles are far too intertwined into the presentation for semantic markup to be beneficial at a large scale. My primary concerns with semantic markup is that there's no quick way in your developer tools / inspector to lookup correlated rules in your LESS/SASS files and have them make sense (i.e. how many columns is this and how does it handle responsively?). As @bguthrie said, there's little you can deduce regarding relationships between the CSS file and the HTML markup. For this reason I stick with classes, as it's far easier to tell how my layout/grid is structured by simply viewing the source. I'm sure many will opinionatedly differ, but it's worked just fine for me for a decade and I find it easier to maintain and for other's to understand the structure on first glance of the HTML.


I recently started using source maps, which basically allow you to inspect the underlying less (I dunno about sass...). That might not totally fix your issues with inspecting correlated rules, or maybe you've already tried it, but I've been finding it helpful.


Sass can generate source maps too. :)


You should check out - http://brackets.io/index.html

It does a really good job at showing the relationship between HTML + CSS


Does it now support multiple cursors (like CTRL+D on Sublime Text 2) ? Last time i checked, it didn't, and that is a deal breaker for me


I spend about half my time cranking out responsive PSD->CMS themes, and I feel the same way. I use a lot of template parts/helpers, and generally it's not a pain point to reproduce classes across a document. Except where it is and then, well, there I extend a class.

Simply having some kind of standard to work against is a big step up for me across projects. There is a great deal of semantic information involved in the in-line class names of a framework, once I learned them. Having verbose classes is maybe not quite a domain specific language, but it is a move in that direction.

Any time you've chosen to select a language for describing what is going on, you're locked into that decision. I just like having a largish dictionary that other people know, and I don't mind being a little more explicit in the markup if it lowers the number of unique or idiosyncratic words I need to develop for myself.


This is why I have been using SUIT-like components and utilities in my recent projects.

https://github.com/suitcss/suit


Yeah, +1 for SUIT CSS. Modularity is clutch, particularly on larger projects that get tossed around a lot. I'm not completely sold on OOCSS, but MapBox's style guide is making a believer out of me (https://www.mapbox.com/base/). Minus the unsemantic grid, of course...


I used to be firmly in the "don't use bootstrap" semantic css camp, but now that Bootstrap 3 is out, I no longer see the point. It's a pain to have to think of all the specific class names for things, and the end user doesn't care anyway.I'm not sure what the actual real world benefits of semantic css are, and I have wasted a huge amount of time in the past coming up with my own stylesheets that end up being worse versions of Bootstrap anyway.

The only place that Bootstrap really "traps" you is in the presentational grid class names, but you'll get this with any grid, and the Bootstrap grid is pretty solid (I have invested a large amount of time designing my own grid systems in the past).

The biggest benefit of Bootstrap that I see is that it enforces a sensible naming convention, so that someone who has not read through your quirky "semantic" 3000 line stylesheet can easily get to work on the site. The custom stylesheet (and the variables stylesheet) that you load after Bootstrap will tend to only be a few hundred lines, and contain only the things that make your site unique.

I have several large sites that I made before I used Bootstrap for everything and I constantly kick myself when I've got to dig in and maintain them. If you are a good designer and take pride in your work, nobody will be able to know that you used Bootstrap without opening the inspector.


As far as grid layouts go, bootstrap's is fine. The main argument against grid layouts is that they incorrectly couple two things:

1) Content and presentation (by having the HTML actually include layout information).

2) Various classes that use the grid classes (which have no reason to be coupled).

It's difficult, because standard CSS doesn't give us a great way of solving the problem. If you are going to move the descriptions of layout into the CSS, where they belong, then there will be a lot of repetition without variables/classes that things like SASS give you. In my opinion you are far better off by at least separating the concerns and having a bit of repetition in your CSS rather than using a grid system in your HTML, should you be using standard CSS.


To be fair, you cannot design a useful grid system where the HTML is void of layout info. I mean, sure you can do something like this:

  <div class="features>
     <div class="feature">...</div>
     <div class="feature">...</div>
     <div class="feature">...</div>
  </div>
But the problem with the above is that you can't easily distinguish between the three features. They are all the same, unless you do some type of "first feature is 2x the size". So you end up with code like this instead:

  <div class="features>
     <div class="feature feature-primary">...</div>
     <div class="feature feature-two-images feature-narrow">...</div>
     <div class="feature feature-last-no-thumbnail feature-small hide-on-mobile">...</div>
  </div>
There isn't really anything semantic about the added stuff (except maybe the feature-primary class). You end up trading off between custom class names for every use case (ephemeral-photographic-feature) with all types of custom rules, or you end up saying "screw it, I'll just have semi-semantic markup that directly affects layout".

I am also starting to think that at some point semantic markup starts benefiting search engines much more than anyone else. After all the average user with credit card in hand has no idea if the credit card field has a class of "FormFieldCCNum__1" or "credit-card". The developer does, and that's who these tools should be optimized for.


I agree with your post, but I think you only address half of the issue: the other half is the incorrect coupling. In terms of maintainability it does not make sense to have a bunch of random things with a class of "narrow" because then you can't predictably change the "narrow" class. It's really hard though, and I don't see a clear answer using CSS without some kind of OO addon (less, sass etc.)


Upvoted for truth, but TFA goes a long way towards minimizing the difficulty of creating and maintaining a semantic solution. I've been turned away from semantic css by simple pragmatic efficiency, but this solution might be worth trying out.


Yes, but then you've added SASS to the mix. If you stay in Bootstrap-land you're at CSS level still. Or am I wrong?

I want to stay at HTML/CSS/JS level. I don't want layers and layers and layers. Even using Ruby templates (if I'm using Ruby for instance) irks me. Maybe I'm weird. But I'm only a semi-professional web dev at this stage so my 2c may be worth les than your 2c :)


Bootstrap is a black box: I don't really care what it was implemented in (LESS as someone else pointed out). I include bootstrap.min.js, and then customize it as necessary in my SASS file, compiled during deployment to CSS. No conflict here.


I use bootstrap-stylus, because Stylus is what I like. I load one custom.styl after the bootstrap files, and modify bootstrap's variables.styl.


Bootstrap was made in LESS.


What does "TFA" mean?



The biggest problem of using @extend this way is that it makes the CSS file grow really _really_ fast. I’ve done things in similar way in the past in a medium-sized project (though with Blueprint and custom utility styles since Bootstrap doesn’t existed back then) and ended up with selectors that looks like this after compilation, but for the whole file:

   .tag,
   div#main h1 span,
   div#content h2 span,
   div.comment ul.info li.username span,
   div.comment ul.info li.comment span,
   div.sidebar div.search span,
   (a lot more selectors here),
   div.footer ul.links span {
      /* … */
      }
      .tag:hover,
      div#main h1 span:hover,
      div#content h2 span:hover,
      div.comment ul.info li.username span:hover,
      div.comment ul.info li.comment span:hover,
      div.sidebar div.search span:hover,
      (a lot more selectors here):hover,
      div.footer ul.links span:hover {
         /* … */
      }
Then I hit the 4095 selectors limit[1] in Internet Explorer. That pretty much force me to cleanup the whole CSS. In the end I took similar approach to Bootstrap classes, which make the CSS file size and number of selectors much more manageable.

[1]: http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/10164...


I know that /* ... */ is obviously a placeholder for more code, but I find the fact that it looks like a "dead" or "paralyzed" face to be much more amusing (and, for that matter, relevant)


Are we talking about Saas? You can use placeholders to deal with that.

http://sass-lang.com/documentation/file.SASS_REFERENCE.html#...


I don't think this is quite what I want to say, what I meant to say was that using @extend will increase the number of CSS selectors by the number of selector it extends to when compiled (including nested selectors.)

For example, .form-control in Bootstrap total of 9 selectors, the login example from the article extends from it twice, now the compiled CSS ended up with at least 18 selectors. Another example would be .btn the author used in the login example, which has another 9 more selectors for .btn alone, then 16 more selectors in each .btn-variant. The example extend from both .btn and .btn-variant twice, this result in 50 more selectors that will be added. From my very quick counting, the login form example alone will create about 71 more selectors for a simple login form.

This might not be a problem for a small site, but the number could become unmanageable very quickly once the site grow.


This was thoroughly disappointing.

I was hoping to see a discussion of how to separate out the structure of bootstrap and the appearance of bootstrap so that as you grow and change you have neat separation of concerns and single reaponsibility.

Instead, they trotted out the old "<div class="nav"> is bad, <nav> is good" semantic web fetishism. And while yes, nav seems easier for a robot to understand, As soon as you start defining custom components you loose much of that robotic awareness because now you have to program the parser to handle unanticipated element types, and mis-use of element types. So on net you're at best a little better off than you were with <div class="nav"> And definitely more complicated.

I'd love for someone to prove to me how semantic naming actually helps. To me it seems like the XML vs JSON debate where we are piling complexity on chasing after an impossible goal of machines being able to consume data without having to know the context of the data. Unless I am missing something, I think we'll look back at this period of time in HTML structuring and scratch our heads like we are doing now at the XML fad.


I think Nicholas Gallagher made the case against this best:

"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.

Once you start writing non-trivial websites and applications that you and others must not only maintain but actively iterate upon, you quickly realise that despite your best efforts, your code starts to get harder and harder to maintain. It’s well worth taking the time to explore the work of some people who have proposed their own approaches to tackling these problems: Nicole’s blog and Object Oriented CSS project, Jonathan Snook’s Scalable Modular Architecture CSS, and the Block Element Modifier method that Yandex have developed.

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."

from "About HTML semantics and front-end architecture" http://nicolasgallagher.com/about-html-semantics-front-end-a...


Why do HTML classes have to be semantic, and by semantic I mean describing the content encapsulated in the element? I never understood this mantra. It's parroted around and followed religiously, often lacking any arguments. It's not for users. Users aren't going to `view source` and say, "Look at all this rich, semantic goodness!" I could see their utility for search engines and vertical web crawlers, but beyond that, I just don't get it. I'm using OOCSS now and have abandoned strict semantic HTML class names. The huge benefit is that the CSS ruleset is small and maintenance is so easy. When you're using a grid system, for example, you don't have to look at the class name, and then reference that in the CSS (inspector helps, I will admit). You already know what's happening. It's a lot less to learn, and updates are much faster in my experience.


Of all the reasons offered for it I only ever really saw one as legitimate(ish): making it easier for robots to parse your site, whether it's google bot or screen readers for the visually impaired.

I think it was a reaction to monolithic, single file, hundreds of divs web development styles(way before my time).

I find it much more useful to just use some sort of templating and split my html files into small chunks. At which point it doesn't matter if you code them in divs with decimal code classes, it's still pretty easy to deal with.


Because when you are refactoring your CSS you want things to be coupled correctly. You want all the things that are similar in content to have the same class so that they look the same. If you don't want this your site is probably not very well designed. It has nothing to do with reading the file, either by humans or robots, it has to do with correctly separating concerns and then coupling them where they should be.


I agree with what you're saying. I just wouldn't follow this dogmatically. To me it boils down to what's DRY, maintainable, and easy to refactor. I do use more abstract class names that have no presentational meaning, but that's only because it's a bundle of styles used in a lot of places, like a heading repeated all over. Or maybe it's a component with a bunch of interrelated elements. But there are one-off situations where I've used <p class="color-offwhite"> or <p class="color-brand font-size-sm">. I also find using grid classes directly is easy to maintain. Using grid classes directly also means you've separated most of your layout concerns. So separating concerns can happen in different contexts. OK, I'm done rambling.


They actually shouldn't, assuming I'm understanding you properly. class should never describe the content but should instead be generic. So rather that class="big_red_text" it should be class="alert_text" or something


FYI, big_red_text is presentational (specifies size and color, while saying nothing about what the role or purpose of the text is) while alert is semantic (describes the content, says nothing about presentation).


I wrote an article describing this exact technique almost 2 years ago, but at the time the commenters on HN fell just short of calling me an idiot.

https://news.ycombinator.com/item?id=3653540


I believe I read that one also. It seems more confrontational at quick glance.


There are alternatives to bootstrap like bourbon, neat and bitters:

http://bourbon.io http://neat.bourbon.io http://bitters.bourbon.io


I totally dig the Thoughtbot toys, and use Bourbon/Neat in my own foundation - but it's a pretty loose alternative to Bootstrap if you're looking for all that Bootstrap has to offer. Bitters still kind of feels like an after-thought to me. Not sure if that's unfair or not.


Yahoo Pure is very light: http://purecss.io/

It has components you can stick together (or not): grid, button, table etc. Also it plays nice with others, it was easy to create a Bootstrap Button component, so now I can mix and match.


Semantics are semantics.

The point of semantics is to glean meaning. This does not necessarily mean Oxford Dictionary meaning, nor does it mean HTML Spec meaning.

Here's the tradeoff: The semantic meaning of a bootstrap class is evident to the developers. The semantic meaning of an element is evident to the browser.

What is more valuable to you: a common language amongst multiple developers, or a semantically rich HTML document? I'd imagine for most web-apps, where permanence is unlikely and iteration is constant, that the former is true. Bootstrap provides a predictable common language, despite it's not-so-semantic effects on the markup.

I agree with woah here - real world benefits of semantic class names are, probably, waning.


TLDR: try to use Boostrap like Zurb Foundation is designed to be used.


Exactly. This is why I started using Foundation primarily in the first place. I tried staying on the bootstrap-sass bandwagon, but Foundation won me over entirely by letting me overwrite Sass variables to retheme.


"but Foundation won me over entirely by letting me overwrite Sass variables to retheme."

Can you elaborate on this? Is this not possible with LESS?


> Can you elaborate on this? Is this not possible with LESS?

It's definitely possible. I overwrite Bootstrap's colors/borders/buttons with LESS. LESS and SASS are, functionally, extremely similar.


So what happens when my markup needs to change? I also need to update the SASS right? If that's the case, I see no benefit.


Exactly. There shouldn't be a markup structure to style dependency. Personally I would never use an element selector because it makes life really difficult when you need to refactor the markup, which happens fairly often in my experience. Using classes doesn't make things less semantic as long they are named correctly and as long as the markup is semantic.


Can't you do the same thing with LESS?

    body { .container; }
    
    body > header { .page-header;
      p { .lead; }
    }
    
etc

Then you can make use of bootstrap's variables as well for customizing? Obviously personal preference LESS vs SASS, but no reason you _need_ to switch from the default


For large/complex sites, you should take into consideration the performance of various selectors. ID selectors are always fastest, and single classes are faster than complex selectors.

Nested rules in LESS/SASS make things easier to manage, but when you end up using extend blocks, nested files, and parent rules, you can end up with very non-performant CSS rules. It may not matter much in a small page, but on larger pages with thousands of DOM nodes it can add up.


Unless you're just nesting the ever-loving shit out of your pre-processor, there is almost always lower hanging fruit when it comes to performance.


I like this post.

I felt bad forcing my HTML to fit Bootstrap. Using @extends to keep everything semantic ensures my templates logically sound.


But what are your actual benefits to your semantic layout besides "not feeling bad"? It seems that using the @extends creates just as many issues as it solves.


One of the best benefits is confining the style to the stylesheet so it can be swapped out allowing per customer skinning of the app.


What kind of problems would it create? I'm not familiar with SASS, but the approach described in the article looks interesting to me.

I like to keep the markup as semantic as possible, and keep the structure/presentation distinct. I find it easier to reason about.


It bloats your compiled stylesheet.


(In response to some of these comments)

Concise, semantic markup results in:

    * less complexity
    * easier maintenance
    * greater portability
For one example, what happens when you want to use another grid framework instead of bootstrap's? With non-semantic markup, you have to go through and strip out all those bootstrap classes on everything. On the other hand, if you use concise, semantic HTML and Sass (or LESS, if you don't mind totally abusing at-rule syntax), all you have to do is swap out the grid mixins (or, in the case of the approach in the OP, @extends) and related styles, often with no changes to the markup. Same with any other component you might want to swap out, such as form styles.

What happens when 3 years from now someone inherits your mess of HTML with presentational styles for a framework that's years old and no longer relevant? In addition to updating the styles, they also have the pleasure of spending hours or longer stripping out your outdated, framework-specific presentational classes and ids.

What happens when you HTML needs to be consumed in an unknown, unpredictable context? Content organizations are still dealing with the fallout of having inflexible HTML and CSS that can't easily be adapted for mobile.


I've experimented with this strategy -- avoid putting bootstrap classes directly in markup, but instead use CSS pre-processors to mix bootstrap classes into your own css classes.

I've found it's less maintainable, in the sense that the extra level of indirection becomes a lot more confusing to debug or change. Dealing with a bootstrap upgrade (minor or major) only makes it worse.

The presentational classes in your markup does give me a bad feeling. Maybe if Bootstrap had been designed from the start to keep your DOM purely semantic and your presentation purely in CSS, then it would result in a framework that can more easily be used that way. However, there are other frameworks that tried to do this; they haven't been as successful (ie popular) as bootstrap, and it may be that some of the reason why is the extra complexity it takes to try and keep presentation and semantics strictly separate.

There is such a thing, sometimes, as too much abstraction. When we start calling it 'over-engineering' or 'too complex'.


I learned along time ago that you can either write "perfect code" or you can write "pragmatic code" guess which ones wastes less time and puts more bread on table?

I started a long time ago in college with procedural see, moving onto JAVA and .NET and its OO cruft only to realise that instead of helping its slowing me down and come around full circle


> "...we can still style this page using Bootstrap's style definitions by @extend-ing Bootstrap classes..."

FYI, LESS has the same exact functionality since v1.4.0. https://github.com/less/less.js/blob/master/CHANGELOG.md


So you want your HTML to be clean and semantic and your CSS to be a spaghetti riddled @extend-fest. No thank you.


Most of the applications I build are for internal users and unlikely to have any type of real designer working on the project. Bootstrap provides a way to make good layouts without a ton of design work. It's also nice to use the bootstrap css between companies without any IP issues.


I see the point, but isn't this only moving the "debt" to another area? Instead of your markup being littered with Bootstrap classes, now your Less files are.


I tend to agree with the post. Mainly I've used bootstrap so I dont have to focus on the design and I can focus on the other aspects. Recently I have been having to deal with getting off of the row layout I used in my initial designs.

This has been a pain and the pains keep growing as I realize that I need more control over the design. In fact, recently I have spent a lot more time fighting Boostrap and now I am spending the time I saved in the beginning by using it.


Isn't this how everyone utilizing a pre-processor uses it?


Been doing this for my last few projects and loving it. Using yeoman helps simplify the process a ton.

Now if there was only a simple way to exclude all of the styles that are never used across a site I'd be able to cut my CSS down like 75%, but that would probably take a headless browser crawling the whole thing.


As far as I know, this (still experimental) grunt task by Addy Osmani, does exactly that: https://github.com/addyosmani/grunt-uncss


This is exactly what I was looking for!


As another commenter pointed out, you can recompile the .less files, excluding what you don't need. You can also use the web customizer in our hosted docs at getbootstrap.com.


I'd recommend using the bootstrap source at first, and pulling out the modules you don't need from the bootstrap.less file. Because they are separated semantically, you can probably guess which pieces you won't need, and then band-aid from there.


or event better , use a framework with an asset pipeline that does that for you ... like express or rails ...


In that case one should look at PureCSS.io from Yahoo! .


I am of the opinion that semantic markup is not an indicator of a quality product. Tradeoffs need to be evaluated including maintainability, code sharing, knowledge transfer and rapid prototyping among other factors. Purists that say no markup in HTML are constrained to a religion, just as any other must do that drive decisions. I argue that you employ not just the tools, but the techniques and strategies that will allow you to advance. Every situation is unique.

Regarding this technique...

In some circumstances, it is more than justified. Adding another layer of encapsulation can allow for a separation of concerns that may accelerate some stages of development.

I ask myself, is this more of a tooling question? If, we had a view of our stack that a) allows for these encapsulations and b) surfaces the right information at the right time would we not make use of it?

For example, my personal frustration is that when building a new feature for Rails for example, I have to conceptually traverse the full stack (html/erb, css/sass, javascript/rjs, views, helpers, layouts, controllers, model, database) -- substitute your own versions these separations depending on your stack. That means that adding a new checkbox to a form could potentially touch 9 different layers! Do I really have to hunt and peck for 9 different files to add 1 checkbox? Oh yeah, don't forget your tests...10!

I think that organizing the layers allows different experts to optimize different layers...a good thing!, but at the cost of being able to see 1 slice of the 10 layer cake.

I often search (and have not yet found) a set of tools that will allow me to view my stack depending on my current task and goals. I am not talking about edit/debug/optimize type views that come with some IDEs. I mean the logical grouping of all concerns related to my current feature.

This is a tooling issue in my opinion. Why can't my editor give me the right view of my stack at the right time? At a minimum, let's have our editors filter project files (and database views) depth first, grouped to all files that are relevant to the feature I am currently implementing. Sure, I can quick open and type out some names, but I would rather have my editor show me the relevant files (and only the relevant files) that make up my current slice of my cake.

Is there an editor, or plugin out there that will do this today?

Or what about 1 step further... Instead of surfacing files, what about surfacing just the chunks of code that are relevant. What if my editor let me author bits of all parts of the stack for 1 feature in 1 logical file, and save it out to the traditional locations expected by my framework. I personally would be more efficient, and effective, if I could see my snippets of html/javascript/css/controller code/model code all in 1 tight view. No more would I have to keep all the connections in my head, they would be laid out right there in 1 file. Also required for this type of productivity would be simple ways to reuse and refactor.

Just looking for a tool that will let me have my cake and eat it too.


You are searching for the IntelliJ IDEA Project Scopes feature [1]. It let you view group of files either manually set or automatically, based on what changed, what belongs to a particular problem, etc. Basically it exactly does what you are searching for :) 1 step further: it only can do this with regular expression; you can edit a regular expression in a new window and it automatically change it on the relevant place real time.

[1] http://www.jetbrains.com/idea/webhelp/scope.html


Bravo!




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

Search: