The Right Frame of Mind: Applying the Lessons of CSS Frameworks

In recent years, the web design and development world has undergone a transformation. Development frameworks—both on the server side (Rails, Django, CakePHP), and on the client side with JavaScript (jQuery, Prototype) and CSS (CSS Frameworks like Blueprint and the 960 Grid System)—have come to the fore, promising an increased level of productivity, less repeat coding for common functions, and, in the case of the client-side frameworks, an abstraction from browser inconsistencies. While server-side and JavaScript frameworks have been widely welcomed and accepted by developers, CSS frameworks have been much more controversial among designers.

While I happen to agree that CSS frameworks do come with a wide range of disadvantages (such as unnecessary bulk, additional HTTP requests, and the risk of becoming overly reliant on other developers’ code) and advantages (faster production times, fewer browser issues, easier development for beginners), their very existence provides us with an opportunity to re-examine how we write our own code. Ideally, if we can incorporate the best lessons of reusability, abstraction, and ease of use from these frameworks, we can avoid the need to use CSS frameworks by adapting our code to follow their ideals. CSS frameworks are simply a solution to problems web designers experience on a daily basis, enabling them to produce clean, agile, cross-browser code. Even though these tools have their own issues to contend with, they can serve as an excellent model to produce higher quality, more portable, and reusable CSS.

The purpose of this article isn’t to debate whether or not you should use a framework, but to examine why the need for such solutions exists. We’ll take the processes used (and lessons learned) in their creation, and try to show how they can be applied to your own style sheets. If you examine the source code of any framework, you’ll discover a world filled with innovative ways to increase the mobility of style and, as a result, increase your own productivity without the disadvantages that the use of third-party components commonly brings with it.

What’s in a Framework?

When producing CSS code for your own designs, you likely go through a very simple process of deciding how you want your HTML elements to appear. You might start by applying conventions that are inherited throughout the site (through element selectors), and once this has been completed you then hook on enough class and id selectors to style the individually distinct parts of the site. This of course requires time and effort, and if you produce more than one website, you’ll soon find yourself repeating certain conventions (such as column layouts, typography defaults, or perhaps even the way in which your navigation menus appear).

The problems frameworks try to solve can be divided into three groups:

Browser quirks

All browsers treat CSS differently; anyone who’s had the misfortune of coding for Internet Explorer 6 can tell you that. One aspect of CSS that most designers regularly tackle is the set of flaws and quirks that browsers suffer, both in how the browsers implement CSS code and in their support for varying levels of the CSS specifications.

Common components

Conventions exist for a reason: they provide designs that users can adapt to quickly. Sign-up forms, warning and error notifications, articles and their associated meta-data—all can have a set of common design features. Because such components are written over and over, you may find yourself spending time simply retreading old ground.

Repeat properties

Code bloat is a major issue in any development effort and CSS is no different: as we layer more and more style into our designs, we may find ourselves reusing CSS properties in a hundred different ways, many of which could have the same value. Some designers choose to group their code; however, it’s still very much an issue of tentative style application.

These issues are faced by all designers who use CSS, and if you choose not to use a framework you still have to address them in your work. If we’re careless, we wind up spending a great deal of time reinventing the wheel. Sometimes this is out of need, while other times it’s because we find ourselves replicating a design convention over and over in the interest of usability. Examining our own code to make the kinds of optimizations and refinements that could help resolve these issues is often our last consideration when working on a project. However, as I hope to show you, CSS libraries lavish care and attention to ensure the code is as durable and compatible as possible.

Under the Knife

To better understand how CSS libraries go about producing components that can be reused or applied to a wide number of designs (thereby speeding up the development process and lowering the amount of work you need to do), we should take a close look at their source code. What I’ll try to do here is highlight the ways in which frameworks make use of the various CSS selector types to set out their conventions and hooks.

note: Libraries We’ll Be Examining

The CSS libraries used as the basis for examining how they function include: 960 Grid System, Blueprint, BlueTrip, Elements, Emastic, Eric Meyer Reset, SenCSs, Tripoli, Typogridphy, YUI Grids, and YAML (Yet Another Multicolumn Layout).

Method One: Reset

Almost all of the CSS frameworks inspected use some manner of reset mechanism. The CSS reset mechanism takes every element in the HTML specification that’s given a default styling by certain browsers, and overrides those styles with nil values (thereby resetting them to “unstyled” defaults).

Method

Uses element and occasional wildcard (*) selectors to apply browser-wide style.

Used by

960, Blueprint, BlueTrip, Elements, Emastic, EMR, SenCSs, Tripoli, Typogridphy, YUI, YAML

Reasoning

By removing any default styles, reset mechanisms reduce the amount of rendering inconsistencies and quirks that can occur between browsers.

Example:

From the Eric Meyer Reset:

html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, font, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center, dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td {  margin: 0;  padding: 0;  border: 0;  outline: 0;  font-size: 100%;  vertical-align: baseline;  background: transparent;}body {  line-height: 1;}ol, ul {  list-style: none;}blockquote, q {  quotes: none;}/* remember to define focus styles! */:focus {  outline: 0;}/* remember to highlight inserts somehow! */ins {  text-decoration: none;}del {  text-decoration: line-through;}/* tables still need 'cellspacing="0"' in the markup */table {  border-collapse: collapse;  border-spacing: 0;}
The lesson

Even if you’re not using a framework, it’s important to be aware of the default styling that’s applied to certain elements by browsers. Forgetting to overwrite a property on an element-wide basis can often lead to confusing cross-browser issues down the road. You can develop your own set of reset styles or just keep a copy of the reset styles from a third-party framework on hand and drop them into each new project.

Method Two: Baseline Styles

Many CSS frameworks, in addition to resetting default browser styles, also introduce some new defaults. Unlike the browser defaults stripped away by the reset, these will be consistent and reliable across browsers, since they’re introduced by the framework itself. These new defaults provide a sensible baseline from which to start when you come to write your own styles.

Method

Uses element or attribute selectors to apply styles across every instance of an element.

Used By

960, Blueprint, BlueTrip, Elements, Emastic, SenCSs, Tripoli, Typogridphy, YUI, YAML

Reasoning

Baseline styles can reduce the amount of code needed in future development as the baseline aims to tackle common design-wide alterations.

Example

From the BlueTrip CSS Framework:

html { font-size: 62.5%; font-family: "Liberation Sans", Helvetica, Arial, sans-serif; }strong, th, thead td, h1, h2, h3, h4, h5, h6 { font-weight: bold; }cite, em, dfn { font-style: italic; }code, kbd, samp, pre, tt, var, input[type='text'], input[type='password'], textarea { font-size: 92%; font-family: monaco, "Lucida Console", courier, monospace; }del { text-decoration: line-through; color: #666; }ins, dfn { border-bottom: 1px solid #ccc; }small, sup, sub { font-size: 85%; }abbr, acronym { text-transform: uppercase; font-size: 85%; letter-spacing: .1em; }a abbr, a acronym { border: none; }abbr[title], acronym[title], dfn[title] { cursor: help; border-bottom: 1px solid #ccc; }sup { vertical-align: super; }sub { vertical-align: sub; }
The lesson

Have a look at your last few projects. Are there element-wide styles that you tend to use in every project? Look for a way to abstract out styles that you consistently apply to a given element or group of elements.

Method Three: id Hooks

Although rare in CSS frameworks—simply because their nature makes them less likely to be applicable across projects—id hooks are sometimes employed, most often when dealing with core page elements like the wrapper, header, navigation, or footer.

Method

Uses id attributes (HTML) and id selectors (CSS) for single-use components.

Usage

Elements, Emastic, Typogridphy, YUI, YAML

Reasoning

Many web pages wind up being made of the same core structural elements. If certain properties of those elements are consistent between projects, abstracting them out and using naming conventions can help to reduce repetition and save development time.

Example

Typogridphy Framework

#wrapper{  width:94em;  margin:0 auto;}#header{  width:94em;  padding-top:1.5em;  margin-bottom:2em;}#nav{  font-size:2em;}#nav a{  font-variant: small-caps;  color:#000;}#nav a:hover{  text-decoration: none;}#nav span{  float: right;  margin-top:-1.2em;}#footer-nav{  word-spacing:0.2em;}#footer-nav a{   color:#000;   font-variant: small-caps;}
The lesson

As with baseline styles, the key here is introspection. Look through your code and try to find repetition. Think of how you might build a set of styles that would make it easier to move those baselines into a new project while staying flexible and making it easy to overwrite them or choose between them as necessary.

Method Four: class Hooks

Far more common than id hooks, class hooks are found in just about every CSS framework. By providing a set of classes associated with predefined styles, they let you rapidly hook into tested styles while you’re writing your markup.

Method

Uses both class attributes and selectors to apply reusable styles.

Usage

960, Blueprint, BlueTrip, Elements, Emastic, SenCSs, Tripoli, Typogridphy, YUI, YAML

Reasoning

Whereas id hooks are generally used for elements having the same semantic purpose across different sites or projects, class hooks allow you to predefine certain groupings of styles; for example, pertaining to typography or layout. These can then be applied easily to any element in any project simply by adding the relevant class or classes.

Example #1

The 960 Grid System makes use of the class attribute to simplify the development of a grid structure. Any block or column can be assigned a .grid_x class to give it a width spanning x columns of the master grid:

.container_24 .grid_1{width:30px}.container_24 .grid_2{width:70px}.container_24 .grid_3{width:110px}.container_24 .grid_4{width:150px}.container_24 .grid_5{width:190px}.container_24 .grid_6{width:230px}.container_24 .grid_7{width:270px}.container_24 .grid_8{width:310px}.container_24 .grid_9{width:350px}.container_24 .grid_10{width:390px}
Example #2

Blueprint also uses a number of numerically named classes to set the width of grid elements, though there’s no reliance on a container like the 960 Grid System:

.span-1 {width: 30px;}.span-2 {width: 70px;}.span-3 {width: 110px;}.span-4 {width: 150px;}.span-5 {width: 190px;}.span-6 {width: 230px;}.span-7 {width: 270px;}.span-8 {width: 310px;}.span-9 {width: 350px;}.span-10 {width: 390px;}
Example #3

SenCSs uses class hooks for a different purpose; rather than relying on them for quick access to a predefined grid layout, it employs a set of classes for styling specific, frequently used UI notifications:

.error{  background:#fee;  border:1px solid red;  margin:1.5em;  padding:0.666em;  text-align:center;}.notice{  background:#eef;  border:1px solid #00f;  margin:1.5em;  padding:0.666em;  text-align:center;}.success{  background:#efe;  border:1px solid #0f0;  margin:1.5em;  padding:0.666em;  text-align:center;}.warning{  background:#ffe;  border:1px solid #ff0;  margin:1.5em;  padding:0.666em;  text-align:center;}
The lesson

This is a harder one. The types of styles from which you can build class hooks won’t always be packaged together by class if you look through your existing code. But you can still find chunks of code with strong potential for reuse. The goal, again, is abstraction. Imagine yourself hooking into these styles in a future project. If you can pull out a set of layout or typographic properties in a way that makes them easier to hook into, you can save yourself a lot of time in future development.

Portable Productivity

So we’ve seen some of the ways in which frameworks aim to make their code reusable. Maybe you now feel like developing your own framework, but even if you don’t, these lessons can be turned into productivity. I’ve laid out six simple rules to follow to optimize your code based on the lessons learned from the CSS frameworks we’ve studied:

Use name conventions

One of the main ways in which the studied frameworks allowed their styles to be quickly “plugged into” a new design was through the use of naming conventions. By naming your page elements consistently, you ensure that any styling you wish to reuse can be quickly dropped into place with little or no modification.

Plan for reuse

This is the key lesson that you should take from looking into the code of these CSS frameworks. What should be obvious to you is that these libraries are planned from the get-go to be used in wildly different contexts. Whether it’s establishing a set of sensible defaults, packaging generic typography definitions in a set of predefined class hooks, or preparing a more fully fledged class-based layout system, thinking ahead and planning for reuse is what will save you the most time and effort.

Fix common browser problems

IE6 makes some of us want to throw our hands up in the air and cry. CSS libraries are a fantastic example of how the appropriate treatment of common browser flaws can reduce the time required to debug your code, as certain basic fixes can easily be ported to new projects. A valuable lesson is that when bugs occur, there’s often a reusable way to work around them.

Structure and group code

Over time, code libraries become highly optimized, structured and enhanced for maximum flexibility, compatibility, and portability. In CSS we all too often use whatever does the job, rather than take the time to stress test or tweak our style so that it can be reused without having to restate it everywhere. The lesson: a bit of love and care will yield benefits, especially for ongoing site maintenance. Structuring your CSS in a logical manner will not only make reusing easier, it will also produce much more readable code.

Remove redundancy

While CSS libraries are often tightly packed, they usually have features you’d never use, leading to unnecessary bloat. In the context of your own style sheets, any reusable elements you stop using or have no need for doing a specific task can be removed on a case-by-case basis; this will save using bandwidth unnecessarily.

Document, document, document

Most libraries and frameworks are exceptionally well documented. The best lesson I believe we can draw from these tools is to always document your code. Mind, you should avoid having more comments than CSS (count those bandwidth calories!), but well-documented CSS makes maintenance and future development much less time-consuming, eliminating the need to spend time figuring out why you coded a solution in a certain way.

Summary

Throughout this article I’ve tried to highlight that CSS frameworks are very misunderstood creatures. They arose out of the need for general purpose solutions that are known to work and can be easily relied upon when starting a new design. I hope I’ve been able to show you the similarities these frameworks have to your own code, and how with a little care and attention you can turn your own CSS into code that works for you: doing the job better than a pre-written example, and making allowances for your projects’ needs while being flexible enough to be used in other designs.

CSS frameworks are a good role model that have unfortunately suffered bad press. I think if you strip away the buzz associated with them, and the laziness people seem to assume that their use implies, you can take away some practices that may help you become a better designer. Who knows, in a year you may have built your own library of useful snippets, which could be turned over to the community and added to the ever-evolving list of frameworks out there.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

No Reader comments

Comments on this post are closed.