SMACSS – Scalable and Modular Architecture for CSS

SMACSS Book Cover - Taken from smacss.comMany of you may already be aware of it, but in case not, I thought I’d point out that Jonathan Snook has released a site/ebook called Scalable and Modular Architecture for CSS or SMACSS (pronounced “smacks”). If you’ve read any of his previous stuff or had a chance to meet him at past events like South by Southwest Interactive, you know he’s a smart cookie, and nice to boot.

SMACSS is an interesting look into Jonathan’s process and structure, and as he puts it “a way to examine your design process and as a way to fit those rigid frameworks into a flexible thought process. It’s an attempt to document a consistent approach to site development when using CSS.”

I’ve personally spent a lot of time thinking about how I organize my CSS, so I love the opportunity to see the path that Jonathan has followed. We follow different practices in some cases (organization of attributes for example), but at a minimum, reading through his choices has caused me to think about the patterns I have set for myself.

Beyond the content, I love the fact that he’s sharing it publicly on the Web, in ebook format and via a third “Full Membership” option, so the information is freely available but he’s still able to profit from his efforts. I’ve signed up for that last option, in part to support him, but also because I’m excited to see what he’ll release to those members.

Image from the SMACSS site

Fixed-Width vs. Responsive, Connect Four vs. Twister

Fixed-width design isn’t going away, because it’s easy. It’s like playing the game Connect Four versus playing Twister. One is simple and straightforward, the other multivariate, so much so that you can’t really formulate a one-size-fits-all strategy. Which isn’t to say people shouldn’t endeavor to do responsive sites, just that they can’t expect the heavy lifting to be done for them.

Nathan Smith on Google Buzz for .Net Magazine’s next “Big Question

Chrome, Futura and Garbled Characters


For some reason Chrome on this machine (iMac running 10.6) doesn’t render Futura, which I use for my headlines, replacing it with extended characters. The site renders properly on MacBook Pro, which also runs 10.6. I’ve double-checked the character encoding and verified that removing Futura from the style sheet repairs the problem.

I’m digging in further, but if anyone out there knows of an explanation, I’d appreciate any help.

Pictos »

Using a font instead of images for icons is an interesting concept, which ensures that the icons are infinitely scalable and that the presentation can be easily changed on the fly without any extra page weight (even more so with CSS3).

I am curious where the tipping point lies in terms of page weight and render speed – 3 icons used, five…15? Either way, this is a really good start down an innovative path.

HTML5 Boilerplate »

As noted on the site, this is "the professional badass's base HTML/CSS/JS template for a fast, robust and future-proof site" While I likely won't use this whole, there are some very interesting pieces to this worth using, especially in the style sheet and .htaccess files. I'll likely appropriate many of the concepts for my work.

This is an outstanding contribution to the Web development community by Paul Irish and Divya Manian as well as all of the people whose work they built upon.

Compass »

"Compass is a stylesheet authoring framework that makes your stylesheets and markup easier to build and maintain. With compass, you write your stylesheets in Sass instead of CSS. Using the power of Sass Mixins and the Compass community, you can apply battle-tested styles from frameworks like Blueprint to your stylesheets instead of your markup."

Ruby must be on the system in order for the style sheets to be compiled, but the output doesn't require it.

Style Guides Using Sass @extend »

via @pengwynn. This is a smart use of Sass to define a separate style guide file for key presentation elements like fonts and colors that the designer can easily modify, while ensuring that the main style sheet can inherit all of those values.

This warms my front-end developer heart as I'm not fond of breaking up a site into separate style sheets for colors, spacing, fonts and the like as it becomes unmanageable or very cumbersome as everyone has to be aware of which files reference any given element, and should a significant change need to be made to the structure of the markup, it must be reflect throughout the site.

Type on the Web – An Evolutionary Shift

For designers and anyone interested in typography on the Web, I highly recommend you check out Web Font Specimen and the A List Apart article “Real Web Type in Real Web Context” that explains it. As we near a point where real typographic controls and options are available to us, its pivotal time for professionals to step up and gain (or remember) skills that haven’t been of use on the Web. The gap between good and great designs and designers will grow and the differences will be much more apparent at a glance and in the details.

If you haven’t had a chance to play with Typekit or learn about the various font embedding options (see The Potential of Web Typography: and Bulletproof @font-face Syntax) recently layered into browsers, now’s a good time to fatten up a few brain cells.

Reset Your Style

