Thursday, January 17, 2013

CSS - Horizontal menu, show sub-menus on hover, autohide when hover is moved


Following example how to create navigation horizontal menu, with following features:

- menu items have horizontal sub-menus with one row
- menu item for current page is highlighted
- sub-menu for current page is always shown, except when overlapped with sub-menu from hovered menu item
- sub-menus for hovered items are automatically hidden when hover is moved to another item, except for sub-menu for current page


Picture 1

Full CSS code is given below:

html  
{
   min-width: 600px; 
}

body, div, td, th, h2, h3, h4 
{ 
   font-family: verdana,sans-serif;
 font-size: x-small;
 voice-family: "\"}\"";
 voice-family: inherit;
 font-size: small;
 color: #030303; 
}

div
{
 border: none;
 border: 0px;
 margin: 0px;
 padding: 0px;
 font-family: verdana,geneva,arial,helvetica,sans-serif;
 font-size: 14px;
 font-weight: normal;
 color: #030303;
}

p.note 
{
 background: #E0E0E0;
 padding: 4px;
 font-family: tahoma;
 font-size: 85%;
 line-height: 130%;
 margin-top: 0;
}

#contents 
{
 border: 2px solid #000000;
 padding: 15px;
 background: #D0D0D0;
 min-height: 300px;
}

#ulNav 
{
 position: relative;
 display: block;
 height: 28px;
 width: 100%;
 background: #224D6F;
 /*background: url(../images/menu-bg.gif) top left repeat-x;*/
 margin: 0;
 padding: 0;
}

#ulNav li ul
{
 display: block; 
}

#ulNav a 
{
 text-decoration: none;
}

#ulNav li 
{ 
 margin: 0;
 float: left;
 display: block;
 padding-right: 15px;
 text-align: center;
 line-height: 28px;
}

#ulNav li ul 
{
 display: none;
}

#ulNav li.off ul, #ulNav li.on ul  
{ 
 position: absolute;
 top: 25px;
 left: 0; 
 background: #224D6F;
 /*background:url(../images/menu-bg.gif) top left repeat-x;*/
 height: 28px;
 width: 100%;
 margin: 0;
 padding: 0;  
}

#ulNav li.on ul 
{
 background: #224D6F;
 /*background:url(../images/menu-bg.gif) top left repeat-x;*/
 width: 100%;
 margin: 0;
 padding: 0;  
}

#ulNav li.on:hover ul, #ulNav li.over ul /*for ie*/
{  
 background: #224D6F;
 /*background:url(../images/menu-bg.gif) top left repeat-x;*/
 width: 100%;
}

#ulNav li a 
{
 color: #FFFFFF;
 font-weight: bold; 
 display: block;
 width: 93px;
 padding: 0;  
}

#ulNav li.on a 
{
 color: #FF6A00;
}

#ulNav li.on ul a, #ulNav li.off ul a 
{
 border: 0;
 float: left; /*ie doesn't inherit the float*/
 color: #FF6A00;
 width: 100%;
 margin: 0;
 padding: 0; 
}

#ulNav li.on:hover ul a, #ulNav li.over ul li a /*for ie - the specificity is necessary*/
{ 
 background: #224D6F;
 /*background: url(../images/menu-bg.gif) top left repeat-x;*/
}

#ulNav li.on ul 
{
 display: block;
}

#ulNav li.off:hover ul, #ulNav li.over ul 
{
 display: block;
 z-index: 6000;
}

#ulNav li.off a:hover, #ulNav li.on a:hover 
{ 
 color: #FF6A00;
}

#ulNav li span 
{
 position: absolute;
}

#liSubnav a 
{
 display: block;
 position: relative;
 height: 28px;
}

#ulNav li.off ul a, #ulNav li.on ul a 
{
 display: block;
 background: #224D6F;
 /*background: url(../images/menu-bg.gif) top left repeat-x;*/
 color: #FFFFFF;
 font-family: arial, verdana, sans-serif;
 font-size: small;
 margin: 0;
 padding: 0;
 padding-left: 10px;
}  

#ulNav li.on ul a 
{
 background: #224D6F;
 /*background: url(../images/menu-bg.gif) top left repeat-x;*/
 margin: 0;
 padding: 0;
 padding-left: 10px;
}
  

Apply CSS in your web page code, for all pages. For current page, set href="#" id="current". For given snapshots, HTML code looks like this:

<div>
    <ul id="ulNav">
     <li id="liSubnav" class="off"><a href="Home.aspx">Home</a></li>
     <li id="liSubnav" class="off"><a href="Services.aspx">Services</a>
        <ul>
     <li><a href="#">Finance</a></li>
       <li><a href="#">Weather</a></li>
       <li><a href="#">Shopping</a></li>
      </ul>
   </li>
     <li id="liSubnav" class="on"><a href="#" id="current">Community</a>
        <ul>
       <li><a href="#">Blog</a></li>
       <li><a href="#">Chat</a></li>
       <li><a href="#">Forum</a></li>    
      </ul>
   </li>
     <li id="liSubnav" class="off"><a href="About.aspx">About</a>
        <ul>
       <li><a href="#">Company</a></li>
       <li><a href="#">People</a></li>
       <li><a href="#">Careers</a></li>
      </ul>
     </li>
     <li id="liSubnav" class="off"><a href="Contact.aspx">Contact</a></li>
    </ul>
 </div>

