Jun 042014
 

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

 Posted by at 6:39 pm  Tagged with:
Jun 252010
 

OK, so I feel it is officially time to kill IE 6 and below. IE 6 has been the bane of web developers’ existence for quite some time now. I say, just kill it. If your product manager whines and says “but we need to support all browsers” insist that they reconsider. Management and product managers don’t understand the real cost associated with supporting this awful browser. Many think that it’s simply a little more tweaking. It’s not. If they truly knew how bad it is they’d understand.

I also think that there’s a bigger picture here. If your site doesn’t work in IE6, it will actually propel people to upgrade. So don’t enable (“enable” as in, allow someone to continue their addiction) it and eventually people will get the picture.

The last site I built had IE6 traffic of 1.6%. I’m sure those people were at their corporate offices when they looked at the site. So they had to go home to their Macs and use Firefox or Safari. Big deal, I say.

I do think you should actually check for someone using the browser and tell them they suck. So, here’s a quick hack to put an end to IE 6 once and for all.

Assumption: You have a main div on your page that has an id of “main”. We need this to hide the whole page. If you’ve got it named something else, just change the id in the style definitions below. If you don’t have one at all, you’ll need to wrap all your existing content inside of the new div.

<body>
<div id=”main”>
the rest of your page content here
</div>
</body>

Stick this somewhere in your head tag. Make sure it comes BEFORE the IE-specific directives below it.

<style type=”text/css”>
#ie-upgrade {
 display: none;
}
</style>

Now put this after that:

<!--[if lte IE 6]>
<style type=”text/css” media=”screen”>
  #main {
   display: none;
  }
 
  #ie-upgrade {
   display: inline-block;
   color: white;    /* my site had a black background. remove this line if yours doesn’t */
   font-size: 650%;  /* was really trying to hammer it home */
   font-weight: bold;
   margin: 20px;
  }

  </style>
<![endif]-->

Finally, add this to your page after the <body> tag, but before (outside of) the “main” div discussed above.

<div id=”ie-upgrade”>This site is not supported in your version of Internet Explorer. Please upgrade to IE 7 or above, <a href=”http://www.mozilla.com/en-US/firefox/personal.html”>Firefox</a>, <a href=”http://www.apple.com/safari/download”>Safari</a>, or <a href=”http://www.google.com/chrome”>Chrome</a>.</div>

P.S. If you have Google Analytics code on your site, keep it outside the main div too.

 Posted by at 1:27 pm  Tagged with:
Mar 142010
 

Some experimentation with the text-overflow property.

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”
    “http://www.w3.org/TR/html4/strict.dtd”>
<html>
  <body>
<div style=”border: 1px solid red; max-width: 400px; overflow:hidden; text-overflow: ellipsis;”>
<nobr>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ac libero nec est luctus aliquam. Nulla sodales, dolor a consectetur volutpat, elit mi convallis sem, at ornare ligula odio non metus. </nobr>
</div>
</body>
</html>

Firefox 3.5

Safarai 4

IE 7

 Posted by at 6:04 pm  Tagged with:
Mar 022010
 

A little CSS pattern to demonstrate what to do when you want one column to stay at a fixed width and the other column to stretch horizontally with the window. Thanks to my friend CSS guru Joe Silvashy for this one.

What I want it a column on my right side to be a fixed width, and the column on the left to stretch with the window gracefully (in web terms this is called a “liquid” layout).

Given right-hand-column (in our example, a div tag with a class right-hand-column) has a fixed dimension (in our case), how do I get left-hand-column to take up the remaining amount of width within outter_div by letting the text wrap (instead of keeping it all on a single line).

On the left, I have a bunch of words. I want the words to linebreak when the left column isn’t wide enough to fit all the words on one line. My right-hand column is an image – a pic I ripped from whitehouse.gov – with a fixed height & width. So I want this column to always be the same width, and the left column to adjust based on the size of the browser window.

Here’s a beginners approach – and it doesn’t work. The approach is float right div to the right, left div to the left. Give right div a fixed with an left div no width at all.

As we’ll see in a minute, this is wrong and doesn’t work the way we want it to.

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
 “http://www.w3.org/TR/html4/loose.dtd”>
<html>
 <head>
  <meta http-equiv=”Content-type” content=”text/html; charset=utf-8″>
  <title>css_correct_width</title>
  <style type=”text/css” media=”screen”>
   div {
    margin: 4px;
   }
  
   .right-hand-column
   {
    border: solid blue;
    float: right;
    width: 306px;
    height: 371px;
    background-image: url(http://www.whitehouse.gov/sites/default/files/hero_feature/title_image/hero_bkgd_education-in-focus.jpg);
   }
  
   .left-hand-column
   {
    border: solid green;
    float: left;
   }
  </style>
 </head>

 <body id=”css_correct_width” onload=””> 
  <div id=”outter_div”>
   <div class=”right-hand-column”>
   
   </div>
 
   <div class=”left-hand-column”>
    <br />lorem ipsum dor amit. js oq xpqsqis aslsaldhq sdasasd.
   </div>
  </div>
 </body>
</html>

When there’s a wide window, right column takes up the width we assigned and left column takes up how ever much space it needs to fix the inline content on one line.

When there’s a narrow window, right column takes up the width we assigned and left still takes up how ever much space it needs keep that content, and drops the whole div down.

But this isn’t what I wanted. What I want is for my left column to always take up the remaining space after you subtract how much my right div (the image) needs. And while we’re at it, wrap the text so that it flows onto multiple lines.

Joe’s solution. (He included reset CSS, which I’ve removed [forgive me] for purposes of this demonstration. In your CSS, you must never forget the reset CSS.)

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
 “http://www.w3.org/TR/html4/loose.dtd”>
<html>
<head>
 <meta http-equiv=”Content-type” content=”text/html; charset=utf-8″>
 <title>css_correct_width</title>
 <style type=”text/css” media=”screen”>

 .right-hand-column
 {
  border: solid blue;
  width: 306px;
  height: 371px;
  background-image: url(http://www.whitehouse.gov/sites/default/files/hero_feature/title_image/hero_bkgd_education-in-focus.jpg);

  
  /* position absolute _inside_ a position relative allows for absolute positioning within an element and not the entire page */

  position:absolute;
  top:0;
  right:0;
 }

 .left-hand-column
 {
  border: solid purple;
  margin:0 320px 0 0; /* remember, top right bottom left */
 }
 </style>
</head>
<body>

 <div id=”outter_div”>

  <div class=”right-hand-column”></div>

  <div class=”left-hand-column”>
   <br />lorem ipsum dor amit. js oq xpqsqis aslsaldhq sdasasd.
  </div>

 </div>

</body>
</html>

What he’s done is to set the right column with absolute position to the right (top: 0; right: 0) and the left column with a right-hand margin of 320px (the width of the right column). This pushes it past the set width of the image on the right.

Note that the left column (the green one) now stretches to fill the remaining space in the window, whereas before it stayed at the width that was necessary to fit the text into the div (you can tell this because I put green border on it in all the examples).

Narrow window works the way we want it to.

 Posted by at 12:15 am  Tagged with:
Sep 222009
 

Symbols used in CSS

symbol name what for notes
. dot (period) denotes class value
# pound denotes id value
* star universal selector
space descendant selector
, comma group selector
: colon used for pseudo-classes only :hover and :active are supported by older IE versions; different pseudo-class support based on browser
> greater than child selector not supported by IE6 & earlier
+ plus adjacent selector CSS3 only
[ ] brackets attribute selector CSS3 only
 Posted by at 11:42 am  Tagged with: