This page basically tell you how to make CSS 2.0 selectors and rules work on your IE5.0, IE5.5 and IE6.0. Before we getting start, I would like to introduce some CSS hacks I prefer to use here. They are easier than any other CSS hacks you can find on the web.
Take css background rules for <body /> for example:
body
{
background:red; /*display for all browsers*/
background/**/:green; /*hide from IE5*/
background/**/:/**/blue; /*hide form IE5, IE5.5*/
_background:purple;
/*hide from all none-IE browsers, thus
you can apply any IE-only rule with this method*/
}
Besides, we need to include the an external Javascript file which help use to finish our job into the <head />
<head> <!--[if IE]> <script src="http://www.hedgerwow.com/360/mwd/ie_css_hack.js"></script> <![endif]--> </head>
The first thing I want to talk about is the pseudo class : ":before", which is very important in the following practices. The ":before" allow use to append texts or images after the begining of a tag or before the end of a tag.
Old fasioned markup, easy to write, hard to maintain. Less semantic since decoration images are not contents at all.
<img src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/65.gif" width="22" height="18" alt="text icon" valign="absmiddle" /> text 1
More semantic, and the presentation layer is separated for data and structure. However, IE6.0- won`t recognize it.
<style>
.TextIcon0
{
padding:0 0 0 20px;
border:solid 1px red;
background:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/65.gif) left center no-repeat;
}
</style>
<span class="TextIcon0">text 1</span>
Using background images is an easy and popular solution. However we have some problem here.
Let`s see what else we can do. We will try the before: pseudo class.
<style>
.TextIcon1:before
{
margin:0 4px 0 0;
content:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/65.gif);
width:22px;height:18px;vertical-align:middle;
}
</style>
<span class="TextIcon1">text 1</span> (you won`t see any icon before text if you use IE)
Now we will make it work for standard web browsers and IE5.0+
<style>
.TextIcon2:before
{
margin:0 4px 0 0;
content:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif);
width:18px;height:18px;vertical-align:middle;margin:0 4px 0 0;
}
.TextIcon2
{
/*we use expression() here to make IE insert an image at the begin of tag.*/
behavior:expression( void( CSS.insertHTML(this,"http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif",2) ) );
}
.TextIcon2 img
{
/*for IE, we need to adjust the presentation of image we just inserted.*/
width:18px;height:18px;vertical-align:middle;margin:0 4px 0 0;
}
</style>
<span class="TextIcon2">Do you see a little icon before the content?</span>
Now let`s make a simple example!
<style>
/*append image after content*/
.TextIcon3:after
{
margin:0 4px 0 0;
content:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif);
width:18px;height:18px;vertical-align:middle;margin:0 4px;
}
.TextIcon3
{
behavior:expression( void( CSS.insertHTML(this,"http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif",3) ) );
}
/*append text before content*/
.TextIcon3 img
{
width:18px;height:18px;vertical-align:middle;margin:0 4px;
}
.TextIcon4:before
{
content:">";
color:purple;
font-family:"Arial Black";
font-size:22px;
vertical-align:middle;
}
.TextIcon4
{
behavior:expression( void( CSS.insertHTML(this,"<span>></span>",2) ) );
}
.TextIcon4 span
{
color:purple;
font-family:"Arial Black";
font-size:22px;
vertical-align:middle;
}
</style>
<span class="TextIcon3">icon after content </span>
<span class="TextIcon3">icon after content</span>
<span class="TextIcon4">character before content</span>
<span class="TextIcon4">character before content</span>
Let`s go a little further, see how to make generated contents both before and after tags
Text Node
Text Node
Text Node
<style>
.Quotes1 q
{
quotes:" [ " " ] ";
behavior:expression( void( CSS.quotes(this, CSS.chars[9] , CSS.chars[10] ) ) );
/*
CSS.chars is an string of Array, with predefined characters inside.
CSS.chars = [ " ","(",")"," ","{","}",":","*","&","[ "," ]"];
*/
}
</style>
<div class="Quotes1">
<q>Text Node</q>
<q>Text Node</q>
<q>Text Node</q>
</div>
first-child`s border-top-color is white
<style>
.FirstChild1 li
{
border-top:dotted 3px #FF00CC ;padding-top:12px;margin-bottom:12px;
behavior:expression( void( CSS.isFirstTag(this)?this.className="first-child":null ) );
}
.FirstChild1 li:first-child{ border-top-color:white ;}
.FirstChild1 li.first-child{ border-top-color:white ;}
</style>
<ul class="FirstChild1">
<li>Text Node</li>
<li>Text Node</li>
<li>Text Node</li>
<li>Text Node</li>
</ul>
links with seperators
<style>
.FirstChild2 li
{
border-left:solid 1px black ;padding-left:12px;margin-right:12px;float:left;list-style:none;
behavior:expression( void( CSS.isFirstTag(this)?this.className="first-child":null ) );
}
.FirstChild2 li:first-child{ border-left-color:white ;}
.FirstChild2 li.first-child{ border-left-color:white ;}
</style>
<ul class="FirstChild2">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
<br />
links enhanced with seperators and icons
<style>
.FirstChild3 li
{
border-left:solid 1px black ;padding-left:12px;margin-right:12px;float:left;list-style:none;
behavior:expression(
void( CSS.isFirstTag(this)?this.className="first-child":null ) ||
void( CSS.insertHTML(this,"http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif",2) )
);
}
.FirstChild3 li:before
{
margin:0 4px 0 0;
content:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/71.gif);
width:18px;height:18px;vertical-align:middle;
}
.FirstChild3 li img
{
margin:0 4px 0 0;
width:18px;height:18px;vertical-align:middle;
}
.FirstChild3 li:first-child{ border-left-color:white ;}
.FirstChild3 li.first-child{ border-left-color:white ;}
</style>
<ul class="FirstChild3">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
<br />
selected by parentNode`s className
<style>
.childNode1 div
{
border:solid 1px red;margin:12px;padding:12px;background:white;
behavior:expression( void( CSS.isChildOf(this,".childNode1")?this.style.background="orange":0 ) )
}
.childNode1>div{background:orange;}
</style>
<div class="childNode1">
<div>
child
<div>grandchild</div>
</div>
</div>
selected by parentNode`s id
<style>
#childNodeID div
{
border:solid 1px red;margin:12px;padding:12px;background:white;
behavior:expression( void( CSS.isChildOf(this,"#childNodeID")?this.style.background="yellow":0 ) )
}
#childNodeID>div{background:yellow;}
</style>
<div id="childNodeID">
<div>
child
<div>grandchild</div>
</div>
</div>
selected by parentNode`s tagName
<style>
.childNodeTagName div
{
border:solid 1px red;margin:12px;padding:12px;background:white;
behavior:expression( void( CSS.isChildOf(this,"form")?this.style.background="#FF99CC":0 ) )
}
.childNodeTagName>div{background:#FF99CC;}
</style>
<form class="childNodeTagName">
<div>
child
<div>grandchild</div>
<div><div>foo~~</div></div>
</div>
</form>
the second <span /> has different icon
<style>
.Sibling1 span
{
padding:4px 0 4px 26px;float:left;margin:0 4px;
background:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/67.gif) left center no-repeat;
behavior:expression( void( CSS.previousSibling(this,"span")?this.className="yes":0 ) )
}
.Sibling1 span.yes
{
background-image:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/66.gif);
}
.Sibling1 span+span
{
background-image:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/66.gif);
}
</style>
<div class="Sibling1">
<span><a href="#">Text Node 1</a></span>
<span><a href="#">Text Node 2</a></span>
</div>
<br />
Make Ranking List with sibling selectors
<style>
.Ranking1 li{ list-style:none;margin:0;padding:0; vertical-align:middle;}
/*um.....fewer classNames makes more selectors*/
.Ranking1 li:before{content:"\2780";font-size:20px;vertical-align:middle;margin:0 4px 0 0;color:#339900;}
.Ranking1 li+li:before{content:"\2781";}
.Ranking1 li+li+li:before{content:"\2782";}
.Ranking1 li+li+li+li:before{content:"\2783";}
.Ranking1 li+li+li+li+li:before{content:"\2784";}
.Ranking1 li+li+li+li+li+li:before{content:"\2785";}
.Ranking1 li+li+li+li+li+li+li:before{content:"\2786";}
.Ranking1 li+li+li+li+li+li+li+li:before{content:"\2787";}
.Ranking1 li+li+li+li+li+li+li+li+li:before{content:"\2788";}
.Ranking1 li+li+li+li+li+li+li+li+li+li:before{content:"\2789";}
/*let`s do it with IE*/
.Ranking1 li
{
behavior:expression(
void( CSS.getTagIndex(this) ) ||
void( CSS.insertHTML(this,"<span>&#" + ( this.tagIndex +9312 ) + ";</span>",2) )
);
}
.Ranking1 li span{font-size:20px;vertical-align:middle;margin:0 4px 0 0;color:#339900;}
</style>
<ol class="Ranking1">
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
<li><a href="#">Text Node</a></li>
</ol>
<input /> with attribute type="submit"
<style>
.Attribute1 input[type="submit"]
{
cursor:pointer;
background:#663399;
color:white;
border:outset 2px #663399;
font-family:"Verdana";
}
.Attribute1 input
{
behavior:expression( void( CSS.hasAttribute(this,"type","submit")?this.className="yes":0 ) );
}
.Attribute1 input.yes
{
cursor:pointer;
background:#663399;
color:white;
border:outset 2px #663399;
font-family:"Verdana";
}
</style>
<div class="Attribute1">
<input type="text" value="" />
<input type="radio" value="" />
<input type="checkbox" value="" />
<input type="submit" value="submit" />
</div>
<tr /> with attribute of "name™
| foo |
| foo |
| foo |
| foo |
| foo |
| foo |
<style>
.Attribute2 tr td{padding:12px;border:solid 1px #336600;}
.Attribute2 tr[NAME]
{
background:#663399;color:white;
}
.Attribute2 tr
{
behavior:expression( void( CSS.hasAttribute(this,"NAME")?this.className="yes":0 ) );
}
.Attribute2 tr.yes
{
background:#663399;color:white;
}
</style>
<div class="Attribute2">
<table>
<tr name="odd"><td>foo</td></tr>
<tr><td>foo</td></tr>
<tr name="odd"><td>foo</td></tr>
<tr><td>foo</td></tr>
<tr name="odd"><td>foo</td></tr>
<tr><td>foo</td></tr>
</table>
</div>
<tr /> with roll-over effect
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
| text node | text node | text node | text node |
<style>
.Hover1{border:solid 1px #aaaaaa;border-collapse:collapse;}
.Hover1 tr td
{
border:solid 1px #aaaaaa;
padding:6px;
}
.Hover1 tr
{
behavior:expression( void( CSS.hover(this,"hover") ) );
}
.Hover1 tr:hover td
{
color:white;
background:#333366;
}
.Hover1 tr.hover td
{
color:white;
background:#333366;
}
</style>
<table class="Hover1">
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
<tr><td>text node</td><td>text node</td><td>text node</td><td>text node</td></tr>
</table>
<input /> with focus effect
<style>
.Focus1 input:focus{background:yellow !important;}
.Focus1 input.red{background:red;}
.Focus1 input.focus{background:yellow !important;}
.Focus1 input{behavior:expression( void( CSS.focus(this,"focus") ) );}
</style>
<div class="Focus1">
<input type="text"class="red" />
<input type="text" />
<input type="text" />
</div>
Now we can combine these CSS 2.0 selectors to make our own semantic markup
<style>
.summary_hd{padding:4px;}
.summary_bd{ _height:50px; border:solid 12px #aaaaaa; }
.summary_bd .pri{ width:49.9%; float:left;padding:12px 0; }
.summary_bd .sec{ width:49.9%; float:right; padding:12px 0; }
.summary_bd:after{content:url(http://tw.yahoo.com/p.gif);display:block;clear:both;height:1px;}
.summary_bd .tool
{
margin:0;padding:0;list-style:none;text-align:right;margin:0 0 0 12px;
padding:4px 12px 4px 0;border-bottom:solid 6px #FF9900;
}
.summary_bd .tool li{ margin:0 4px;padding:0;list-style:none;display:inline;}
.summary_bd[class] .tool li{background:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/49.gif) left center no-repeat;
padding:4px 0 4px 22px;}
.summary_bd[class] .tool li+li{background-image:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/50.gif)}
.summary_bd[class] .tool li+li+li{background-image:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/51.gif)}
.summary_bd[class] .tool li+li+li+li{background-image:url(http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/52.gif)}
.summary_bd .tool li{behavior:expression(
void( CSS.getTagIndex(this) ) ||
void( CSS.insertHTML(this,"http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons6/" + ( 49 + this.tagIndex ) +".gif" ,2))
);}
.summary_bd .tool li img{vertical-align:middle;margin:0 2px;}
.summary_bd .item li
{
border-top:solid 1px #666666;
padding:4px;list-style:none;text-align:right;
behavior:expression(
void(CSS.isFirstTag(this)?this.style.borderTop="none":0 ) ||
void(CSS.hover(this,"hover") ) ||
void(CSS.insertHTML(this,"<span>▶</span>",2) )
);
}
.summary_bd .item li:first-child{border-top:solid 0px #666666;}
.summary_bd .item li:hover{background:#FFCC00;}
.summary_bd .item li:before{content:"\25BA";color:red;margin: 4px;}
.summary_bd .item li span{color:red;margin: 4px;}
.summary_bd .item li.hover{background:#FFCC00;}
.summary_bd .sec label{display:block;clear:both;margin:4px;}
.summary_bd .sec input{font-family:Verdana;}
.summary_bd .sec label input
{
margin:0 4px;vertical-align:middle;
behavior:expression( void( CSS.focus(this,"focus") ) || void( CSS.htmlFor(this) ));
}
.summary_bd .sec label b{display:block;width:8em;text-align:right;float:left;vertical-align:middle;cursor:pointer;cursor:hand;color:black;font-weight:normal;}
.summary_bd .sec label input:focus{background:yellow;}
.summary_bd .sec label input.focus{background:yellow;}
.summary_bd .sec input[type="submit"],.summary_bd .sec input[type="reset"]{ cursor:pointer;background:#333366;color:white;}
.summary_bd .sec p input:hover{background:orange;}
.summary_bd .sec p input{behavior:expression( void(CSS.hover(this,"hover") ) )}
.summary_bd .sec p input.hover{background:orange;}
</style>
<div class="summary_hd">Compatible with IE5.0+ and CSS2.0 enabled browsers.</div>
<div class="summary_bd">
<div class="pri">
<ul class="tool">
<li><a href="#">email</a></li>
<li><a href="#">print</a></li>
<li><a href="#">save</a></li>
<li><a href="#">add to list</a></li>
</ul>
<ul class="item">
<li>this is a hover item</li>
<li>this is a hover item</li>
<li>this is a hover item</li>
<li>this is a hover item</li>
<li>this is a hover item</li>
</ul>
</div>
<div class="sec">
<form>
<label><b>text box</b><input type="text" /></label>
<label><b>text box</b><input type="text" /></label>
<label><b>text box</b><input type="text" /></label>
<label><b>text box</b><input type="text" /></label>
<label><b>check box</b><input type="checkbox" name="ck" /></label>
<label><b>check box</b><input type="checkbox" name="ck" /></label>
<label><b>check box</b><input type="checkbox" name="ck" /></label>
<label><b>check box</b><input type="checkbox" name="ck" /></label>
<p>
<input type="submit" value="submit" />
<input type="reset" value="reset" />
</p>
</form>
</div>
</div>