If you like to have modern look, with gradient menu items, use background image, instead of simple color. Image in Picture 2 could be used to get look from Picture 3:

Picture 2


Picture 3


To achieve this, put background image to img (or any other) sub-folder in your project. In all #ulNav sections, replace background: #224D6F; with background: url(../images/menu-bg.gif) top left repeat-x;.

XSL - Create Bar Chart

When using XSL templates to transform XML data to HTML, there is a frequent need to present some sort of statistics, in a form different than simple table. Chart could be a common choice. Bar chart could be generated from input data using simple XSL/HTML tags.

Following example uses four ranges on X axis, with respective percentages presented as bars for each range. Y axis is divided into five ranges.

<table cellSpacing="0" cellPadding="0" align="center" style="border-right: white 0px solid; border-top: white 0px solid; ; border-left: white 0px solid; border-bottom: white 0px solid; text-align: center">
 <tbody>
<tr>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: black 1px solid; width: 30px; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; width: 20px; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; width: 60px; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; width: 60px; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; width: 60px; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; width: 60px; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: black 1px solid; border-left: white 0px solid; width: 10px; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid"/>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td rowSpan="10" vAlign="bottom" align="center"
       style="border-right: white 0px solid; padding-right: 0px; border-top: black 1px solid; padding-left: 0px; font-size: 1px; padding-bottom: 0px; border-left: black 1px solid; padding-top: 0px; border-bottom: black 1px solid">
    <table style="border-right: black 1px solid; border-top: black 1px solid; ; border-left: black 1px solid; width: 80%; border-bottom: white 0px solid">
     <tbody>
<tr style="background-color: lime; height: 15px;">
       <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
      </tr>
</tbody>
    </table>
</td>
   <td rowSpan="10" vAlign="bottom" align="center"
       style="border-right: white 0px solid; padding-right: 0px; border-top: black 1px solid; padding-left: 0px; font-size: 1px; padding-bottom: 0px; border-left: white 0px solid; padding-top: 0px; border-bottom: black 1px solid">
    <table style="border-right: black 1px solid; border-top: black 1px solid; ; border-left: black 1px solid; width: 80%; border-bottom: white 0px solid">
     <tbody>
<tr style="background-color: yellow; height: 35px;">
       <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
      </tr>
</tbody>
    </table>
</td>
   <td rowSpan="10" vAlign="bottom" align="center"
       style="border-right: white 0px solid; padding-right: 0px; border-top: black 1px solid; padding-left: 0px; font-size: 1px; padding-bottom: 0px; border-left: white 0px solid; padding-top: 0px; border-bottom: black 1px solid">
    <table style="border-right: black 1px solid; border-top: black 1px solid; ; border-left: black 1px solid; width: 80%; border-bottom: white 0px solid">
     <tbody>
<tr style="background-color: cyan; height: 20px;">
       <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
      </tr>
</tbody>
    </table>
</td>
   <td rowSpan="10" vAlign="bottom" align="center"
       style="border-right: black 1px solid; padding-right: 0px; border-top: black 1px solid; padding-left: 0px; font-size: 1px; padding-bottom: 0px; border-left: white 0px solid; padding-top: 0px; border-bottom: black 1px solid">
    <table style="border-right: black 1px solid; border-top: black 1px solid; ; border-left: black 1px solid; width: 80%; border-bottom: white 0px solid">
     <tbody>
<tr style="background-color: magenta; height: 30px;">
       <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
      </tr>
</tbody>
    </table>
</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid">80%</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid">60%</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid">40%</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid">20%</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td rowSpan="2" style="border-right: white 0px solid; border-top: black 1px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid"/>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid"/>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-weight: bold; font-size: 10pt; border-left: white 0px solid; border-bottom: white 0px solid">Range 1</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-weight: bold; font-size: 10pt; border-left: white 0px solid; border-bottom: white 0px solid">Range 2</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-weight: bold; font-size: 10pt; border-left: white 0px solid; border-bottom: white 0px solid">Range 3</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-weight: bold; font-size: 10pt; border-left: white 0px solid; border-bottom: white 0px solid">Range 4</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: white 0px solid; height: 10px"/>
  </tr>
<tr>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: black 1px solid; border-bottom: black 1px solid"/>
   <td style="border-right: white 0px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: black 1px solid"/>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-size: 10pt; border-left: white 0px solid; border-bottom: black 1px solid">15%</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-size: 10pt; border-left: white 0px solid; border-bottom: black 1px solid">35%</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-size: 10pt; border-left: white 0px solid; border-bottom: black 1px solid">20%</td>
   <td style="border-right: white 0px solid; border-top: white 0px solid; font-size: 10pt; border-left: white 0px solid; border-bottom: black 1px solid">30%</td>
   <td style="border-right: black 1px solid; border-top: white 0px solid; border-left: white 0px solid; border-bottom: black 1px solid; height: 10px"/>
  </tr>
</tbody>
</table>


The basic point is to create regular table. For example with 4 ranges on X scale and 5 ranges on Y scale, table should have 13 rows, with 7 columns in each row. Some columns are spanned (merged) over multiple rows, allowing labels and bars to be defined. The outlook of "raw" table, with hidden borders shown dotted, is presented in Picture 1:
Picture 1
When merger is implemented to create row for bars, they are simply defined using heights in pixels.

Replace hardwired values from example with values read from source XML file.

The resulting HTML in browser is shown in Picture 2:

Picture 2