CSS

Equal Height Column Layouts with Borders and Negative Margins in CSS

Smashing-magazine-advertisement in Equal Height Column Layouts with Borders and Negative Margins in CSSSpacer in Equal Height Column Layouts with Borders and Negative Margins in CSS
 in Equal Height Column Layouts with Borders and Negative Margins in CSS  in Equal Height Column Layouts with Borders and Negative Margins in CSS  in Equal Height Column Layouts with Borders and Negative Margins in CSS

“What? Another “Equal Height Columns” article? Enough already!” If this is what you think, then think again because this solution is different. It does not rely on any of the usual tricks. It does not use images, nor extra markup, nor CSS3, nor pseudo-classes, nor Javascript, nor absolute positioning. All it uses is border and negative margin. Please note that this article will also demonstrate different construct techniques and will brush up on a few concepts.

1. Centering columns without a wrapper div

This layout will be built without a wrapper div:

Screenshot-1 in Equal Height Column Layouts with Borders and Negative Margins in CSS

The basics

We use the background of body and the border of one of the columns to create background colors that vertically fill the “row”.

The markup

<div id="header">
	<h2><a href="#">Header</a></h2>
	<p>Lorem ipsum...</p>
</div>

<div id="sidebar">
	<h2><a href="#">Sidebar</a></h2>
	<p>Lorem ipsum...</p>
</div>

<div id="main">
	<h2><a href="#">Main</a></h2>
	<p>Lorem ipsum...</p>
</div>

<div id="footer">
	<h2><a href="#">Footer</a></h2>
	<p>Lorem ipsum...</p>
</div>

Tip: always include links within your dummy text to spot stacking context issues.

About using body as a wrapper:

  • always style html with a background to prevent the background of body from extending beyond its boundaries and be painted across the viewport.
  • never style html with height: 100% or the background of body will be painted no taller than the viewport.

The CSS

html {
  background: #9c9965;
}

body {
  width: 80%;
  margin: 20px auto;
  background: #ffe3a6;
}

#header {
  background: #9c9965;
}

#sidebar {
  float: left;
  width: 200px;
  background: #d4c37b;
}

#main {
  border-left: 200px solid #d4c37b;
}

#footer {
  clear: left;
  background: #9c9965;
}

What do these rules do exactly?

  • We style html with a background to prevent the browser from painting the background color of body outside our layout.
  • We style body with auto margin to center the layout; the width is set using percentage. The background declaration is for #main.
  • We style the background of #header to mask the background color of body (the same goes for #footer).
  • The background color of #sidebar matches the border color of #main. This is the trick we use to make our columns appear as being of equal height.
  • The footer clears any previous float so it stays below the columns, at the bottom of the layout.

If you take a look at this first step, you’ll notice that the heading in #sidebar is not vertically aligned with the heading in #main and that we have some gap at the top and bottom of the #sidebar. This is because out of these two containers, only one is a block formatting context. So margins do not collapse in #sidebar while they do in #main. This also means that #main will not contain floats and that applying clear:left to any nested element in there will clear #sidebar as well.

So to prevent any float and margin collapsing issues we make all the main boxes block formatting contexts.

#header,
#footer {
  overflow: hidden;
  zoom: 1;
}

#main {
  float: left;
}

#sidebar {
  margin-right: -200px;
}

Note: if things look a bit different in IE 6 and 7 it is because in these browsers default margins do collapse inside block-formatting contexts. The following should also be considered:

  • overflow and zoom on #header and #footer make these elements new block formatting contexts.
  • For #main we use float rather than overflow to prevent potential issues if we had to offset some nested content.
  • The negative margin keeps #main into place because now that it is a float, its border box comes next to the margin box of #sidebar (the negative vlaue must match the dimension of the said box).

If you look at the second step, you’ll see that the border of #main hides #sidebar. This is because of the stacking context. In the flow (tree order), #main comes after #sidebar so the former overlaps the latter.

Positioning #sidebar brings it up in the stack.

#sidebar {
  position: relative;
}

