HTML5/JavaScript Cargo Cult Beliefs

There are tools and techniques we use and rules we follow every day that make absolutely no sense but we follow along anyway, nodding our heads, evangelizing, and looking down on all those poor “developers” on StackOverflow who haven’t yet heard of our new HTML5 Boilerplates. Poor souls must be developing in a third world Internet.

Let’s all take a minute to slow down, review our work, and starting asking ourselves why we’re following along with some of this cargo cult programming crap. These are a few of my favorite examples of things we do or put up with that don’t make sense.

Conditional Styling (A.K.A. IE bug fixes)

I’ve been using the HTML5 Boilerplate since its first release. When I first started using it there was a ton about the index.html file alone that I just didn’t understand and thus never once used. Now that I’ve graduated to the level of competent web developer I understand every bit of the framework but still don’t use much of it. So I began to throw things out. One of the things I never stopped using however was the conditional classes on the HTML tag. Does this look familiar to anyone?

1
2
3
4
5
<!DOCTYPE html>
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]><html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->

That’s what HTML5 Boilerplate gives you in the default index.html file. So what are all those conditions and why are they there? Well, their purpose is to allow you to fix styling bugs specific to certain versions of Internet Explorer. It’s the lesser of a few evils and the best technique for targeting only certain versions of IE in your stylesheets there is. But the question is, do we really need it? Before we answer, let’s also talk about the .no-js class.

The .no-js class is used by Modernizr. When Modernizr detects JavaScript and certain JS features a browser supports, it’ll replace this class with a plain .js. This way you can apply different styling and JavaScript to certain elements depending on if and which features of JavaScript the browser supports. The question this raises is, are we going back to the “For the best experience use Browser X” days?

The problem with conditional styling is manyfold.

  1. You might not need it at all. In fact, most of the time, developers never use the classes but keep the conditional tags there anyway.
  2. Being so quick to serve up different CSS to different browsers is lazy. The first thing people do is say “oh, that doesn’t work in IE, let’s just serve them something shittier” when the first reaction to a situation like that should be “hey, how else can we approach this that does allow IE to get the closest, if not identical experience other browsers are getting”.
  3. If enough of your userbase is using a browser that lacks a feature you’re going to use, you should really rethink that feature.

Conditional CSS and other styling hacks should be a last resort. This sort of code tells developers that they should just resign themselves to the fact that they’re powerless to come up with a cross browser solution so they should code two different ones instead. This flies in the face of progressive enhancement. Progressive enhancement is supposed to rely on the browser’s native capabilities to work, not artificially with conditional CSS classes.

A simple example: You have an element with a gradient background. IE doesn’t support gradients. What do you do? Well, you could use conditional markup and then apply a png background to your element that only IE sees. Or, you can just use a fallback rule. IE can get served a solid color while other browsers get the nice gradient. In this case we assume that this feature isn’t critical to the design. Please don’t get me started on what designers like to call “critical” either. Some things just aren’t as important as others, I’m sorry but I’m not sorry.

The problem with .no-js is that everyone has JavaScript enabled!

Seriously, who in 2014 is browsing the web with JS turned off? No one. And if they are, they likely know it and thus they know exactly how to fix your broken site.

Update: Looks like the HTML5 Boilerplate project has remove the conditional .no-js classes and html tags from their index.html file.

If you website relies on JavaScript to display properly then you should be confident that your audience will have it enabled. In this day and age, no one has it turned off. This feels like an edge case with a clever solution that everyone implements so they can feel smart and pat themselves on the back for making sure that all 0.001% of their visitors with JS disabled get a pretty site. Beyond that, there’s a perfectly good <noscript /> tag one could use to do something like this just after the opening body tag:

1
2
3
4
5
<noscript>
  <p>
    Hey there, looks like you're the last person on earth without JavaScript support. You can either turn it on, go download a browser that supports it, or have the absolute worst Internet experience everywhere you go.
  </p>
</noscript>

There are very few cases where you really need no-js. If you know you need it, use it but don’t go around slapping a .no-js on a page just because that’s what Paul Irish (who’s much smarter than me despite my disagreement here) told you to do.

CSS Lint

CSS Lint is a tool that’s supposed to help you write better CSS. It’s aimed at beginner and intermediate developers. The funny thing about CSS Lint in practice is that its so full of bad advice that its only really helpful for people who wouldn’t need it in the first place!

