Monday, April 12, 2010

CSS Sprites: What They Are, Why They're Cool, and How To Use Them

You’ve heard of them, but…

Do you really understand them? The name might be a little misleading, because sprites aren’t little images like you might be picturing, a sprite is actually one big image. Have you ever seen the CSS technique where the “on” and “off” states of a button are contained within the same image and are activated by shifting the background-position?

http://css-tricks.com/wp-content/csstricks-uploads/simple-css-sprite.png

Here is an example of that on CSS-Tricks.

Think of CSS Sprites as an extension of that technique. The difference is that instead of just two or three images being combined into one, you can combine an unlimited number of images into one. The origin of the term “sprites” comes from old school computer graphics and the video game industry. The idea was that the computer could fetch a graphic into memory, and then only display parts of that image at a time, which was faster than having to continually fetch new images. The sprite was the big combined graphic. CSS Sprites is pretty much the exact same theory: get the image once, shift it around and only display parts of it, saves the overhead of having to fetch multiple images.

Why combine all those images? Isn’t it quicker to have smaller images?

Nope, it’s not. Back in the day, everybody and their brothers were “slicing” images to make pages load faster. All that technique did was fool the eye to make it look like the page was loading faster by loading bits and pieces all over at once. Each one of those images is a separate HTTP-Request, and the more of those, the less efficient your page is.

Let’s look at a quote from the article “Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests” by Tenni Theurer on the Yahoo! User Interface Blog.

Table 1 shows popular web sites spending between 5% and 38% of the time downloading the HTML document. The other 62% to 95% of the time is spent making HTTP requests to fetch all the components in that HTML document (i.e. images, scripts, and stylesheets). The impact of having many components in the page is exacerbated by the fact that browsers download only two or four components in parallel per hostname, depending on the HTTP version of the response and the user’s browser. Our experience shows that reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.

Table 1. Time spent loading popular web sites

Time Retrieving HTML

Time Elsewhere

Yahoo!

10%

90%

Google

25%

75%

MySpace

9%

91%

MSN

5%

95%

ebay

5%

95%

Amazon

38%

62%

YouTube

9%

91%

CNN

15%

85%

Every single image, whether it’s an <img> tag or an background-image from your CSS is a separate HTTP-Request, so you can image how quickly those requests can wrack up.

OK. So how is it done?

I thought you would never ask. Let’s start by showing the BEFORE example. Notice in the CSS below how the anchor tag does not get a background-image, but each individual class does.

#nav li a {background:none no-repeat left center}
#nav li a.item1 {background-image:url('../img/image1.gif')}
#nav li a:hover.item1 {background-image:url('../img/image1_over.gif')}
#nav li a.item2 {background-image:url('../img/image2.gif')}
#nav li a:hover.item2 {background-image:url('../img/image2_over.gif')}
...

example1before.png

Using CSS Sprites, we can really lighten this example up. Instead of having ten separate images for the buttons (five default states and five rollover states), we can literally combine all of them into one big long image. I won’t go into great detail about how this is done, I’ll just give you a basic walkthrough. Create a new image that is as wide as your widest image and and as tall as the combined height of all your images plus X pixels, where X is the number of images you have. Now place you images into this new image, left aligned, one on top of the other with one pixel of white space in between.

Now check out the AFTER example. Notice in the CSS that there is a single background-image applied to the anchor element itself, and the unique classes merely shift the background position with negative Y coordinates.

#nav li a {background-image:url('../img/image_nav.gif')}
#nav li a.item1 {background-position:0px 0px}
#nav li a:hover.item1 {background-position:0px -72px}
#nav li a.item2 {background-position:0px -143px;}
#nav li a:hover.item2 {background-position:0px -215px;}
...

example1after.png

We were able to reduce the number of HTTP-Requests by 9 and the total file size of the image(s) by 6.5 KB. That’s a pretty huge improvement for such a little example. Imagine what you could do on a full website.

 

Ugh. That sounds like a lot of work.

Just remember what Chuck Norris once said: “All great things require great dedication.” Actually I’m not sure if he said that or not, but it’s good advice anyway. But fortunately for you, there is a web service which makes creating and implementing sprites really easy. There are actually lots of different services designed to help you making sprites easier, but I think hands down, the best one is SpriteMe.

Using SpriteMe

SpriteMe is a bookmarklet. So after you’ve put it up in your bookmarks bar, just go to any website and click it. It will open up an overlay over the right side of your screen.

http://css-tricks.com/wp-content/csstricks-uploads/spriteme-1.jpg

The top white box is a list of all the background graphics on your page that it feels like could be combined into a sprite. The boxes below are graphics that probably won’t work for sprites (and it will tell you why). If you think differently, you can drag the links in and out of their boxes. Once you have all the images to be combined in that top box, just click the “Make Sprite” button. It will combine them all into a single image (a CSS Sprite!) that you can view right there.

http://css-tricks.com/wp-content/csstricks-uploads/spriteme-2.jpg

On the current design of this site, this is a (scaled down) version of the end result. (Or see the real thing)

http://css-tricks.com/wp-content/csstricks-uploads/sprite-example.png

Recently, SpriteMe also made it available to “export” the CSS. Click that button and you’ll see some code like this:

A id=home-link
{
  background-image: url(http://css-tricks.com/wp-content/themes/CSS-Tricks-4/images/logo.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -10px;
}
A
{
  background-image: url(http://css-tricks.com/wp-content/themes/CSS-Tricks-4/images/nav.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

The crossed out code is what used to be in your CSS, and what the replacement should be is below it.

What can’t sprites do?

They don’t do repeating graphics*. Sprites are for graphics that are just single blocks. Icons are a great example candidate for CSS sprites.

*OK, they kinda can do repeating, but it’s a little trickier and can only work one-dimensionally (x or y).

Either start from the beginning with Sprites, or do it all at the end

The using of sprites is a no-brainer. You should do it. But what is the workflow when creating a new design? I think you should go one of two routes. The first is to know that you are going with sprites from the get-go and built it as you go along. That means have a Photoshop file open, start from the upper left, and drop stuff in as you need it. If you have another icon (or whatever) that makes sense to put in a sprite drop it in there and resave it.

The other way, which perhaps makes even more sense, is to develop without thinking about sprites at all. Make everything separate individual graphics. Then when the site is “complete” (or at least, ready for release, we all know sites are never “complete”), then use SpriteMe and do the spriting then.

 

Monday, April 5, 2010

IE9 Platform Preview available

IE9 Platform Preview available

In November last year, Microsoft revealed some of what will be new and improved in Internet Explorer 9 in the IEBlog post An Early Look At IE9 for Developers.

Today, IE General Manager Dean Hachamovitch posted a follow-up: HTML5, Hardware Accelerated: First IE9 Platform Preview Available for Developers. Yes, you can now download what Microsoft calls a Platform Preview to test drive Internet Explorer 9 for yourself.

There are also a number of demos to show the improved performance and standards support in IE 9. Judging by several of the demos (HTML5 T-Shirt Designer and SVG-oids are two) it looks like IE9 will finally support XHTML served with the application/xhtml+xml media type. We’ll never know, but I can’t help wondering if the number of people using “real” XHTML would have been greater if Microsoft had implemented support for that earlier.

One of the things that Microsoft claims will be improved in IE9 is type rendering, which I’m looking forward to a lot. To my (admittedly Mac OS X-conditioned) eyes the whole of Windows needs to catch up there.

As Jeffrey Zeldman puts it in IE9 preview:

Thus efforts to catch up to the typographic legibility and beauty of Mac OS X and Webkit browsers are presented, in Dean Hachamovitch’s blog post, as leading-edge innovations.

Type rendering aside, it’s promising to see more information about IE9. Let’s hope Microsoft can live up to what Dean Hachamovitch writes in today’s blog post:

We want the same markup to just work across different browsers. In IE9, we’re doing for the rest of the platform what we did for CSS 2.1 in IE8. IE8 delivered a high-quality CSS 2.1 implementation, sticking to the standard, and looking to other implementations in places where the standard is ambiguous.

I’m still amazed at how few IE8 problems related to CSS 2.1 I have run into. If IE9 can deliver that level of support for HTML5, DOM, CSS3, and SVG… yay!

Makes me wonder how long it will take for IE8 to be phased out.

 

 

Thursday, April 1, 2010

sIFR default CSS hides content from at least one screen reader

Just a heads-up to anyone using sIFR to render text: the default CSS that comes with sIFR hides the replaced text from the VoiceOver screen reader. I don’t know if any others are affected – VoiceOver is the only screen reader I have been able to verify this problem in.

The culprit is the following rule:

  1. .sIFR-alternate {
  2. position:absolute;
  3. left:0;
  4. top:0;
  5. width:0;
  6. height:0;
  7. display:block;
  8. overflow:hidden;
  9. }

VoiceOver (or WebKit, not sure) figures that anything inside an element with those properties should not be displayed or spoken, so the end effect is pretty much the same as using display:none – the user won’t know that the text is there.

This is obviously a major issue for anyone using VoiceOver. Fortunately the following CSS can be used to hide the replaced text instead:

  1. .sIFR-alternate {
  2. position:absolute;
  3. left:-9999px;
  4. }

After this change, all screen readers I have been able to test with read the replaced text. So, if you use sIFR on any of your sites, please consider updating the CSS to avoid inadvertently causing problems for VoiceOver users.

 

Copyright http://www.456bereastreet.com/archive/201002/sifr_default_css_hides_content_from_at_least_one_screen_reader/

Wednesday, March 31, 2010

CSS efficiency tip: use a single stylesheet file for multiple media

The way most people link CSS intended for different media types, such as screen, print, or handheld, is to use multiple files. The files are then linked either through link elements with a media attribute or through @import statements with one or more media types specified.

There is nothing wrong with splitting your CSS into multiple files and linking them this way (I currently do that here on this site), but there are two drawbacks: it leads to more HTTP requests from the browser to the server and the need to maintain multiple CSS files.

Some people like splitting their CSS across several files, and not only for different media but for different sections of a site. I have tried working like that and while it may work well for some, it most definitely does not suit my workflow. To each his own, but the fewer CSS files I have to keep track of, the faster I work.

Luckily for me and others who feel the same way there is a way to put all of your CSS into a single file.

Enter the @media at-rule

An @media rule lets you group CSS rules by media type in the same file. Any rules outside @media rules apply to all media type that the stylesheet itself applies to.

Here is an example stylesheet that uses @media rules:

  1. body {
  2. color:#444;
  3. background-color:#fff;
  4. }
  5. @media screen, projection {
  6. body { background-image:url(background.png); }
  7. }
  8. @media print {
  9. body { color:#000; }
  10. }
  11. @media handheld {
  12. body { color:#0f6517; }
  13. }

Assuming that the above rules are in a CSS file that applies to all media, the following will apply:

  • For the screen and projection media types, text will be dark grey and the background will consist of a repeated image.
  • For the print media type, text will be black on white.
  • User agents that apply the handheld media type will render dark green text on a white background.
  • For all other media types, text will be dark grey on white.

This may or may not work for you, but personally I’ve found that doing this leads to less redundancy and reduces the risk of one or more media types being overlooked when I make changes to the CSS.

 

Copyright http://www.456bereastreet.com/archive/201002/css_efficiency_tip_use_a_single_stylesheet_file_for_multiple_media/

CSS3 Zebra Striping a Table

tbody tr:nth-child(odd) {

   background-color: #ccc;

}

 

Style Override Technique

p {

   font-size: 24px !important;

}

 

Standard CSS Image Replacement

h1#logo {

   width: 200px; // width of image

   height: 100px; // height of image

   background: url(../path/to/image.jpg);

   text-indent: -9999px;

}

 

Tuesday, March 23, 2010

Absolute Positioning Inside Relative Positioning

A page element with relative positioning gives you the control to absolutely position children elements inside of it.

To some, this is obvious. To others, this may be one of those CSS “Ah-ha!” Moments. I remember it being a big deal for me when I first “got it”.

Here is a visual:

The relative positioning on the parent is the big deal here. Look what would happen if you forgot that:

Might not look like a big deal in this small example, but it really is a significant change. What is happening is the absolutely positioned elements are positioning themselves in relation to the body element instead of their direct parent. So if the browser window grows, that one in the bottom left is going to stick with the browser window, not hang back inside like his well behaved brother from the first image.

Once you “wrap” your head around this concept (rim-shot) you will find little uses for it all over the place, and start noticing examples of other places using it. It’s like when you learn a new word and then you start hearing it everywhere. Yeah.

Grid Accordion with jQuery

Accordions are a UI pattern where you click on a title (in a vertical stack of titles) and a panel of content reveals itself below. Typically, all other open panels close when the new one opens. They are a clever and engaging mechanism for packing a lot of information in a small space.


Basic accordion from jQuery UI

One way to look at an accordion is like a collapsed single column of a table. I was recently building a page for a client site, where the information that they provided really made sense to present as a table. But it was too much information to view all at once. I thought it would have been overwhelming visually. I also thought that it was most likely that people visiting this page would know what they needed right away, so having them click once to get it seemed pretty reasonable. So, a table of accordions!

Another consideration in this table I was building is that there was enough columns that each individual column (should they have been equal width in the space available) wasn’t very wide, maybe 150px. Some of these cells contained several paragraphs of text. A cell 150px wide with several paragraphs of text would awkwardly tall. Hence, the Grid Accordion is born!

The Grid Accordion works with the same theory as most other accordions. Only one cell is open at a time. The big thing is that the column of the current open cell expands to a reasonable reading width.

You can view and download the example at the end of this article. I’ll go through some of the important bits next.

HTML: Classic use of the definition list

Accordions are perfect semantic examples of definition lists. A quick review of those:

<dl>
   <dt>Title</dt>
   <dd>Information about that title here</dd>
   <dt>Another Title</dt>
   <dd>Information about that other title here</dd>
</dl>

Our grid accordion will be made up of divs floated into a horizontal row. Each div contains the title for the column and an image, as well most importantly the definition list itself. Sample of one of those divs:

<div class="info-col">
 
        <h2>Batman</h2>
 
        <a class="image batman" href="http://jprart.deviantart.com/">View Image</a>
 
        <dl>
          <dt>Super Power</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Costume</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Morality</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Sidekicks</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Vehicles</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
          <dt>Weaknesses</dt>
          <dd>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</dd>
        </dl>
 
</div>

CSS: trying to stay accessible

Most of the CSS is just simple setup and not really worth covering here (full CSS file here).

One aspect that is worth covering those is accessibility. We need to “hide” all the information panels of the table by default. One of the ways we could do that is to set the dd elements to display: none; in the CSS. This is a seriously accessibility problems though, as many screen readers will obey that CSS and completely remove that information.

Instead, we can “hide” the cells by just kicking them outside the browser window.

dd { position: absolute; top: -9999px; left: -9999px; }

This is a classic technique. In fact, it’s pretty common to see those exact CSS properties and values with a utility class name like this:

.screen-reader-text { position: absolute; top: -9999px; left: -9999px; }

We have another concern though. We’re going to be using some jQuery animations to slideUp and slideDown the info cells. So we can’t have them kicked off the page for typical viewers. We’ll move the cells back when the JavaScript first runs and then have the JavaScript hide them.

The thing about the slideDown jQuery function is that it works best when it already knows what height the element originally was before it was closed or hidden, so it can smoothly animate itself back to that original height. If we used display: none; in the CSS, this function would have no idea how tall those cells are supposed to be. Kicking them off the page instead means that the original height will be calculated, keeping that animation as smooth as it can be. We just need to make sure that the cell is set to its “full” width so the height is calculated at the width the cell will be when it’s visible.

dd { width: 299px; position: absolute; left: -9999px; top: -9999px; }

So at this point we have an accessible page of information, in that screen readers should be able to get all they need, and regular users have a smoothly operating system. However one thing that isn’t fully addressed is simply having JavaScript turned off. In that scenario, the information cells are still hidden by CSS. Personally, I’m far more concerned about accessibility than I am about people who browse around with JavaScript turned off and a torch to bear. However if you are, feel free to either 1) Put in a <noscript> message or 2) remove the CSS hiding and just let there be a bit of a flash of content before the JavaScript hides the cells.

CSS: Fun with CSS3

The CSS3 pseudo class selector :nth-of-type is particularly useful with definition lists. Because the dt and dd elements alternate, and actually can be repeated or in any order, :nth-child would be a non-maintainable way to go. Let’s color the cells of the table using :nth-of-type

dt:nth-of-type(1) { background: #b44835; }
dd:nth-of-type(1) { background: #b44835; }
 
dt:nth-of-type(2) { background: #ff7d3e; }
dd:nth-of-type(2) { background: #ff7d3e; }
 
dt:nth-of-type(3) { background: #ffb03b; }
dd:nth-of-type(3) { background: #ffb03b; }
 
dt:nth-of-type(4) { background: #c2a25c; }
dd:nth-of-type(4) { background: #c2a25c; }
 
dt:nth-of-type(5) { background: #4c443c; }
dd:nth-of-type(5) { background: #4c443c; }
 
dt:nth-of-type(6) { background: #656b60; }
dd:nth-of-type(6) { background: #656b60; }

For the rabble-rabble-IE-compatibility crowd, go ahead and add extra class names to the cells and do your coloring with those hooks.

One of the bits flair we are going to add is highlighting the current column. The class name of “curCol” will be applied and removed as needed via JavaScript. The current column will have a shadow around it, which of course is the perfect use for box-shadow:

.curCol { -moz-box-shadow: 0 0 10px rgba(0,0,0,0.2); -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2); z-index: 1; position: relative; }

While I was playing with this, I originally tried using some transforms to scale up the size of the current column. Ultimately I didn’t like the look (one pixel lines look awful when scaled). I liked the shadows much better, but I found that the right edge of the shadow was being cut off the the next column. It was because that next column sat slightly above the current one in terms of vertical stacking order. Hence, the curCol class having the z-index and relative positioning, to make sure it sits on top of the others.

Randomly, I also discovered that the transform property also solved the problem. As in, setting -moz-transform: scale(1); (which scales something to 100%, or basically, does nothing to unscaled elements) also worked by making the shadow visible. In other words: using transforms on elements affects their vertical stacking order. I’m just not sure how it all works exactly quite yet.

jQuery JavaScript

Again I won’t cover every line of this (you can see the full file here). Here is the logical structure though:

  1. When a <dt> is clicked…
  2. If it’s the currently active cell, do nothing
  3. Otherwise…
  4. Close all open cells
  5. Shrink old title
  6. Enlarge new title
  7. Open new cell
  8. Mark the current column
  9. Make sure current column is expanded and others are shrunk

Couple of interesting things…

I would have normally used the .live() function to handle the clicks on the dt elements. But the newfangled hip way to handle this in jQuery is using .delegate()

$("#page-wrap").delegate("dt", "click", function() {
  // do stuff
}

Where live would have to watch the entire document for clicks, delegate limits that watching to only the page-wrap, which is more efficient.

I showed this to Doug Neiner, and he also suggested that clicking on the photos in each column would only open the column. Then if clicked again, they would actually go to the artist’s website (where the href of each image links to). The trick here was to prevent the default action (going to the link) when clicking on an image if it’s not the current column. Instead, divert the click to the first title in that column (which will open it). We can use delegate for this again:

$("#page-wrap").delegate("a","click", function(e) { 
 
    if ( !$(this).parent().hasClass("curCol") ) {
        e.preventDefault();
        $(this).next().find('dt:first').click();
    } 
 
});
 
Copyright : http://css-tricks.com/grid-accordion-with-jquery/

 

Thursday, March 18, 2010

Internet Explorer 9 Platform Preview Released

Microsoft today announced further details of their forthcoming Internet Explorer 9 browser, along with the first platform preview for developers, at their MIX Conference 2010.

Amongst the announcements comes increased support for CSS3, with support promised for CSS3 Selectors, Namespaces, Colors, Values, Backgrounds & Borders and Fonts, along with increased support for HTML5 and improvements in JavaScript performance.

The platform preview, downloadable from the Internet Explorer website, comes with a number of demonstrations including those for CSS3 border-radius and selectors. The preview also scores an impressive 578/578 on our CSS3 Selectors Test and an improved 55/100 on the Acid 3 test, with further improvements promised before the final release.

You can read more on the Internet Explorer blog, or download the platform preview here.

Copyright: http://www.css3.info/internet-explorer-9-platform-preview-released/

Meet the Pseudo Class Selectors

Pseudo class selectors CSS selectors with a colon preceding them. You are probably very familiar with a few of them. Like hover:

a:hover {
 /* Yep, hover is a pseudo class */
}

They are immensely useful in a variety of situations. Some of them are CSS3, some CSS2… it depends on each particular one. Outside of IE, they have great browser support. In IE land, even IE8, support is pretty barren. However, the IE9 preview has full support of them. The link-related ones work but not much else. Let’s take a brief look at each one of them. Don’t worry, there isn’t that many.

Link-related pseudo class selectors

:link – Perhaps the most confusion-causing link-related pseudo selector. Aren’t all <a>’s links? Well not if they don’t have an href attribute. This selects only those that do, thus is essentially the same as a[href]. This selector will become a lot more useful should any-element linking become reality.

:visited – Selects links that have already been visited by the current browser.

:hover – When the mouse cursor rolls over a link, that link is in it’s hover state and this will select it.

:active – Selects when the link while it is being activated (being clicked on or otherwise activated). For example, for the “pressed” state of a button-style link or to make all links feel more button-like.

There is a fun technique to remember all the link pseduo class selectors. Look at the first letter if each: LVHA … LOVE HATE.

Input & link related pseudo class selectors

:focus – Defining hover styles for links is great, but it doesn’t help out those who used keyboard navigation to get to the link. :focus will select links that are the current focus of the keyboard. This is not limited to links, but can be used (and really should be used) on inputs and textareas as well. Some would tell you to define a :focus style for anything that has a :hover style.

Copyright : http://css-tricks.com/pseudo-class-selectors/

Wednesday, March 10, 2010

Perfect Full Page Background Image

Technique #2

Big thanks, as usual, to Doug Neiner for this alternate version.

Here, we can use CSS with no JavaScript fixes, and the image is just an inline image with a class name of “bg” and no extra markup. That’s a big win for all the folks unhappy about the extra markup.

The only caveat is that it doesn’t quite meet all the requirements layed out about, in that it doesn’t center in IE 7, doesn’t work at all in IE 6, and may not always be proportionate depending on the original image size. BUT, since it’s simpler and bug-free, it’s defenitly a solid option. Here is the CSS:

img.bg {
/* Set rules to fill background */
min-height: 100%;
min-width: 1024px;

/* Set up proportionate scaling */
width: 100%;
height: auto;

/* Set up positioning */
position: fixed;
top: 0;
left: 0;
}

@media screen and (max-width: 1024px){
img.bg {
left: 50%;
margin-left: -512px; }
}

div#content {
/* This is the only important rule */
/* We need our content to show up on top of the background */
position: relative;

/* These have no effect on the functionality */
width: 500px;
margin: 0 auto;
background: #fff;
padding: 20px;
font-family: helvetica, arial, sans-serif;
font-size: 10pt;
line-height: 16pt;
-moz-box-shadow: #000 4px 4px 10px;
-webkit-box-shadow: #000 4px 4px 10px;
}

body {
/* These rules have no effect on the functionality */
/* They are for styling only */
margin: 0;
padding: 20px 0 0 0;
}

Monday, March 8, 2010

Unicode Characters for Class Names

Reader Kartlos emailed me in pointing to me to an interesting article by the great Mr. Snook from a few years back. I don’t think I had seen it before and it’s a bonafide “CSS Trick” so I thought I would share.

The idea is that you can use unicode characters (read: fancy symbols) for class names in your HTML, and even use write CSS selectors with those same characters.

< div class="♫">
A.A. Bondy
I Can See The Pines Are Dancing
< /div>

.♫ {
display: block;
background: #eee;
padding: 5px;
}

Pretty cool eh? I’d call my example above perfectly semantic as well, since the div with the music note class name is marking up a musician and song. Possibly even more semantic, as a music note symbolizes music moreso than any English word.

I put together a super simple demo page that shows it working. Oh, and yes-it-works-in-IE6™ & yes-it-validates™
But…

One funny thing? View the source on that page. I use PHP includes for the headers and footers of all my demos, and because of the character encoding (?) of that page the PHP doesn’t run it just sits there as text.

That ain’t right.

Coda does warn you first.

Weird eh? If you know how this could work both ways, let me know.
Other uses

Jonathan presented (in his original article) and idea for targeting the corners of a box.

< div class="□">
< div class="┌">
< div class="┐">
< div class="└">
< div class="┘">
content
< /div>
< /div>
< /div>
< /div>

Remember back a few years ago most of us were rocking rounded corners with nested divs and images like that! The corners symbols are clever, but I could see the < div class="□"> being used for like “container” or “box” style classes today, or, perhaps best of all, the clearfix.

I posted a little code clip of this over on Forrst (sorry I know most folks don’t have accounts there yet) and a guy named Aaron had a funny idea. Using upside down writing to be annoying! id='ɹǝpɐǝɥ', id='ɹǝddɐɹʍ', id='ɹǝʇooɟ'

Copyright : http://css-tricks.com/unicode-class-names/

Wednesday, March 3, 2010

How to shake your browser

Just paste below code in address bar


javascript:function Shw(n) {if (self.moveBy) {for (i = 35; i > 0; i–) {for (j = n; j > 0; j–) {self.moveBy(1,i);self.moveBy(i,0);self.moveBy(0,-i);self.moveBy(-i,0); } } }} Shw(6)

Wednesday, February 24, 2010

Multiple Class / ID and Class Selectors

Can you spot the difference between these two selectors?
#header.callout { }

#header .callout { }
They look nearly identical, but the top one has no space between “#header” and “.callout” while the bottom one does. This small difference makes a huge difference in what it does. To some of you, that top selector may seem like a mistake, but it’s actually a quite useful selector. Let’s see the difference, what that top selector means, and exploring more of that style selector.
Here is the “plain English” of “#header .callout”:
Select all elements with the class name callout that are decendents of the element with an ID of header.
Here is the “plain English” of “#header.callout”:
Select the element which has an ID of header and also a class name of callout.
Maybe this graphic will make that more clear:

Combinations of Classes and IDs
The big point here is that you can target elements that have combinations of classes and IDs by stringing those selectors together without spaces.
ID and Class Selector
As we covered above, you can target elements by a combination of ID and class.

This Should Be Red


#one.two { color: red; }
Double Class Selector
Target an element that has all of multiple classes. Shown below with two classes, but not limited to two.

Double Class


.three.four { color: red; }
Multiples
We aren’t limited to only two here, we can combine as many classes and IDs into a single selector as we want.
.snippet#header.code.red { color: red; }
Although bear in mind that’s getting a little ridiculous =)
Example
So how useful is all this really? Especially with ID’s, they are supposed to be unique anyway, so why would you need to combine it with a class? I admit the use cases for the ID versions are slimmer, but there are certainly uses. One of those is overriding styles easily.
#header { color: red; }
#header.override { color: black; }
The second targets the same element, but overrides the color, instead of having to use:
.override { color: black !important }
or perhaps prefacing the selector with something even more specific.
More useful is multiple classes and using them in the “object oriented” css style that is all the rage lately. Let’s say you had a bunch of divs on a page, and you used multiple various descriptive class names on them:







They all share the class “box”, which perhaps sets a width or a background texture, something that all of them have in common. Then some of them have color names as classes, this would be for controlling the colors used inside the box. Perhaps green means the box has a greenish background and light green text. A few of them have a class name of “border”, presumably these would have a border on them while the rest would not.
So let’s set something up:
.box { width: 100px; float: left; margin: 0 10px 10px 0; }
.red { color: red; background: pink; }
.blue { color: blue; background: light-blue; }
.green { color: green; background: light-green; }
.border { border: 5px solid black; }
Cool, we have a good toolbox going here, where we can create new boxes and we have a variety of options, we can pick a color and if it has a border or not just by applying some fairly semantic classes. Having this class name toolbox also allows us to target unique combinations of these classes. For example, maybe that black border isn’t working on the red boxes, let’s fix that:
.red.border { border-color: #900; }

Border color on red box changed because it had both the red class and border class
Based on this demo page.
Specificity
Also important to note here is that the specificity values of selectors like this will carry the same weight as if they were separate. This is what gives these the overriding power like the example above.
Browser Compatibility
All good current browsers support this as well as IE back to version 7. IE 6 is rather weird. It selects based on the first selector in the list. So “.red.border” will select based on just “.red”, which kinda ruins things. But if you are supporting IE 6, you are used to this kind of tomfoolery anyway and can just fix it with conditional styles.

Use Firebug in Any Browser

Just include this script on the site and you’ll get a Firebug console that pops up for debugging in any browser. Not quite as full featured but it’s still pretty helpful! Remember to remove it when you are done.

Keep Flash Behind Other Elements

For example, a dropdown menu going “behind” a flash movie, or staying on top of a lightbox layover.
Try This #1
Add this to the Flash embed code:


Try This #2
Make sure the element that is supposed to be on top has positioning (fixed, relative, or absolute) and a z-index value higher than the Flash object.

Tuesday, February 23, 2010

CSS Centering – fun for all!

How do you center a containing block on a page using CSS? There are two main methods and the choice should be made based on whether your page layout is liquid (will move in and out depending on the size of the browser window) or fixed width.
Centering liquid layouts
Liquid layouts are easy to center using margins on each side of the containing box. The margins can be set with em, pixel or percentage units.
div#container
{
margin-left: 10%;
margin-right: 10%;
}
Centering fixed-width layouts
Theoretically, you should be able to apply auto margins to the left and right of the containing block and it should center on the page.
The W3C Visual formatting model states: “If both ‘margin-left’ and ‘margin-right’ are ‘auto’, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.”
So, a containing block should be able to be centered using the following rules:
div#container
{
margin-left: auto;
margin-right: auto;
width: 50em;
}
However, some browsers do not center the containing blocks using this method as they ignore the auto margins. These browsers include:
• NN4 (Mac and Win)
• Win/IE4
• Win/IE5
• Win/IE5.5
• Win/IE6 (when in quirks-mode)
By adding two simple rules, this problem can be overcome in all of the browsers mentioned above, excluding NN4.
1. Center the body
While these browsers ignore auto margins, they will follow “text-align: center”. If this is applied to the body, the containing block will center correctly. So, a new rule is added:
body
{
text-align: center;
}

div#container
{
margin-left: auto;
margin-right: auto;
width: 50em;
}
2. Resetting text-align
The only problem with this new rule is that all content on the page is now center-aligned. To overcome the center alignment problem, a new declaration is added within the containing block rule set – “text-align: left”. The final CSS code is:
body
{
text-align: center;
}

div#container
{
margin-left: auto;
margin-right: auto;
width: 50em;
text-align: left;
}

Monday, February 22, 2010

Optimizing HTML

Why clean markup?

Client-side optimization is getting a lot of attention lately, but some of its basic aspects seem to go unnoticed. If you look carefully at pages on the web (even those that are supposed to be highly optimized), it’s easy to spot a good amount of redundancies, and inefficient or archaic structures in their markup. All this baggage adds extra weight to pages that are supposed to be as light as possible.

The reason to keep documents clean is not so much about faster load times, as it is about having a solid and robust foundation to build upon. Clean markup means better accessibility, easier maintenance, and good search engine visibility. Smaller size is just a property of clean documents, and another reason to keep them this way.

In this post, we’ll take a look at HTML optimization: removing some of the common markup smells; reducing document size by getting rid of redundant structures, and employing minification techniques. We’ll look at currently available minification tools, and analyze what they do wrong and right. We’ll also talk about what can be done in a future.
Markup smells

So what are the most common offenders?
1. HTML comments in scripts

One of the gross redundanies nowadays is inclusion of HTML comments — — in script blocks. There’s not much to say here, except that browsers that actually need this error-prevention measure (such as ‘95 Netscape 1.0) are pretty much extinct. Comments in scripts are just an unnecessary baggage and should be removed ferociously.
2. sections

Another often needless error-prevention measure is inclusion of CDATA blocks in SCRIPT elements:



It’s a noble goal that falls short in reality. While CDATA blocks are a perfectly good way to prevent XML processor from recognizing < and & as start of markup, it is only the case in true XHTML documents — those that are served with “application/xhtml+xml” content-type. Majority of the web is still served as “text/html” (since, for example, IE doesn’t understand XHTML to this date), and so is parsed as HTML by the browsers, not as XML.

Unless you’re serving documents as “application/xhtml+xml”, there’s little reason to have CDATA sections hanging around. Even if you’re planning to use xhtml in a future, it might make sense to remove unnecessary weight from the document, and only add it later, when actually needed.

And, of course, an ultimate solution here is to avoid inline scripts altogether (to take advantage of external scripts caching).
3. onclick=”…”, onmouseover=”“, etc.

There are some valid use cases for intrinsic event attributes, such as for performance reasons or to target ancient browsers (although, I’m not aware of any environment that would understand event attributes — onclick="...", and not property-based assignments — element.onclick = ...). Besides well-known reasons to avoid them, such as separation of concerns and reusability, there’s a matter of markup pollution. By moving event logic to external script, we can take advantage of that script’s caching. Event handler logic doesn’t need to be transferred to client every time document is requested.
4. onclick=”javascript:…”

An interesting confusion of javascript: pseudo protocol and intrinsic event handlers results in this redundant mix (with 106,000 (!) occurrences). The truth is that entire contents of event handler attribute become a body of a function. That function then serves as an event handler (usually, after having its scope augmented to include some or all of the ancestors and element itself). “javascript:” addition merely becomes an unnecessary label and rarely serves any purpose.
5. href=”javascript:void(0)”

Continuting with “javascript:” pseudo protocol, there’s an infamous href="javascript:void(0)" snippet, as a way to prevent default anchor behavior. This terrible practice of course makes anchor completely inacessible when Javascript is disabled/not available/errors out. It should go without saying that ideal solution is to include proper url in href, and stop default anchor behavior in event handler. If, on the other hand, anchor element is created dynamically, and is then inserted into a document (or is hidden initially, then shown via Javascript), plain href="#" is a leaner and faster alternative to “javascript:” version.
6. style=”…”

There’s nothing inherently wrong with style attribute, except that by moving its contents to an external stylesheet, we can take advantage of resource caching. This is similar to avoiding event attributes, mentioned earlier. Even if you only need to style one particular element and are not planning to reuse its styles, remember that style information has to be transferred every time document is requested. Moving style to external resouce prevents this, as stylesheet is transferred once and then cached on a client.
7.

The thing is that charset attribute only really makes sense on “external” SCRIPT elements — those that have “src” attribute. HTML 4.01 even says:

Note that the charset attribute refers to the character encoding of the script designated by the src attribute; it does not concern the content of the SCRIPT element.

Testing shows that actual browsers behavior also matches specs in this regard.

Searching for this pattern, reveals about 2000 occurrences. Not suprising, given that even popular apps like Textmate include wrong usage of charset.



Copyright http://perfectionkills.com/optimizing-html/

Friday, February 19, 2010

Shadows and CSS3

Text-shadow

Applying text-shadow to elements is easy, and coupled with RGBA it works beautifully. Since both text-shadow and RGBA are supported by Safari, Firefox, Konqueror, and Opera, why not start playing with them now?

Text shadow is sexy.

If you’re using one of the aforementioned browsers, you should see a nice drop shadow on the text above. (If you’re not — why?) This drop shadow is created using the following code:

text-shadow: 1px 1px 1px rgba(0,0,0,.4);
Breaking it down

* The first 1px indicates how much the shadow should be offset horizontally; in this case we’re telling the shadow to appear one pixel to the right. Using -1px would move the shadow one pixel to the left.
* The second 1px indicates how much the shadow should be offset vertically; in this case we’re telling the shadow to appear one pixel lower than the text. Using -1px would move the shadow one pixel above the text.
* The third 1px value tells the shadow how much it should blur. Using 0 for this value would create a solid drop shadow, which has a blocky, high-contrast effect. Using only this value (ex. text-shadow: 0 0 1px rgba(0,0,0,.4);) would create an outer glow.
* rgba(0,0,0,.4); gives the shadow its color. In this case we’re using (0,0,0), which is the RGB value for black, and we’re giving that black an opacity of 40%, or .4.

Why use RGBA for the shadow color?

Using RGBA instead of a solid color for the shadow is great because it allows some of the page’s background color to bleed through. This means that the shadow will blend nicely with the page’s existing color scheme, and if you ever change up the site’s background color your shadows will change too. If you’re unclear about how rgba works, check out Drew McLellan’s 24ways article.

So now you should be able to implement text-shadow and RGBA in your designs. This technique is very powerful, as it can be used to make text jump off the page:

Text shadow is sexy.

or appear to be set into the page:

Text shadow is sexy.
Box shadow

Once you know how to use text-shadow + RGBA to achieve drop shadows, you’re well on your way to mastering box-shadow. The syntax is exactly the same, so box-shadow: 0 1px 10px rgba(0,0,0,.1); will create a black shadow at 10% that’s centered horizontally, one pixel down, with a ten pixel blur.

test image

Misty the one-toothed cat thinks box shadow is awesome.

Box shadow is supported in Safari and Firefox 3.5, but like border-radius it requires the use of vendor-specific properties. So assuming we wanted to add a drop shadow to an image in Safari and Firefox, here’s how we’d code it:

-webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,.1);
box-shadow: 0 1px 10px rgba(0,0,0,.1);

You’ll notice I included the standard box-shadow property; this is in place for future browsers who may one day support this property.

There you have it! Once again your shadow blends nicely with the background because you’re using RGBA, and creates a kick-ass 3-D effect with minimal markup.

Box-shadow and text-shadow may not be for every project, but since they’re so easy to implement and browser support for these features is growing, why not try them out?

I can hear some of you naysayers yelling about Internet Explorer, but really is it so bad if some users get to see shadows and some don’t? The design won’t be broken for IE people, they’re just missing out on a few visual treats that other users will see.

If you’re not sold on the argument that we should reward users who choose modern browsers, check out Dan’s Handcrafted CSS book, Aaron Gustafson’s A List Apart article and Andy Clarke’s multiple well written articles on the subject.

This entry was posted on Monday, December 14th, 2009 at 4:42 pm and is filed under CSS3, Tips, web design. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Copyright: http://owltastic.com/2009/12/shadows-and-css3/

Thursday, February 18, 2010

@font-face Browser Support & Tutorial

Up to now, web developers were limited in what typography they could use on a website to what the client had installed in their environments. Now that we have finally convinced designers to not include any fonts outside of georgia, helvetica, arial, times roman, and a handful of others because of the awfulness of text images, @font-face allows us to retrain designers to use unique fonts, only if they have the legal right to post those fonts on the web.

What is @font-face

Generally, we’ve been limited to using the fonts pre-installed on MS Windows, Mac and Linux OSs. Increasing support of the CSS3 @font-face allows us to load a font onto our servers, link to and name that font in our CSS, and then use that font we’ve imported as if it were a native font in the client’s environment. With @font-face, we can worry less about what font our users have installed, and make our sites better match the intentions of our designers. @font-face enables you to provide your own font(s), @font-face eliminates the need to depend on the limited number of fonts users have installed on their computers

Browser Support for @font-face

CSS2 introduced @font-face. CSS2.1 killed it. CSS3 is reintroducing it. Why do you need to know the history? Because, it means there is actually a feature of CSS3 that internet explorer supports, albeit, differently than all other supporting browsers.

Because I am browser support table happy, here is the @font-face browser support table:
CSS Property IE6 IE7 IE8 Safari iPhone Chrome Firefox Opera
@font-face 3.2 4.0.249.78 3.5 10
format EOT EOT EOT TTF/OTF 3.1 supports SVG TTF/OTF support added 1/25/10
SVG supported by default TTF/OTF TTF/OTF

* SVG is supported, but it’s a larger file size
Google Chrome and @font-face:

Google Chrome actually does support @font-face, but it was turned off by default until version 4.0.249.78 released on 1/25/20. Chrome has supporte SVG fonts for a while now.

While developers have been able to turn on @font-face support in Chrome in their own environment, only Chrome users who have updated to the January 25, 2010 release have it on by default. Google chrome users tend to be quick at updating, but stats don’t indicate the version number, so as of right now you can’t assume that Chrome has @font-face turned ON as the default settings for most users. Like with all site enhancement features, feel free to include fonts of type TTF/OTF, but make sure to pick a font backup that degrades nicely.

Note: Digging deeper, I found Becoming a font embedding master which both explains a link on where you can convert TTF2EOT so you can display similarly on IE than on good browsers (yeah, I said it) and exporting to SVG for font support on iPhone 3.1, Chrome 2 & 3, and 4 less than 4.0.249.78, and Opera 9 (your SVG font will work in Opera 10 and future versions of FF, Chrome, iPhone and Safari as well). Also check out FontSquirrel to convert your font files to differing formats (EOT, SVG, WOFF) for greater browser support. WOFF is a new format that Mozilla is hoping will become the browser standard. It is supported in FireFox only, as of FF3.6
Internet Explorer and @font-face:

Internet Explorer has been implementing @font-face support since version 4*. In any event, it is defintely supported in IE6, IE7 and IE8. However, their implementation relies on Embedded Open Type (.eot), a proprietary format, which no other browsers use. To make IE users happy (which some could argue you shouldn’t, as a method to encourage them to upgrade), import EOT fonts in addition to TTF/OTF fonts, and included them as "fall backs" in the font family declaration (discussed in @font-face implementation below) . FontSquirrel is a place where you can convert fonts you can legally distribute to EOT (and SVG) format.

* Note: Most people say original support of @font-face was IE5. I am not sure and I am not going to pull out my 286 to check. However, with a search, I found that IE4 had a few rendering issues, like not rendering anything on the page until the font was downloaded, so I am sticking with 4.
@font-face implementation

The syntax for the @font-face implemenation is:

@font-face {
font-family: yourNameForTheFont; /* required */
src: source; /* required */
font-weight: weight; /* optional */
font-style: style; /* optional */
}

The font-family name can be anything you make up. I like to make it one word, for ease of entering it correctly as a value of the font-family property of a CSS selector later.
Declaring font-family source(s):

The source can take several formats. In addition, you can declare more than one source. If the browser doesn’t find the first source, it will go for the next source, and so on, until it either finds a source, or it runs out of sources. Example formats include:

@font-face {
font-family: curlyQ;
src: url('../fonts/makeUpSomethingElse.eot');
src: local('Edwardian Script ITC'),
url('../fonts/EdwrdScrpItc') format('opentype'),
url('../fonts/GaelicWimsy') format('svg'),
url(data:font/otf;base64,T1RUTMillIONsOfLETteRsInaROW12fAtGrrYUUUUBx);
}

In the above example, I’ve listed 5 sources. A bit excessive, but I wanted to explain those five components, so I made an excessive example.

The first declaration is for IE. IE ignores local, which is the first declaration in the second listing. In this way, IE only downloads what it needs and doesn’t download stuff it doesn’t understand.

Next I declare a font local to the user’s machine: local('Edwardian Script ITC')**. This looks for the font file locally on the site visitors computer. IE ignores local, which is great, since it will then ignore the other stuff it doesn’t understand. If you don’t have a local font style to declaration, it is OK. IE also doesn’t understand the multiple listings or the format, so as long as you include local, more than one declaration or a declaration with a format suggestions, IE will do o.k. IE will either ignore in the case of local, or misunderstand it, if there is a format or more than one declaration withing a property/value pair.

If your suggested format is incorrect, as long as the file is an understood format, it should work in Safari, Opera and Firefox.

The next example looks for a file in the SVG format. This is what you are feeding to Chrome and Opera 9.

The last example is a data example, cut way short. Actual fonts will have a few thousand characters. Similar to how you can include a data source for images, you can include them for fonts. TypeKit (described below) actually serves their fonts up in data format to Firefox and Safari, and serves EOT for IE.

**Note: Watch this page become the first google results for Edwardian Script. That would be funny. None of these examples are actually meant to work. I made the URLs and file names up.
Applying imported fonts with CSS selectors

Once the font is declared using the @font-face syntax, you can then refer to it as you would helvetica, arial, etc. Using the example above:

h3 {
font-family: yourNameForTheFont, curlyQ, arial, helvetica, sans-serif;
}

Note that I have included two imported font family names. That is legal. Note that I have also included common fonts and a default font. That is HIGHLY recommended.
TypeKit

While the TypeKit website indicates support for Firefox 3.5+, Safari 3.4+ and all versions of IE, parsing the TypeKit javascript, they have support for the following browser engine versions:
Browser Type Version
Gecko 1.9.1
Safari 525.13
Chrome

4.249.4
supported by TypeKit.
Chrome has @font-face support turned off by default
IE 6.0
iPhone specifically excluded in Typekit
Opera not included in Typekit, though Opera Supports @font-face

However, I am reading obfuscated code, so I could be talking out of my tushy. I did test in those browsers (not necessarily those versions, but those browsers), and it works in all except iPhone.

The way TypeKit works is you join TypeKit, enter the domain you want to use TypeKit on (you’re only allowed one domain for the free version), and select the fonts you would like to enable for that domain. TypeKit provides you with a link to a script file and a javascript snippet to add to your document . TypeKit also provides you with a class that you can add to elements that you want to have the font, and provides you with a snippet of CSS code for the font-family property that you can sprinkle your CSS with for selectors where you want to use the TypeKit font.

The TypeKit javascript that you attach to your code basically does a LOT of browser sniffing, and only serves up to Gecko, Safari (not iPhone), Chrome and IE6+. Since it is sniffing, it doesn’t serve up any CSS to browsers not in the sniffing. So, while Opera10 does support @font-face, TypeKit does not.
Microsoft WEFT

The Microsoft WEFT is a free utility to create linked font objects. WEFT font objects are compressed and are privately installed by IE in a way that is inaccessible to other applications on the computer and other websites. WEFT supports OpenType (OTF) and TrueType (TTF) fonts in TrueType (TTF) format.
Legalese

The main issue with @font-face is the ownership of the fonts. Make sure you are legally allowed to upload and share a font before using @font-face, as when you embed a font, that is what you are doing: sharing a file. Just like music, for most fonts it is illegal to upload and share without proper attribution and/or payment.

Copyright http://www.evotech.net/blog/2010/01/font-face-browser-support-tutorial/

Wednesday, February 17, 2010

Just IE6 PNG fixes? Mmm how about this?

We all hate IE6

This browser is crap and we all know it. Unfortunately, some clients demand support for this browser so we can’t avoid having some workarounds for it.

PNG Images

.png images have the best quality and fidelity for our web designs. Their best feature is their seamless and smooth transparency. We can achieve transparency with .gif files but their smoothness are not even close to .png files.

There are many times where our designs need a transparent .png and we also need to add support for IE6. So… what do we do?

PNG fixes to the rescue!

PNG fixes are mostly javascript (sometimes css) solutions for fixing IE6’s lack of transparency support for.png files. There are various PNG fixes. Here are some of them:

The good thing about PNG fixes :)
  1. They are easy and fast to setup.
  2. They get rid of the problem in most cases.
Problems using PNG fixes :(

Well, unfortunately, it’s not everything as nice as cupcakes and rainbows. I’ve encountered some problems using PNG fixes:

  1. Background-image support is quite poor (repeats and positions specially).
  2. It’s a pain in the ass if you are using CSS sprites.
  3. Sometimes the proportion of the images gets screwed up.
  4. You add another javascript file to your page.
  5. In CSS workarounds the code isn’t pretty and fails W3C’s validation.

Ok… so what now?

Well, I have my own workaround for transparent .png’s in IE6. Maybe you will like it, maybe not, but I wanted to share the technique in case it comes in handy for you.

I don’t use transparent PNG’s for IE6

That’s right. I use .gif files instead.
Sorry to dissapoint, but I believe this is the way to go.
The quality of our images decreases of course, but we are embracing and accepting the browser’s limitations.


Copyright: http://thecssblog.com/tips-and-tricks/just-ie6-png-fixes-how-about-this/