Modern Web Design - Moving forward to CSS2.0

Intro

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>

Practice : Generated contents before or after texts

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.

Traditional markup

Old fasioned markup, easy to write, hard to maintain. Less semantic since decoration images are not contents at all.

example
text icon text 1
<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

Semantic markup with CSS2.0

More semantic, and the presentation layer is separated for data and structure. However, IE6.0- won`t recognize it.

example
text 1
<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.

example
text 1
<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)

Semantic markup with CSS2.0 + CSS2.0 Patch for IE6.0-

Now we will make it work for standard web browsers and IE5.0+

example
Do you see a little icon before the content?
<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>

syntax: behavior:expression( void( CSS.insertHTML(x, y, z) ) )

Now let`s make a simple example!

example
icon after content icon after content character before content character before content
<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>&gt;</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

syntax: behavior:expression( void( CSS.quotes(x, y, z, k) ) )

example
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 = [ "&nbsp;","(",")"," ","{","}",":","*","&","[&nbsp;","&nbsp;]"];
   */
}
</style>

<div class="Quotes1">
   <q>Text Node</q>
   <q>Text Node</q>
   <q>Text Node</q>
</div>

Practice : ChildNode selector

syntax: behavior:expression( void( CSS.isFirstTag(x) ) )

first-child`s border-top-color is white

example
<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

example

<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

example

<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 />

syntax: behavior:expression( void( CSS.isChildOf(x, y) ) )

selected by parentNode`s className

example
child
grandchild
<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

example
child
grandchild
<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

example
child
grandchild
foo~~
<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>

Practice : Sibling selector

syntax: behavior:expression( void( CSS.nextSibling(x, y) ) )

the second <span /> has different icon

example

<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

example
  1. Text Node
  2. Text Node
  3. Text Node
  4. Text Node
  5. Text Node
  6. Text Node
  7. Text Node
  8. Text Node
  9. Text Node
  10. Text Node
<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>


Practice : Attribute selector

syntax: behavior:expression( void( CSS.hasAttribute(x, y, z) ) )

<input /> with attribute type="submit"

example
<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™

example
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>

Practice : Hover effect

syntax: behavior:expression( void( CSS.hover(x, y) ) )

<tr /> with roll-over effect

example
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext node
text nodetext nodetext nodetext 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>

Practice : Focus effect

syntax: behavior:expression( void( CSS.focus(x, y) ) )

<input /> with focus effect

example
<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>

Practice :Summary

Now we can combine these CSS 2.0 selectors to make our own semantic markup

example
Compatible with IE5.0+ and CSS2.0 enabled browsers.
  • this is a hover item
  • this is a hover item
  • this is a hover item
  • this is a hover item
  • this is a hover item



<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>&#9654;</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>



guest book | visitors