I won’t go into detail here because this article explains why CSS Lint is dangerous far better than I could. What I will say is that I do use it and I ignore most of its warnings. I usually scan them and use them as a kind og guideline to see if there’s any part of my CSS that I need to rethink. After reviewing my styles I usually figure that everything is going just fine. It’s rare that CSS Lint alerts me to a problem I didn’t know about or that there may be a better way of doing things.

The creator of CSS Lint is also the woman behind OOCSS (Object Oriented CSS). The idea behind OOCSS sounds great at first but then it sort of falls apart in practice. A better idea is what I like to call Module Oriented CSS. That’s a post for another day though.

People think that because other people are using CSS Lint and those people have popular projects on GitHub then those people must be smarter than them and therefore they too should be using and listening to this tool. This couldn’t be further from the truth. Don’t just blindly follow a linter. Become proficient in the language first. If you’re a beginner and blindly follow a linter’s rules without understanding them you’re opening yourself up to learning how to do things the wrong way without knowing it. If you’re proficient in a language and still blindly follow a linter’s rules you need to get rid of that imposter syndrome. Think about why you’re following those rules. Do you really want to never use an ID in your stylesheets? Ever? Like, they will never ever have a valid use and were invented by people who definitely were much smarter than us for a reason?

Semantics! Think of the semantics!

Everyone is all about the semantics these days. Semantics are great, don’t get me wrong, but just like any good thing too much can be bad. Semantic front-end code generally means that you’ve structured your markup and styling in such a way that the meaning of your content is decoupled from the way it looks. For example, a machine reading your web page can easily and accurately strip out the content and find the hierarchy, the main content, know which parts of the page are sidebars/tangentially related to the main content, etc. while humans are able to see that visually.

Achieving semantic zen to most people means using as few CSS classes and IDs as possible and when you do use them, name them after what they’re styling not how they’re styled (for example, .price-bucket describes a reusable widget that’s semantic while .red-button is a non-semantic class that could be called .cancel-button or something instead). This is a great goal but people take it too far. The new HTML5 elements are straightforward and easy to use. That doesn’t mean that if you use a wrapper div you’re a bad coder now, however.

One thing I’ve seen in the pursuit of semantics is the proliferation of grid systems build on CSS preprocessors. They claim that by using mixins instead of static classes your markup becomes more semantic. Well, that’s certainly true but at what expense? Let’s say your grid has this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Great for containing multiple rows with a full-page background
.container() {
  padding: 0 20px;
  width: 100%;
  .clearfix; // The micro-clearfix hack
}

// This element will contain any number of columns up to @total-cols
.row() {
  width: 100%;
  max-width: @max-width;
  min-width: @min-width;
  .clearfix;
  display: block;
  margin 0 auto;
}

// A single column in a row
.column(@colspan: @total-cols) { // Defaults to a column spanning the whole row
  width: (@total-cols / @colspan) * (100 / @total-cols) - @gutter;
  margin: 0 (@gutter / 2);
  float: left;
  &:last-child {
      // Some code to deal with the padding or margin of the last element in a row
  }
}

// Imagine we also have the micro-clearfix hack here as a mixin

Note: Don’t use this grid – it’s wrong. This is just an approximation of what SASS/LESS grid code looks like

Looking at the code above, in order to achieve a semantic layout you either need to painstakingly think about every element in your layout and have them all extend the .row and .column classes or you can do what most people do which is just add these mixins to elements one by one as they go. This results in you duplicating the .column and .row classes (at a minimum), far more times than you would have had you just used classes like a normal person.

Now, I love LESS grids. I made one. I studied a bunch of them. They’re awesome. But for me their real use is the ability to apply changes to an entire site by messing with a few variables, not in being semantic. A better solution, unless you have a very small site, is to just use normal .row, .container, and .column-x classes. If you have a 12 column grid then you’d have up to 12 classes that repeat themselves aside from the width rule. Big deal. Had you tried to go semantic you’d end up with far more than that.

What’s funny about this is that despite having actually saved yourself from duplicating rulsesets by taking your mixins and applying them to shortcuts (like .column-1 through .column-12) CSSLint will complain if you use more than 12 floats in your code. Okay, so fine. We’ll take the floats out of all of our column classes and do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.row() { ... } // The row mixin

.column(@colspan: @total-cols) { ... } // Column mixin without the float and display property

// Here's our new class that removes duplicat float and display rules
.col {
 float: left;
 display: block;
}