Eric Meyer has updated his reset style sheet, outlining the reasons for his change in the post Resetting Again. The modifications, while small, are logical and affirm how important the Reset sheet has become to Web professionals and amateurs alike. As Eric notes “this is more than just a throwaway development tool. It really is the beginning of a baseline style sheet. (Or can be.) Things like boldfacing and italics are some of the most obvious textual effects readers will see, and to have reset styles that treat them inconsistently across browsers doesn’t make sense.”

I use a variant of the reset style sheet in every site I build; the majority of those variants are now accounted for, making my life a bit easier. As always, Eric helps our profession move forward in a realistic way that is accessible to developers of all skill levels.

Style Evolution – Dynamic CSS Part 2

Please note that this assumes you have read Part One of the series.

Also, I have taken to calling this Evolved CSS, as the word “dynamic” is a bit too close to the old days of DHTML (Dynamic HTML) for my liking. Let’s jump right in shall we?

Files

Download this zip file if you would like to see a running example of this project and/or have a foundation for your experimentation.

Reduce Server Calls Without Sacrificing Ease of Maintenance and Organization

Web Developers follow many practices in their organization of style sheets. Some put everything in a single document, while others create separate style sheets for each of their major page types or templates. In addition, most seasoned professionals make use of a style sheet that resets all the browser rules (see Eric Meyer’s version) to make life easier.

And..?

Well, if you’re in the practice of using multiple style sheets, your sites may be taking longer to render than they need to, no matter how compressed your CSS may be. This is due to the fact that the browser needs to communicate with the server to snag each individual document, and most browsers only allow a few connections at a time. As noted on the Yahoo UI Blog, a lot of performance issues are directly related to front-end engineering. That’s actually a big win for those of us on the front-end as we don’t have to shell out for better servers or faster pipes. We can simply improve our code to make life easier for our users.

Example of HTTP Requests from FireBug
Their four-part article on reducing HTTP requests is lengthy, and may contain more details than you you’ll care about, so to break it down, here’s the key point in regards to this write-up: “Reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.” In the context of Evolved CSS, we can make a large impact by using PHP/ASP/JSP et al to take all of our style sheets and combine them into a single document.

The code

For this example, let’s assume your site has the following set up:

  • reset.css – Resets all styles to eliminate browser inconsistencies
  • core.php – Includes the global layout rules (navigation, header, content area etc.) and text formatting
  • scheme.php – The colors and images used for your site, this could easily be a script that provides the end-user the ability to choose their own colors.
  • home.css – Home-page specific layout/formatting rules.
  • archive.css – Layout and formatting rules for your archive pages.
  • gallery.css – The rules used to display your photo gallery.
  • print.css – Defines the layout for the page when it is sent to a printer.

You may have noticed the combination of PHP and CSS for those file types – you can easily use either as Part One demonstrated, but keep in mind that you should use flat CSS files over PHP where you are able to reduce the time required to process and render the final style sheet.

Section-Specific vs. the Kitchen Sink

Evolved CSS works well with the practice of using a single global style sheet to define your general layout and styles and section-specific style sheets to serve up rules that are unique to different areas of your site, as you can pass parameters to your main style sheet in order to define which style sheets to include. The Browser will still cache it. Here’s an example of how you could pass these parameters, in this case pulling in the styles for your gallery and a blue color scheme.


<link href="/css/style.php?include=gallery,blue-scheme" rel="stylesheet"
       type="text/css" media="screen" />

The file styles.php includes this code to take those parameters and pull in the appropriate style sheets:


/* -=-=-= Import Styles =-=-=- */
// Grab the parameters clean them up and add them to an array

$cssToInclude = split(',', makeSafe($_GET['include']));

/* -=-=-= Core Styles =-=-=- */
// Core will be included every time

include_once 'core.php';

/* -=-=-= Additional Styles =-=-=- */
// Check the array to determine which style sheets to include

if (in_array('home', $cssToInclude)) {
	include_once 'home.css';
}

if (in_array('gallery', $cssToInclude)) {
	include_once 'gallery.css';
}

if (in_array('archive', $cssToInclude)) {
	include_once 'archive.css';
}

That’s all You Need to Start

Well, this is a pretty short example, but I think it gets the poitn across and sheds some light on the possibilities available to you when you harness the power of server-side scripting languages to serve your CSS.

Note: This code is for example purposes only – it could be a lot cleaner, but at this point I am keeping it simple for explanation’s sake. I’m including the function makeSafe() to clean up the parameters. You can see the code in styles.php, contained in the source file package, if you are curious about it.

A Word on Media Types

This practice can only be used style sheets of the same media type – do not merge your screen style sheets with your print styles or you will get all sorts of ugliness.

What about priority and inheritance?

That’s a damn fine question! At this point, this structure works exactly the same as using multiple style sheets does. Most browsers will use the last rule defined, but you shouldn’t rely on that. As a good developer you should know where your conflicts may be and resolve them intelligently. The !important declaration can be used where needed to resolve specific conflicts.

Conclusion

Well, that about wraps it up for today kids, thanks for reading! Please leave your comments, suggestions and/or questions as I would love to expand the discussion. Also, I would love to hear your thoughts on what I should address next.

Future Evolved CSS Topics

  • Let the server do the math – auto-generating widths for your grid
  • Using Evolved CSS to improve debugging
  • CSS Compression

Dynamic CSS A.K.A. CSS Variables

Cascading Style Sheets are an amazing tool, having transformed Web Design as an industry and the Web as a communications medium. But in all of its glory (and it is glorious), CSS has some flaws. The most frustrating for me is its static nature. I want to be able to reuse values (CSS variables if you will), I want to make use of browser detection instead of CSS hacks, or IE’s proprietary conditional comments and I want to use logic to serve up specific rules in certain situations. Enter PHP (or your server-side langugage of choice), which will provide us a wealth of new options for working with our CSS, including the ability to adapt to our end-users’ needs.

Hello…. JavaScript Can Do That Already!

Yeah, client-side scripting can handle most of these requirements, but I don’t want to rely on a technology for my presentation that can be disabled by the user or their corporate IT department and frankly the JS support of mobile devices is poor at best. Enter server-side languages, which cover all of these bases without impacting the program or device rendering the site.

What I’ll Cover

The Setup

This article assumes that you have a Web server at your disposal that is running one of the aforementioned scripting languages and that you have a basic understanding of scripting in that language and know a bit about CSS. For the purpose of this write up I’ll be using PHP, but I have implemented versions of this system on production sites running JSP, and there’s no reason the same couldn’t be done with Ruby on Rails, Python, ASP or any other server-side solution.

This system can be as detailed or relaxed as you’d like, so I’m going to keep this write-up relatively simple with a few interesting bits thrown in. If it proves to be an interesting subject I’ll write a follow-up showing advanced usage. Let’s hit it!

Serving a Dynamic (PHP) File as CSS

In your editor of choice create a new PHP file. I’m calling mine styles.php. Paste this line at the very top of the document:


	<?php header('Content-type: text/css'); ?>

This tells the server that the page should be sent to the browser as a CSS document, so the file won’t need the .css extension. All of our work will be done in this bad boy. So, on to the next step.

Useful Variables and Practices

So, we have a PHP file that has a serious personality disorder, thinking that it’s a style sheet. What the hell are we going to do with it? Well, we’re going to set a few key variables that will make life much easier. Specifically, we’ll set variables for common measurements (columns, containers and the space between) and some colors from the site’s palette:



$gutter           = '10px';   /* Used to separate visual blocks */
$pageWidth        = '1000px'; /* Width of the Web page */
$pageWidthPadded  = '980px';  /* $pageWidth minus padding ($gutter x 2) */

$col1             = '800px';  /* Width of the main content area */
$col1Padded       = '780px';  /* $col1 minus padding ($gutter x 2) */
$col2             = '180px';  /* Width of the sidebar area */
$col2Padded       = '160px';  /* $col2 minus padding ($gutter x 2) */

$lightGray        = '#e5e5e5';
$charcoal         = '#464646';
$orange           = '#f60';
$darkBlue         = '#0059b2';

Dynamic CSS Illustration The width variables will prove useful in creating a site as they guarantee consistent presentation from page to page and template to template. This model can easily be extended for multiple column widths, so if you want to subdivide Column 1, you only have to set it up once, creating the variables ($col1A, $col1B etc.) and setting their values to the appropriate widths. For you folks who love them grids, this should make life pretty easy.

Setting up color variables simplifies the initial site build-out and future revisions. When you return to the style sheet six months from now, you’ll notice $darkBlue is much easier to remember than #0059b2.

So, now that we have width and colors, it’s simple to use these new variables in the style sheet, all you need to do is use PHP’s echo shortcut (<?= 'print this' ?>):


#Wrapper {
	background-color: <?= $lightGray ?>;
	border 1px dotted <?= $darkBlue ?>;
	margin: <?= $gutter ?>;
	width: <?= $pageWidth ?>;
}

Advanced: I’ve begun to separate the measurement value (px, em, pt) from the actual numerical value so I can harness the power of PHP to do my math for me. That’ll be the subject of a future write-up.

Implementing Browser Detection to Avoid CSS Hacks

I’ve used a couple of different packages in the past; at the moment I use BrowsCap, which covers these needs nicely, but use whatever fits your needs best. Place this code at the top of styles.php, after the PHP header line:


require_once('Browscap/Browscap.php');

// Create a new Browscap object (loads or creates the cache)
$bc = new Browscap('Browscap/cache/');

// Get information about the current browser's user agent
$current_browser = $bc->getBrowser(null,true);
$browser_platform	= $current_browser['Platform'];
$browser_name		= $current_browser['Browser'];
$browser_ver_major	= $current_browser['MajorVer'];
$browser_ver_minor	= $current_browser['MinorVer'];
$browser_ver_full	= $current_browser['Version'];

$is_ie6 = false;
$is_ie7 = false;
$is_safari = false;
$is_ff = false;

if ($browser_name == 'IE' && $browser_ver_major == 6) {
  $is_ie6 = true;
} elseif ($browser_name == 'IE' && $browser_ver_major == 7) {
  $is_ie7 = true;
} elseif ($browser_name == 'Firefox') {
  $is_ff = true;
} elseif ($browser_name == 'Safari') {
	$is_safari = true;
}

So we now have a few variables that will allow us to quickly determine whether the user’s browser is IE 6, IE 7, Firefox (any version) or Safari (any version). You can extend this model to fit your specific audience and needs.

Putting it All Together

Sweet, now we can rock the styles all dynamic-like! Here are a couple of examples for you to nibble on:


body {
<? if($browser_platform == 'MacOSX') { ?>
  font: .85em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } else { ?>
  font: .75em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } ?>

That block outputs a larger font size for folks who are on a Mac compared to folks on PCs or other devices.
The next one modifies the value of a top margin, serving up 5px for IE 6, and zero for all other browsers.


#NavWrapper1  {
  display: block;
  height: 18px;
  <? if ($is_ie6) { ?>
    margin-top: 0;
  <? } else { ?>
    margin-top: 5px;
  <? } ?>
  margin: <?= $gutter ?>;
  width: <?= $pageWidthPadded ?>;
}

Advanced: This method can be used to detect alternate browsers as well. So, you could detect a mobile browser and serve up a separate style sheet. Or if you detect a screen reader you could serve up a style sheet with proper aural rules defined.

That’s it, we’re rolling with dynamic CSS, harnessing the power of both PHP and Cascading Style Sheets. There is a lot more that can be done, but I hope this opened a few avenues for experimentation on your future projects.

In Moderation: Too Much Considered Harmful

It would be really easy to overuse this method. Do not try to replace proper use of grouping and the cascade with PHP. You won’t gain anything but frustration and larger style sheets. Take the time to think through the variables that you are going to create to make sure they make sense and are not simply recreating existing CSS functionality.

Acknowledgments

I am by no means the only person to think of this, there are many others who have covered the topic on their sites, but I felt that there were a few components missing, so here we are. I hope I added to your toolbox. It is also very important to note that there are some great folks with whom I’ve worked who have expanded on the concept and helped me flesh it out to be a viable and reusable tool in the Real World ™, most notably the inestimable Leesa of Red Velvet Cafe.

Your Turn

I look forward to your feedback and questions, so please leave a comment.

Firebug Beta 1 Released

The beta of Firebug 1.0 has been released and comes with some amazingly useful features. For those unfamiliar with this Firefox extension, Firebug provides a wealth of tools for developers to debug, monitor or edit portions of a site. Portions of it overlap the Web Developer’s toolbar, and in several cases, Firebug surpasses it hands down. Some of the features include:

  • Inspect & edit HTML & CSS within the browser to see how changes will impact the current page.
  • Visualize CSS metrics, including box model shading, measurements for each edge of a box (and the ability to edit those measurements in-line) , rulers and guides
  • Monitor network activity to see why a page takes too long to load, broken down by type. You can also see which items are cached or not and examine HTTP headers and XMLHTTP Requests.
  • Debug JavaScript, including the ability to set breakpoints and conditional breakpoints and line-at-a-time code execution. Additionally you can view JS stack traces broken down into the functions within the stack. Use tooltips to see the value of any variable within the JS, log function calls and profile the performance of the scripts. The improved JavaScript logging is amazing in its own right.
  • Explore the DOM and edit as you go (including auto-complete) with handy JS code navigation.
  • Vastly improved error handling and details.

This extension will actually reduce the need for several others you may have installed.