Note: if you make #main a new containing block you’ll revert to the original stack order. In this case, you’ll need to use z-index to keep #sidebar on top of #main.

If you look at step three, you’ll see that we are almost there. The last things to do are mostly cosmetic. I’ve inserted a base styles sheet:

<link rel="stylesheet" type="text/css" href="http://tjkdesign.com/ez-css/css/base.css">

and then added these rules:

html {
  height: auto;
}

body {
  border: 1px solid #efefef;
}

#header,
#main,
#sidebar,
#footer {
  padding-bottom: 2em;
}

Why do we need these rules?

  • We can reset the height on html so the background of #main is not cut-off at the fold (this styling is inherited from the base styles sheet).
  • We can draw a border all around the layout.
  • Because the base styles sheet only sets top margins, we can create gaps at the bottom of the main boxes via padding.

Note: The rule for html is shown here, but it makes more sense to remove that rule from the base styles sheet rather than overwriting the declaration here.

This is the last step for this first layout. It relies on these simple rules:

html {
  height: auto;
  background: #45473f;
}

body {
  width: 80%;
  margin: 20px auto;
  background: #ffe3a6;
  border: 1px solid #efefef;
}

#sidebar {
  float: left;
  position: relative;
  width: 200px;
  margin-right: -200px;
  background: #d4c37b; /* color must match #main's left border */
}

#main {
  float: left;
  border-left: 200px solid #d4c37b; /* color must match #sidebar's background */
}

#header,
#footer {
  clear: left;
  overflow: hidden;
  zoom: 1;
  background: #9c9965;
}

#header,
#main,
#sidebar,
#footer {
  padding-bottom:2em;
}

2. Creating a 2-col-layout with two borders in between the columns

We’ll build this one with a single wrapper for our two columns, and we want to paint a vertical border between the two columns.

Screenshot-2 in Equal Height Column Layouts with Borders and Negative Margins in CSS

The basics

The wrapper div allows us to be a bit more creative here. The background of the wrapper is used to paint the background of one column, while its left border is used to paint the background color of the other column. The vertical border will be done by overlapping the right border of the left column with the left border of the right column.

Note: if you have use a fixed width layout (vs. fluid like here), then the wrapper can be used to create the two background colors as well as the vertical border at the same time. This is done by using the left border for the left column, the right border for the right column and the background for the vertical border. Yes, this means the content box is one pixel wide and that negative margins are used to pull the columns into place.

Markup

<div id="header">
	<h2><a href="#">Header</a></h2>
	<p>Lorem ipsum...</p>
</div>

<div id="wrapper">
  <div id="sidebar">
  	<h2><a href="#">Sidebar</a></h2>
  	<p>Lorem ipsum...</p>
  </div>
  <div id="main">
  	<h2><a href="#">Main</a></h2>
  	<p>Lorem ipsum...</p>
  </div>
</div>

<div id="footer">
	<h2><a href="#">Footer</a></h2>
	<p>Lorem ipsum...</p>
</div>

CSS

We start with the generic rules from the previous demo:

html {
  background: #45473f;
}

body {
  width: 80%;
  margin: 20px auto;
  background: #ffe3a6;
}

#header,
#footer {
  overflow: hidden;
  zoom: 1;
  background: #9c9965;
}

#sidebar {
  float: left;
  width: 200px;
}

#main {
  float: left;
}

To which we add position: relative:

#wrapper {
  display: inline-block;
  border-left: 200px solid #d4c37b;
  position: relative;
}

#sidebar {
  margin-left: -200px;
  position: relative;
}

Note: there is no need to use clear on the footer since #wrapper contains both floats.

  • Rather than using overflow/zoom, we use inline-block to create a new block formatting context (this declaration also triggers hasLayout). The left border will paint a background color behind #sidebar.
  • Negative margin is used to bring #sidebar outside the content box of the parent’s container (to make it overlap the border of #wrapper).

