An anti-pattern is a set of practices or habits (in the context of computer programming) that although are common and repeated are ultimately unhelpful or detrimental. Why anti-patterns form is beyond the scope of this blog post, but today I’d like to explore some practices I’ve seen in CSS that ultimately do more harm than they do good.

Some of these things could be chalked up to developer style, some are just things people do because that’s how they first learned to do them. Specifically, some of these grow out of developer organization style. When knowledge is segregated between different members of a project, specifically when front-end or “CSS skills,” belong to one individual or group, stuff gets written in an less-than-optimal way for re-use, extensibility, and general structure.

Many Agile and Scrum practitioners look down on segregation of skillset on the team, preferring a cross-functional team where everybody is seen as equally capable of taking on any part of the stack.

Building a modern user experience is a complex experience, and requires deep understanding of many parts of the stack. Because “back-end” devs don’t like CSS, or don’t get it, or are frustrated by it, often teams explore having either a specialist for doing the CSS or out-sourcing the front-end. You end up with an external design team delivering to a ‘sandbox’ version of your site with fully working CSS and ‘clickable pages.’

I recommend against this practice for several reasons. Chief among them is how problematic it is to “import” someone else’s CSS into the project I’m working on. There are several considerations, mostly concerning what it is like working on a large app, that design-oriented front-end devs typically don’t get. In the examples below I will speak in the context of Rails, but these ideas can apply to any back-end framework or language.

Basically, this is a list of CSS bad habits, and ways you should expand your knowledge of modern tools (particularly those available in Ruby) to avoid the pitfalls.

CSS Antipattern #1: Long, stringy blocks that have a lot of layout information

You’ve seen this code before. Heck, you’ve probably written. (I wrote CSS like this too once!). Everything on the DOM is targeted with a class or ID (also something to be wary of, see below), and the object you are targeting contains lots and lots of layout information specific to that “thing.”

.contact {
  display: block;
  position: relative;
  top: 20px;
  right: 5px;
  height: 20px;
  margin: 22px 0 19px;
  padding-right: 25px;
  border: 0 none;
  font-family: ‘OpenSans Semibold’;
  text-transform: uppercase;
  font-size: 15px;
  color: #FFF;
}