// Here is where you'd have shortcut/alias classes to your column mixin
// for cols 1 - 12 (or whatever number of columns your grid uses)
.col-2 { .column(2); }
.col-4 { .column(4); }
.col-6 { ... and so on ... }

Awesome. You’ve avoided the totally arbitrary “too many floats” rule (not sure why 10 was chosen as the limit but it was). Now your code can be better and more semantic. Before, your layout code looked awful, like this:

1
2
3
4
5
6
7
8
9
<div class="row">
  <article class="col-9">
      <h2>A Title</h2>
      <p>Here's my beautiful content..</p>
  </article>
  <aside class="col-3">
      <h3>Here's my sidebar!</h3>
  </aside>
</div>

Now, after being more semantic and also blindly following CSSLint’s rules you get markup that looks like this:

1
2
3
4
5
6
7
8
9
<div class="row">
  <article class="col col-9">
      <h2>A Title</h2>
      <p>Here's my beautiful content..</p>
  </article>
  <aside class="col col-3">
      <h3>Here's my sidebar!</h3>
  </aside>
</div>

So yeah, this isn’t much better. In fact, it’s downright annoying even if you don’t care about semantics. Why not just specify a column number and be done with it? Why litter your elements with a minimum of 2 classes each time you need a column?

This is just another example of some rules we blindly follow without thinking about why.

SEO. Where to start with SEO…

SEO is easy. Honestly. Unless you’re Amazon or eBay you only need to know a few rules:

  • No duplicate content
  • Pick a domain and forward all traffic there (i.e. either do no-www or yes-www)
  • Fill in the page description
  • No one cares about the keyword tag
  • Sprinkle relevant keywords in your content and choose anchor text deliberately (never use “click here”)

Mom and pop shops are hiring SEO consultants to revamp their websites. Those SEO consultants are happy to create a blog for “Mary’s Homemade Cupcakes” business along with a social media presence and the addition of bullshit keywords and links all over their site when really, all Mary needs is maybe a few pages that go over:

  • What her business sells
  • How to contact them (phone, email, address, and directions)
  • The history of the business

That’s it. No more no less. Maybe you can add links to Mary’s social media presence that she can run herself and post pictures of yummy cupcakes. The content of her site is something Mary knows best and it would simply write itself and be better than what any SEO person could come up with. All Mary needs is someone to stop bullshitting her and tell her to make it short and sweet and to include those 3 things on her site to start.

SEO is something that should come naturally if you know your domain. This site ranks highly for a handful of terms that I didn’t specifically try to target but still make complete sense. No time was spent meticulously crafting and SEO strategy and things worked out better than well.

Backpedal alert! I suppose this point should read more like “it’s important to know when heavy-duty SEO is necessary”. SEO is important. It is helpful. But its application is largely bullshit. Everyone who needs it doesn’t get it while people who don’t need it are clamoring for it.

Conclusion

All things considered, the people who dream up these rules mean well and are usually pretty smart (smarter than me or anyone reading this I’m sure). But blindly following these rules can have unintended consequences. I suppose that in the end, if you’re a newbie, it’s probably a better idea to follow these rules than to break them just because they don’t suit your purposes. But as you grow in experience it’s important that you eventually come to understand why these rules exist and how they actually work. It’s only when you understand these things that you can make an informed decision on when to follow them.

I fear that these rules and techniques and best practices we’ve created are insulating people from problems they’d otherwise face. Because they’re told to “just always copy this code” they do and their problems are solved leading them to believe they’re more skilled than they really are. When this happens there’s the chance those same people won’t take the next step to truly understand the problems being solved for them leading to the next generation of web developers who are cocky without having earned it. They’ll follow all the best practices to the T regardless of whether they apply to them or will benefit them. They’ll be forever telling others to use certain techniques because “that’s what good devs do”. What happens when a rule needs revision? What happens when it causes more harm than good? Who will be there to warn the rest of us?

On the other hand, without these same practices and rules and tools we’d be solving the same problems over and over again. I know I used to simply implement everything I saw in the HTML5 Boilerplate without understanding it. It took a few years before I even began to scratch the surface of those rules and techniques. Although I fear that few will take the time to ask the why’s of what we do I myself did just that. I’m not special either. So maybe, hopefully, everyone’s journey from beginner to expert eventually brings them to the point where they begin to delve into how the tools and techniques they use work. To really be proficient with a tool you need to understand how it works.

Web design, Web development

« Font Awesome Icons Showing Up as Squares Ignore Your Ruby Tooling »

Comments