The case of IE6: If the above rules use position: relative (twice), it is because of IE 6. It is applied on #wrapper to prevent #sidebar from being clipped outside of its content box. It is also applied on #sidebar to make sure that the elements are “always” painted with the proper offset.

If you look at this first step, you’ll see that we have everything working, but the vertical border is in between the columns. You should also notice that in browsers other than IE 6 and 7, there is a small gap at the bottom of #sidebar (at the bottom #wrapper actually). This is because #wrapper is styled with inline-block so it is sitting on the baseline of the line box. The gap you see is the “descender space” (the space reserved for descenders in lowercase letters).

So these are the rules to remove the gap and create the vertical border:

#wrapper {
  vertical-align: bottom;
}

#sidebar {
  margin-right: -1px;
  border-right: 1px solid #888;
}

#main {
  border-left:1px solid #888;
}

What do these rules do?

  • vertical-align: bottom makes #wrapper sit at the bottom of the line box rather than the baseline.
  • the two borders (for #sidebar and #main) overlap because of the negative right margin set on #sidebar. This overlap guarantees that this “common” border will be as tall as the tallest column.

If you look at step two, things look much better. The last things to do is to add the base styles sheet and the same rules we used at the end of the first demo:

<link rel="stylesheet" type="text/css" href="http://tjkdesign.com/ez-css/css/base.css">

and then add these rules:

html {
  height: auto;
}

body {
  border: 1px solid #efefef;
}

#header,
#main,
#sidebar,
#footer {
  padding-bottom: 2em;
}

This last demo for this layout includes the above rules.

3. Creating a three column layout with a border in between the columns

We’ll build a layout with a single #main-wrapper, one containing all the divs. This approach complicates things a bit, but it also allows to tackle new challenges. Please note that with this layout, the vertical borders will not show in IE 6 and 7.

Screenshot-3 in Equal Height Column Layouts with Borders and Negative Margins in CSS

The basics

We use the wrapper to create the background of the three columns. The left and right borders of the wrapper will be used for the two side bars while its background will be used for the main content.

The markup

<div id="wrapper">
  <div id="header"><h2><a href="#">Header</a></h2><p>Lorem ipsum...</p></div>
  <div id="sidebar"><h2><a href="#">Sidebar</a></h2><p>Lorem ipsum...</p></div>
  <div id="aside"><h2><a href="#">Aside</a></h2><p>Lorem ipsum...</p></div>
  <div id="main"><h2><a href="#">Main</a></h2><p>Lorem ipsum...</p></div>
  <div id="footer"><h2><a href="#">Footer </a></h2><p>Lorem ipsum...</p></div>
</div>

CSS

We start with the generic rules from the previous demos:

html {
  background: #45473f;
}

body {
  width: 80%;
  margin: 20px auto;
  background: #ffe3a6;
}

#header,
#footer {
  overflow: hidden;
  zoom: 1;
  background: #9c9965;
}

#sidebar {
  float: left;
  width: 200px;
}

#main {
  float: left;
}

To which we add:

#wrapper {
  border-left: 200px solid #D4C37B;
  background-color: #ffe3a6;
  border-right: 200px solid #D4C37B;
}

This code sets the background color for the three columns. In the same sequence as the above declarations.

If you look at this first step, you’ll see that we have achieved the background effect we are looking for, but things look pretty broken. Everything shows inside the wrapper’s content box.

These next rules should fix the display of the three columns (zoom: 1 for the #wrapper and position: relative for #sidebar and #aside):

#wrapper {
  zoom: 1;
}

#sidebar {
  margin-left:-200px;
  position: relative;
}

#aside {
  float: right;
  width: 200px;
  margin-right: -200px;
  position: relative;
}

#aside is given a width and floated to the right. The negative margins pull each side bar over the wrapper’s border — outside of the content box.

Note:IE 6 and 7 needs #wrapper to have a layout, hence the use of zoom. IE 6 needs the two position declarations for the same reason as in the previous demos.

If you look at step two, you’ll see that #header does not stretch across the entire layout and that #footer is nowhere to be found.

These two rules should take care of everything:

#header,
#footer {
	margin-left: -200px;
	margin-right: -200px;
	position: relative;
}

#footer {
  clear: both;
}

The negative margin on both sides of #header and #footer stretches the two boxes outside of the wrapper’s content box. clear:both makes the footer clears all the columns. This is step three.

Once again, the position declaration is for IE 6. Just remember to always position elements that you offset.

What’s next?

You know the drill. We insert a base styles sheet in the document:

<link rel="stylesheet" type="text/css" href="http://tjkdesign.com/ez-css/css/base.css">

and add the usual:

html {
  height: auto;
}

body {
  border: 1px solid #efefef;
}

#header,
#main,
#sidebar,
#footer {
  padding-bottom: 2em;
}

Step four shows how things look before we tackle the vertical borders.

Adding vertical borders

The following technique is inspired from the companion columns technique (Ingo Chao) and the Nicolas Gallagher method.

To get the effect we want (two borders touching each other), we use generated content to which we apply a background color and a border.

The CSS

html:before {
	content: ".";
	position: absolute;
	height: 20px;
	background: #45473f;
	left: 0;
	right: 0;
	z-index: 2;
}

body {
  border-top: 0;
}

#header {
  border-top: 1px solid #fff;
}

#wrapper {
  position: relative;
}

#header,
#footer {
  z-index: 1;
}

#wrapper:before,
#wrapper:after {
  content: ".";
  position: absolute;
  width: 1px;
  height: 2000px;
  background: #9c9965;
  bottom: 0;
}

#wrapper:before {
  left: 0;
  border-left: 1px solid #fff;
}

#wrapper:after {
  right: 0;
  border-right: 1px solid #fff;
}

body {
	position: relative\9;
	z-index: -1;
}

OK, so what’s going on here?

  • The fake borders get out of the container (at the top), so the first rule paints generated content on top of them. Note that we would not need this rule if the color of the fake borders was the same as the page’s background (html), or if there was no gap between the top of the viewport and the layout.
  • Because these borders are painted over the border around body, we move the top border from body to #header.
  • To properly position the fake borders, we need to make the wrapper the containing block for the generated content.
  • We bring #header and #footer above the stack so they hide the fake borders which are painted inside the wrapper (from bottom to top).
  • This is the generated content we use to create the columns.

The case of IE 8: The last rule is for IE 8. Without this, IE 8 would not paint the generated content over the borders that escape the wrapper (at the top). If this declaration is sandboxed via the “\9″ hack, it is because Gecko browsers would make everything unclickable/unselectable.

Note: these pseudo-classes are not supported by IE 6 and 7, so in these browsers, there are no borders between the columns.

Things to consider

The third layout uses one main wrapper, but it would make more sense to use a inner wrapper instead to hold only the columns. In case this route was taken here, then it was only for those of you who are stuck with this type of construct, but want to implement this solution for equal height columns.

When absolutely positioning elements inside a containing block with wide columns like in the last two demos, remember that the reference is the padding box, so 0 for right or left may not be the value you would want to use.

Further reading

(ik) (vf)


© Thierry Koblentz for Smashing Magazine, 2010. | Permalink | Post a comment | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: , , ,


!important CSS Declarations: How and When to Use Them

Smashing-magazine-advertisement in !important CSS Declarations: How and When to Use ThemSpacer in !important CSS Declarations: How and When to Use Them
 in !important CSS Declarations: How and When to Use Them  in !important CSS Declarations: How and When to Use Them  in !important CSS Declarations: How and When to Use Them

When the CSS1 specification was drafted in the mid to late 90s, it introduced !important declarations that would help developers and users easily override normal specificity when making changes to their stylesheets. For the most part, !important declarations have remained the same, with only one change in CSS2.1 and nothing new added or altered in the CSS3 spec in connection with this unique declaration.

Overriding-styles-2 in !important CSS Declarations: How and When to Use Them

Let’s take a look at what exactly these kinds of declarations are all about, and when, if ever, you should use them.

A Brief Primer on the Cascade