What don’t I like about this CSS? Well, first off, I really don’t like single, short class names (which is actually Antipattern #2, below). What you’ve done here is said “anything on my website with this class name should be positioned this way.” You’ve specified a lot of layout-related styles in your CSS. So what’s wrong with that? Well, layout related styles are often highly specific to the page the thing appears on. It is entirely conceivable that you could have more than one contact form appear on different parts of the site, and they invariably won’t share this CSS.

You should change your CSS- and the way you think about CSS- to de-couple the stylistic information (color, typography, font weight & shadow, etc) from the layout information (where it appears in relation to other things. In fact, let’s get right to the point here: If you’re writing a lot of CSS that looks like the example above, you probably aren’t using a grid system. Now, I realize this may be a controversial thing to say and grid systems are not right for all websites, but if you haven’t personally learned how to work within a responsive grid system I recommend you do so. Bootstrap, 960gs, and Blueprint are all popular suggestions, but there many out there. One factor when choosing a grid system is if it is written with LESS or SASS, which I will discuss further below.

Why are grid systems so great? Well, for one thing, they make everything easier. You actually don’t have to write as much layout-related CSS in general. Ultimately this becomes easier to work with and refactor later, and less likely to introduce CSS bugs (which, because visuals fundamentally cannot be tested with TDD, are the most common form of bugs when working on a UX-heavy site).

In the example above, display, position, top, and right all become unnecessary selectors. You may still have height, margin, and padding, but I will discuss some patterns below that will help make this style of CSS less repetitive. Finally, font-family, text-transform, font-size, and color are all inappropriate to go into the CSS selectors above – you should either use descriptive stylistic classes (classes that describe the style) or if you really don’t want to clutter up your HTML with extra (non-semantic) classes you can use mixins (with SASS or LESS) to achieve a clean minimally-repeated pattern describing style.

In short, if you see CSS where there large blocks with many layout-specific CSS attributes, you’re probably doing it wrong.

CSS Antipattern #2: Unscoped Simple Single-Word class selectors

As suggested above, something you see often in amateur CSS practioner’s websites are class names that are single words that do way more than they should. Specifically, when don’t scope your CSS to the page you are on at all and use very general words to describe your blocks, you are asking for trouble.

I’m talking about class names like contact, address, group. I’m not even a big fan of the commonly-seen global container boxes with class names like main, container, or page.

First, let’s discuss generally what CSS scope is. I assume the reader is familiar with the basic rules of CSS syntax (I wrote a helpful cheat sheet here).

In particular, before we move on, be sure that you understand the difference between using a space to separate your targets a > symbol.

div.page > section.article {

}
Direct descendant. Will apply styles only to a section with class “article” that is a direct child of a div with a “page” class.
div.page section.article {

}
Any descendant. Any section with a “article” class that is contained within a div with a class “page” will pick up these styles.

In the old days we couldn’t use the direct descendant selector > if we wanted to target old browsers (like IE6), but since IE7 the direct descendant is universally supported so I believe it can be implored as a central tool in our structuring our CSS. Here, I will offer two different patterns (you would adopt either one or the other, not both) for thinking about a general strategy for structuring your CSS.

With this knowledge, consider two possible scooping patterns.

CSS Scoping Pattern #1. Block-Element-Modifier

The Block-Element-Modifier pattern employs use of a general block element of the page, the name of the element you are targeting, and information you might need to modify the state of the element. This pattern likes the use of double underscores between the block and the element and double-dashes between the element and the modifier.

You wind up getting css that looks like this:

.widget__input-amount {
  border: 1px solid #930;
}

Since a lot has already been written about the BEM pattern, I’m not going to go into detail, but point you to this good post about BEM.

CSS Scoping Pattern #2: Controller & Action names on your body element

<html>
<body class=”<%= controller_name %> <%= action_name %>”>

Here’s a Rails example of how to add an automatic output of your controller and action name as class names to every page on your site. Then, you can easily specify which pages you want your CSS to apply to. Here, I’ve specified in SASS that I want the section with a class of address to have a box around it only on my “About Us” page (which, presumably, can be gotten to from the about action on the pages controller).

I know that another developer won’t come along carelessly adding a section with a class “address” somewhere else in the app and wonder why it has a grey box around it. 

body.pages.about
 section.address
  border: solid 1px gray

In general, I recommend always scoping your CSS to at least the part app you are targeting, and even better to the specific page it will appear on.

But what if you really, really want a globally applied style, like, for example, your address appears several places throughout the site and you want all of those places to have a consistent look? Use a single class name with many styles attached (as discussed above, preferably not layout styles) sparingly, and know that you yield great power when you do so. Consider not using very generic words in the dictionary (like address, which could be interpreted as the business owner’s address or the customer’s address), instead choosing to specify with some unique namespace that is very unlikely to ever cause conflict. For example, rg-our-address, imagining that “rg” is the fictitious initials resembling something like the website domian name company name. It’s highly likely someone will want to use a generic word like address as class name, but nearly impossible someone will inadvertently use rg-our-address in the future.

CSS Antipattern #3: Repetitive CSS

This may seem like a no-brainer, but keep things DRY in your CSS. If you find that you are writing the same sets of code again and again, use CSS better, or use LESS or SASS variables.

In SCSS, a variable would look like this:

$font-stack:  Helvetica, sans-serif;
$primary-color: #333;

body {
 font: 100% $font-stack;
 color: $primary-color;
}

Less has a very similar variable syntax that uses @ symbols instead of $.

See also:

Extending Paul Irishs comprehensive DOM-ready execution

By Jason

Leave a Reply

Your email address will not be published. Required fields are marked *