Before we get into !important declarations and exactly how they work, let’s give this discussion a bit of context. In the past, Smashing Magazine has covered CSS specificity in-depth, so please take a look at that article if you want a detailed discussion on the CSS cascade and how specificity ties in.

Below is a basic outline of how any given CSS-styled document will decide how much weight to give to different styles it encounters. This is a general summary of the cascade as discussed in the spec:

  • Find all declarations that apply to the element and property
  • Apply the styling to the element based on importance and origin using the following order, with the first item in the list having the least weight:
    • Declarations from the user agent
    • Declarations from the user
    • Declarations from the author
    • Declarations from the author with !important added
    • Declarations from the user with !important added
  • Apply styling based on specificity, with the more specific selector “winning” over more general ones
  • Apply styling based on the order in which they appear in the stylesheet (i.e., in the event of a tie, last one “wins”)

With that basic outline, you can probably already see how !important declarations weigh in, and what role they play in the cascade. Let’s look at !important in more detail.

Syntax and Description

An !important declaration provides a way for a stylesheet author to give a CSS value more weight than it naturally has. It should be noted here that the phrase “!important declaration” is a reference to an entire CSS declaration, including property and value, with !important added (thanks to Brad Czerniak for pointing out this discrepancy). Here is a simple code example that clearly illustrates how !important affects the natural way that styles are applied:

#example {
	font-size: 14px !important;
}

#container #example {
	font-size: 10px;
}

In the above code sample, the element with the id of “example” will have text sized at 14px, due to the addition of !important.

Without the use of !important, there are two reasons why the second declaration block should naturally have more weight than the first: The second block is later in the stylesheet (i.e. it’s listed second). Also, the second block has more specificity (#container followed by #example instead of just #example). But with the inclusion of !important, the first font-size rule now has more weight.

Some things to note about !important declarations:

  • When !important was first introduced in CSS1, an author rule with an !important declaration held more weight than a user rule with an !important declaration; to improve accessibility, this was reversed in CSS2
  • If !important is used on a shorthand property, this adds “importance” to all the sub-properties that the shorthand property represents
  • The !important keyword (or statement) must be placed at the end of the line, immediately before the semicolon, otherwise it will have no effect (although a space before the semicolon won’t break it)
  • If for some particular reason you have to write the same property twice in the same declaration block, then add !important to the end of the first one, the first one will have more weight in every browser except IE6 (this works as an IE6-only hack, but doesn’t invalidate your CSS)
  • In IE6 and IE7, if you use a different word in place of !important (like !hotdog), the CSS rule will still be given extra weight, while other browsers will ignore it

When Should !important Be Used?

As with any technique, there are pros and cons depending on the circumstances. So when should it be used, if ever? Here’s my subjective overview of potential valid uses.

Never

!important declarations should not be used unless they are absolutely necessary after all other avenues have been exhausted. If you use !important out of laziness, to avoid proper debugging, or to rush a project to completion, then you’re abusing it, and you (or those that inherit your projects) will suffer the consequences.

If you include it even sparingly in your stylesheets, you will soon find that certain parts of your stylesheet will be harder to maintain. As discussed above, CSS property importance happens naturally through the cascade and specificity. When you use !important, you’re disrupting the natural flow of your rules, giving more weight to rules that are undeserving of such weight.

If you never use !important, then that’s a sign that you understand CSS and give proper forethought to your code before writing it.

That being said, the old adage “never say never” would certainly apply here. So below are some legitimate uses for !important.

To Aid or Test Accessibility

As mentioned, user stylesheets can include !important declarations, allowing users with special needs to give weight to specific CSS rules that will aid their ability to read and access content.

A special needs user can add !important to typographic properties like font-size to make text larger, or to color-related rules in order to increase the contrast of web pages.

In the screen grab below, Smashing Magazine’s home page is shown with a user-defined stylesheet overriding the normal text size, which can be done using Firefox’s Developer Toolbar:

User-style-sheet in !important CSS Declarations: How and When to Use Them

In this case, the text size was adjustable without using !important, because a user-defined stylesheet will override an author stylesheet regardless of specificity. If, however, the text size for body copy was set in the author stylesheet using an !important declaration, the user stylesheet could not override the text-size setting, even with a more specific selector. The inclusion of !important resolves this problem and keeps the adjustability of text size within the user’s power, even if the author has abused !important.

To Temporarily Fix an Urgent Problem

There will be times when something bugs out in your CSS on a live client site, and you need to apply a fix very quickly. In most cases, you should be able to use Firebug or another developer tool to track down the CSS code that needs to be fixed. But if the problem is occurring on IE6 or another browser that doesn’t have access to debugging tools, you may need to do a quick fix using !important.

After you move the temporary fix to production (thus making the client happy), you can work on fixing the issue locally using a more maintainable method that doesn’t muck up the cascade. When you’ve figured out a better solution, you can add it to the project and remove !important — and the client will be none the wiser.

To Override Styles Within Firebug or Another Developer Tool

Inspecting an element in Firebug or Chrome’s developer tools allows you to edit styles on the fly, to test things out, debug, and so on — without affecting the real stylesheet. Take a look at the screen grab below, showing some of Smashing Magazine’s styles in Chrome’s developer tools:

Overriding-styles in !important CSS Declarations: How and When to Use Them

The highlighted background style rule has a line through it, indicating that this rule has been overridden by a later rule. In order to reapply this rule, you could find the later rule and disable it. You could alternatively edit the selector to make it more specific, but this would give the entire declaration block more specificity, which might not be desired.

!important could be added to a single line to give weight back to the overridden rule, thus allowing you to test or debug a CSS issue without making major changes to your actual stylesheet until you resolve the issue.

Here’s the same style rule with !important added. You’ll notice the line-through is now gone, because this rule now has more weight than the rule that was previously overriding it:

Overriding-styles-2 in !important CSS Declarations: How and When to Use Them

To Override Inline Styles in User-Generated Content

One frustrating aspect of CSS development is when user-generated content includes inline styles, as would occur with some WYSIWYG editors in CMSs. In the CSS cascade, inline styles will override regular styles, so any undesirable element styling that occurs through generated content will be difficult, if not impossible, to change using customary CSS rules. You can circumvent this problem using an !important declaration, because a CSS rule with !important in an author stylesheet will override inline CSS.

For Print Stylesheets

Although this wouldn’t be necessary in all cases, and might be discouraged in some cases for the same reasons mentioned earlier, you could add !important declarations to your print-only stylesheets to help override specific styles without having to repeat selector specificity.

For Uniquely-Designed Blog Posts

If you’ve dabbled in uniquely-designed blog posts (many designers take issue with using “art direction” for this technique, and rightly so), as showcased on Heart Directed, you’ll know that such an undertaking requires each separately-designed article to have its own stylesheet, or else you need to use inline styles. You can give an individual page its own styles using the code presented in this post on the Digging Into WordPress blog.

The use of !important could come in handy in such an instance, allowing you to easily override the default styles in order to create a unique experience for a single blog post or page on your site, without having to worry about natural CSS specificity.

Conclusion

!important declarations are best reserved for special needs and users who want to make web content more accessible by easily overriding default user agent or author stylesheets. So you should do your best to give your CSS proper forethought and avoid using !important wherever possible. Even in many of the uses described above, the inclusion of !important is not always necessary.

Nonetheless, !important is valid CSS. You might inherit a project wherein the previous developers used it, or you might have to patch something up quickly — so it could come in handy. It’s certainly beneficial to understand it better and be prepared to use it should the need arise.

Do you ever use !important in your stylesheets? When do you do so? Are there any other circumstances you can think of that would require its use?

Further Resources


© Louis Lazaris for Smashing Magazine, 2010. | Permalink | Post a comment | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: ,


Transparent CSS Sprites

Smashing-magazine-advertisement in Transparent CSS SpritesSpacer in Transparent CSS Sprites
 in Transparent CSS Sprites  in Transparent CSS Sprites  in Transparent CSS Sprites

One of the most useful front-end development techniques of recent years is the humble “CSS Sprites�. The technique was popularised by Dave Shea on A List Apart in 2004 with his article CSS Sprites: Image Slicing’s Kiss of Death. CSS Sprites are a relatively simple technique once you understand the fundamentals and it can be applied in all manner of ways. A common use is for a graphic intensive navigation, but it can also be useful for buttons or even styling headings with the corporate font.

Sprites are simply a collection of images which are merged together to create a single file. You then use CSS, changing the background-position the image, to display the correct part of the image you need. I often use the analogy of a large object passing a window — you only see what is within the frame.

Over the last couple of years CSS Sprites has been one of the most widely adopted CSS-related techniques. Popularised by the Yahoo’s research and documentation around speeding up your website, many high profile websites implement the technique, including Google and Amazon. There are numerous tutorials which help you get to grips with the techniques and sprite generators which help you create the graphics themselves.

The Benefits and Potential Problems

CSS Sprites have become a de-facto way of improving the speed of your website or web application. Merging multiple images in to a single file can quickly reduce the number of HTTP requests needed on a typical website. Most browsers only allow for two concurrent connections to a single domain so although individual files can be large, the overall request and response times are considerably lower. Combining images with similar hues also means the colour and compression information is only need once, instead of per file, which can mean an overall reduced file size when compared to the files individually.

The benefits of reduced file size and HTTP requests are often publicised, but potential problems are rarely ever discussed. One of the main techinical issues with CSS Sprites is memory usage which is explained in the article “To Sprite Or Not To Sprite�. Another issue is the maintenance of the sprites, the images and the CSS, both of which can become rather complicated.

A Technological Solution

A common practice in solving slow-down in computing seems to simply throw in more hardware. We all know hardware prices are dropping all the time, so this seems like a reasonable solution. However, I feel there is a fundamental flaw with this philosophy and ingrained mentality. Developers have access to more computing power and as such they code their applications to be handled in these environments. With each new feature the application becomes slower and slower, but this problem has already has a solution — upgrade your hardware. This is an endless cycle.

Many of the user interfaces people come across today are on the Web. This means the user has to download most of the related material (images, CSS, JavaScript) before interacting with the content, so the same philosophy must be applied to the Web. Websites, or more recently web applications, are becoming more complex, even replacing many desktop applications, therefore the user must first download more and more information before beginning their experience.

Although file sizes required to view a website have increased dramatically over recent years, more and more people are upgrading their Internet connections, with broadband becoming the norm in many countries. This cycle conforms to the hardware upgrade philosophy and in theory should negate any potential user experience problems.

However, web developers are falling in to the same trap which many application developers have before. As layouts become more complex, more images are required and so the developer creates more images — even if they are sprites. This seems like a reasonable assertion, but it doesn’t mean it is the best solution.

A Twist on the Technique

Due to the limitations of the Web, there have been many inventive solutions to problems. But the Web isn’t the only place where there can be very tight limitations. Innovation strives on limitation. A great example of this was in the iconic game Super Mario Brothers where the bushes were just recoloured clouds.

This very simple but extremely effective implementation made me think about how to reuse common interface elements, trick the user to believe something the same is different!

Now on to the twist, this idea is to create a transparent sprite allowing the background-color to show through. If you are familiar with CSS Sprites, you should be able to grasp this twist relatively easily.

Simply, an image with a transparent “knocked-out� transparent center is placed over a background colour. Changing the background colour changes the appearance of the element. The only thing you need to pay attention to is that the colour surrounding the transparent part of the image matches the background in which you are using the techinque. This stops the background colour bleeding in to other parts of your image.

Anyway, this technique is much easier to understand in an example…

Example

The following example is only made up of three images. One for all the font samples, one image for both sets of droplets, including hover and active states, and one for the all buttons.

The Images

Fonts
The font image contains transparent typefaces on a white background, meaning they aren’t viewable on a white background. Save the file from the example, open it in your favourite graphics editor and you will see the transparent typefaces.

Drops
The drops image is used on the example above as the colour picker. A single graphic containing the gradient drop on the two different backgrounds, so the background-color is masked out correctly. The image contains all three states used in modern interactive interfaces — static, hover/focus, pressed/active.

Button
The button technique is the most flexible and probably most useful way to use this technique. A simple sprite image containing two states — static and hover/focus — which is then placed over text to create the button. Simply adding a background-color will make every use of this button the same style across your application or website.

Below is some CSS which styles simple fixed width buttons with a grey background colour, but also has two different treatments, “warning” and “go”, which have red and green background colours respectively.

a.button {
  display: block;
  width: 80px; height: 30px;
  margin: 0 20px;
  font-size: 14px; line-height: 30px; color: #fff;
  text-align: center; text-decoration: none;
  background: #4a4a4a url(button.png) no-repeat 0 0;
}
a.button:hover,
a.button:focus,
a.button:active {
  background-position: 0 -40px;
}
a.button.warning {
  background-color: #ea1d22;
}
a.button.go {
  background-color: #309721;
}

The CSS above produces the following buttons:

Conclusion

This techinque could be useful when providing a range of themes for a website. You could create one set of buttons and icons then add the background colour which best suits the selected theme.

Although this technique will never be as broadly useful as the original CSS Sprites, the idea can be useful for websites which allow user theming. The technique could also be used when creating HTML mockups, allowing you to easily update colours based on client feedback.

The main benefit this technique has is that it reduces the number of HTTP requests. But it also reduces browser memory usage compared with what would be needed if you created a larger sprite to handle all the colours you need.

I would like to mention one caveat though, IE6, because it does not natively support transparent PNGs. There are PNG fixes, but none1 of these support background-position which is needed if you are using this technique with CSS sprites, such as with the buttons and droplets above. However, you could provide a slightly less optimal experience using GIFs instead.

1. The IE PNG Fix from TwinHelix does include support for background-position, but the solution requires JavaScript.

Further Resources

If you are interested in any aspect of CSS Sprites, check out the following extra resources.

Below are a list of links used within the article:


© Trevor Morris for Smashing Magazine, 2010. | Permalink | Post a comment | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags:


CSS Validation, How Important Is It?

A really interesting question was asked recently on Answers, discussing the importance and relevance of CSS validation. It would be interesting to discover how much stock developers actually do put in to it, or, is it more important to focus on the actual page being able to function? We would love to hear from you.

You can leave your thoughts, tips and insights in the comment section below, or you can leave your answer on the original question on Answers here: CSS validation, How Important Is It

CSS validation, how important is it
This question was originally asked by Ben G.

Here is the best answer, as voted by our users, so far:

CSS validation, how important is it

So, what do you think, how important is CSS validation?

Thanks to everyone who asked a question, but most importantly thanks to everyone that took the time and effort to offer helpful and useful answers.


Three Fresh CSS Frameworks

CSS Frameworks are those marvelous and innovative tools that will speed up your web development process by taking care of the multitude of repetitive processes you would have to cover for every project, and on top of that, they (mostly) take care of any cross-browser compatibility issues. They have also never been as popular, with new frameworks cropping out from week-to-week. As such, in this design news round-up we have selected our favorites from recent months.

The Square Grid

The Square Grid is a simple CSS framework for designers and developers, based on 35 equal-width columns. The grid is equiped with a 28px baseline-grid for a smooth vertical rhythm with each block (DIV) defined with a margin of 1 square (28px) from the next block.
The Square Grid

FEM CSS Framework

The FEM CSS Framework is a 960px width 12 column grid system. It is based on the 960 Grid System, but with a twist in its philosophy, making it more flexible and faster to play with boxes.
FEM CSS Framework

Formalize CSS

Formalize CSS is a useful framework for giving your forms a cross-browser uniformity.
Formalize CSS

By Paul Andrew (Speckyboyand speckyboy@twitter).


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress