Best html questions in March 2012

Why does CSS margin top not work?

24 votes

I try to add margin values on a div inside another div. All works fine except the top value, it seems to be ignored. But why?

What I expected:
What I expected with margin:50px 50px 50px 50px;

What I get:
What I get with margin:50px 50px 50px 50px;

CSS:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}

HTML:

<div id="outer">
    <div id="inner">
        Hello world!
    </div>
</div>

W3Schools have no explanation to why margin behave this way.

You're actually seeing the top margin of the #inner element collapse into the top edge of the #outer element, leaving only the #outer margin intact (albeit not shown in your images). The top edges of both boxes are flush against each other because their margins are equal.

Here are the relevant points from the W3C spec:

8.3.1 Collapsing margins

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

Adjoining vertical margins collapse [...]

Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context
  • no line boxes, no clearance, no padding and no border separate them
  • both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
    • top margin of a box and top margin of its first in-flow child

The reason why floating either of your div elements, setting either of them to inline-block, or setting overflow: auto to #outer prevents the margin collapse is because:

  • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
  • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
  • Margins of inline-block boxes do not collapse (not even with their in-flow children).

The left and right margins behave as you expect because:

Horizontal margins never collapse.

History of h1, h2...h6 headings in HTML

21 votes

I am curious about the history of the h1, h2...h6 elements in HTML. In particular, I would like to know why were chosen 6 levels and not, for example 8 levels. Is there any historical reason?

The oldest reference to a reason I have seen is this document from 1992 (http://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html) but it only states that:

These tags are kept as defined in the CERN SGML guide. Their definition is completely historical, deriving from the AAP (American Association of Publishers) tag set.

But I was not able to find any further reference or explanation for the limit of 6 levels.

Such that I've been able to learn to date: ISO 12083, which descends from the AAP DTD, is completely hierarchical with a tag serving the function that the six header tags would in HTML. XHTML 2 revives the AAP view of things.

HTML descends from GML (via CERN-SGML), both of which defined h0 to h6, with h0 and the h5 and h6 pair having a slightly different semantic meaning to h1 to h4. GML significantly predates the AAP work so is the lead to follow.

Looking into the GML definition for h tags it just looks like seven (including h0) was how many they needed to offer all the interesting combinations and permutations of features within the table given.

So, I think the answer is: GML defined h0 to h6 based on the judged semantic and stylistic needs of an average document, being designed for a very simple and constrained type of markup. HTML inherited them via SGML.

Jump Link Inside an iFrame

12 votes

Inside an iframe (on page-A), I have a simple page (page-B) that has a few jump links (e.g. <a href="#my-id">jump link</a>) to different sections of the page (page-B). The iframe height is preset to be longer than page-B's height; this is a requirement.

For some reasons, the jump links didn't work on FF (I am on Mac/FF 10.0.2); however, it worked properly on Safari and IE8. This is the sample page.

Code of page

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jump Link Test on an iFrame</title>
</head>
<body>
<h1>Page that has an iFrame</h1>
<iframe width="100%" height="2000" src="./iframe.html" frameborder="0" scrolling="no">
</iframe>
</body>
</html>

Code of iframe.html

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>iFrame Content</title>
<style type="text/css">
.box {
    margin: 0 0 5px;
    width: 400px;
    height: 400px;
}
#box1 {
    background-color: #f00;
}
#box2 {
    background-color: #f0f;
}
#box3 {
    background-color: #00f;
}
</style>
</head>
<body>
<ul>
    <li><a href="#box1">Box 1</a></li>
    <li><a href="#box2">Box 2</a></li>

    <li><a href="#box3">Box 3</a></li>
</ul>
<div>
    <div id="box1" class="box"></div>
    <div id="box2" class="box"></div>
    <div id="box3" class="box"></div>
</div>
</body>
</html>

Note: If I set the iframe height < page-B's height, the problem will be solved. However, unfortunately this isn't an option given my situation because I have no access to page-A.

This is not possible with HTML only.

As you can read on the Firefox Bug Report Nr. 638598 this is mentioned long time ago! Also many people don't like that behavior, but Jonas Sicking says in his comment that this will never change. He sees that as a feature that firefox prevent this potential hacking functionality.

if you don't know him read here that he is the Tech Lead of the project at mozilla as well as an editor for the and specifications at W3C.

Other people tried to find solutions like Matthew but this example didn't work in my short test case with your html structure. Some others say that it should work with JavaScript and the scrollTo() Function.

I'm sorry for saying that this is a limitation of FireFox only, but hope you are happy to be safe in the knowledge about that problem.

Two CSS Classes: Which one Wins?

11 votes

The markup below aligns SAMPLE TEXT to the left.

To me, it seems like it should be aligned to the right. The class that aligns to the right is declared after the one that aligns left. And the class that aligns to the right is even referenced last. So why does the class that aligns to the left win?

CSS

.table {
    width: 100%;
}
.table td {
    text-align: left;
}
.cell {
    text-align: right;
}

HTML

<table class="table">
    <tr>
        <td class="cell">
             SAMPLE TEXT
        </td>
    </tr>
</table>​

Please see my jsFiddle Example.

The .table td selector has a higher specificity. CSS specificity rules are kind of weird... IDs weigh more than class names, which weigh more than tag names.

The specificity rules, in a nutshell:

  • For each tag name, add 1.
  • For each class name, add 10.
  • For each ID, add 100.

The higher values will always override the lower ones. In the case of a tie, the last rule loaded wins.

How can I get array of elements, including missing elements, using XPath in XSLT?

10 votes

Given the following XML-compliant HTML:

<div>
 <a>a1</a>
 <b>b1</b>
</div>

<div>
 <b>b2</b>
</div>

<div>
 <a>a3</a>
 <b>b3</b>
 <c>c3</c>
</div>

doing //a will return:

[a1,a3]

The problem with above is that the third column data is now in second place, when A is not found it is completely skipped.

how can you express an xpath to get all A elements which will return:

[a1, null, a3]

same case for //c, I wonder if it's possible to get

[null, null, c3]

UPDATE: consider another scenario where are no common parents <div>.

<h1>heading1</h1>
 <a>a1</a>
 <b>b1</b>


<h1>heading2</h1>
 <b>b2</b>


<h1>heading3</h1>
 <a>a3</a>
 <b>b3</b>
 <c>c3</c>

UPDATE: I am now able to use XSLT as well.

There is no null value in XPath. There's a semi-related question here which also explains this: http://www.velocityreviews.com/forums/t686805-xpath-query-to-return-null-values.html

Realistically, you've got three options:

  1. Don't use XPath at all.
  2. Use this: //a | //div[not(a)], which would return the div element if there was no a within it, and have your Java code handle any div's returned as 'no a element present'. Depending on the context, this may even allow you to output something more useful if required, as you'll have access to the entire contents of the div, for example an error 'no a element found in div (some identifier)'.
  3. Preprocess your XML with an XSLT that inserts a elements in any div element that does not already have one with a suitable default.

Your second case is a little tricky, and to be honest, I'd actually recommend not using XPath for it at all, but it can be done:

//a | //h1[not(following-sibling::a) or generate-id(.) != generate-id(following-sibling::a[1]/preceding-sibling::h1[1])]

This will match any a elements, or any h1 elements where no following a element exists before the next h1 element, or the end of the document. As Dimitre pointed out though, this only works if you're using it from within XSLT, as generate-id is an XSLT function.

If you're not using it from within XLST, you can use this rather contrived formula:

//a | //h1[not(following-sibling::a) or count(. | preceding-sibling::h1) != count(following-sibling::a[1]/preceding-sibling::h1)]

It works by matching h1 elements where the count of itself and all preceding h1 elements is not the same as the count of all h1 elements preceding the next a. There may be a more efficient way of doing it in XPath, but if it's going to get any more contrived than that, I'd definitely recommend not using XPath at all.

Bottom to top <ul> element arrangement

9 votes

I'm trying to find out how I can force elements to start from the bottom going to the top.

I have searched through stackoverflow and I can't seem to get the answer that i need. This picture should explain it:

explanation image

This should help too:

<?php require("connectdb.php"); ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Dynamic Drag'n Drop</title>
<script type="text/javascript" src="javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="javascript/jquery-ui-1.7.1.custom.min.js"></script>
<script type="text/javascript" src="javascript/jquery.ui.ipad.altfix.js"></script>


<style>
body {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
    margin-top: 10px;
}

ul {
    margin: 0;
}

#contentWrap {
    width: 800px;
    margin: 0 auto;
    height: 500px;
    overflow: hidden;
    background-color: #FFFFFF;
    border: solid 2px #EEEEEE;
}

#contentTop {
    width: 600px;
    padding: 10px;
    margin-left: 30px;
}

#sortable { list-style-type: none; margin: 0; padding: 0;}

#sortable li { margin: 20px 20px 1px 20px; 
padding: 1px;
 float: left; 
 width: 70px; 
 height: 70px; 
 font-size: 12px;
 text-align: center; 
 background-color:#cfcfcf;
 position: absoute;
 bottom: 0;
 display: inline-block;
 float: right;
 }


#contentRight {
    float: right;
    width: 300px;
    margin-top: 100px;
    padding:10px;
    background-color:#336600;
    color:#FFFFFF;
}

#save
{    
    width: 100px;
    height: 30px;
    margin-right: auto;
    margin-left: auto;
    background-color:#336600;
    color:#FFFFFF;
    text-align: center;
}
.on { background-color:#000000; color:#782322; }

            #header{
                background-color: #EEEEEE;
                font-weight: bold;
                width: 804px;
                margin-left: auto ;
                margin-right: auto ;
                padding: 2;
            }
</style>


<script type="text/javascript">
//$(document).ready(function(){ 



    $(function() {

    $(document).bind('touchmove', function(e) {
        e.preventDefault();
    }, false);  

        $("#sortable").sortable({ opacity: 0.6, cursor: 'move', update: function()     {
            var order = $(this).sortable("serialize") +     '&action=updateRecordsListings'; 
            $.post("updateDB.php", order, function(theResponse){
            });                                                              
        }                                 
        }).addTouch();
        $( "#sortable" ).disableSelection();

        //$("li").click(function(){
            //$(this).addClass("on");
        //});   
    });

//});   
</script>

</head>
<body>
    <?php 
        session_start();
        $teacherID = $_SESSION['teacherID'];
        $classID = $_SESSION['csID'];
        $qryClass = "SELECT * FROM class_schedule WHERE csID = '". $classID ."';";
        $class = mysql_query($qryClass);
        while($row = mysql_fetch_array($class))
        {
            $subjCode = $row['subjCode'];
            $section = $row['section'];
            $semester = $row['semester'];
            $sy = $row['SY'];
            $time = $row['time'];
        }
    ?>
    <div id = "header">
        <?php 
            //echo "What do you want to do, " .$fname . "?<br>";
            echo "Subject: " . $subjCode . " Block: " . $section . " -     Semester:" . $semester . " - SY:" . $sy . " - " . $time;
        ?>
    </div>
    <div id="contentWrap">
            <ul id="sortable">
                <?php
                session_start();
                $query  = "SELECT e.*, CONCAT(s.lname,', ', s.fname) name     FROM enrollment e, student s
WHERE e.studentID = s.studentID AND e.csID = '". $classID ."' ORDER BY sort;";
                $result = mysql_query($query);
                $c = 0;
                while($row = mysql_fetch_array($result, MYSQL_ASSOC))
                {
                    //if($c != 4)
                        echo "<li id='recordsArray_'"     . $row['id'] . ">" . $row['name'] . "</li>";
                }
                ?>
            </ul>       

    </div>
    <div id="save">
        Blackboard
    </div>


</body>
</html>

A css solution fiddle

ul, ul li {
-webkit-transform: scaleY(-1);
   -moz-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
     -o-transform: scaleY(-1);
        transform: scaleY(-1);

}
ul {
    width: 350px;
}
 li {
    display: inline-block;
    width: 70px;
    zoom: 1;         
    *display: inline;
}

This works by flipping the entire UL and then each LI on it's Y axis.

Creating a color palette, <img> or <div> or <canvas>?

9 votes

I'm currently working on an color-picker component using HTML, CSS and Javascript, one major question is how I should implement a color palette like this one:

enter image description here

Ignoring browser compatibility issues introduced by IE8 or earlier, I have 3 methods to implement this:

  1. The <img> way:

    This is simple and is used by many color-picker components for years, we simply include an image exactly the same as the above one using <img src="palette.png" />.

    The problem is <img> would introduce extra network roundtrip, although we can prevent it using dataURI, but an image data is a little too large for me.

  2. The <div> way:

    In this way we should use 2 <div> elements, one of them provides a left-to-right linear gradient and the other provides a top-to-bottom alpha gradient, the style should be:

    <style>
        #map {
            width: 400px; 
            height: 400px;
            background: -webkit-gradient(
                linear, left top, right top, 
                color-stop(0%,#ff0000), 
                color-stop(16.67%,#ffff00), 
                color-stop(33.33%,#00ff00),
                color-stop(50%,#00ffff), 
                color-stop(66.67%,#0000ff),
                color-stop(83.33%,#ff00ff), 
                color-stop(100%,#ff0000)
            );
        }
        #overlay {
            width: 400px;
            height: 400px;
            background: -webkit-gradient(
                linear, left top, left bottom, 
                from(rgba(0, 0, 0, 0)), 
                to(rgba(0, 0, 0, 1))
            );
        }
    </style>
    
    <div id="palette"><div id="overlay"></div></div>
    

    It works perfectly, but the problem is, this method introduces 2 elements for styling only, the 2 <div> elements don't have any semantic meanings and don't act as a generic container or block, this is a violation to semantic HTML.

  3. The <canvas> way:

    <canvas> provides very flexible graphic API to implement such a color palette, I use these code to draw it:

    var context = canvas.getContext('2d');
    
    var palette = context.createLinearGradient(0, 0, 360, 0);
    palette.addColorStop(0 / 6, '#ff0000');
    palette.addColorStop(1 / 6, '#ffff00');
    palette.addColorStop(2 / 6, '#00ff00');
    palette.addColorStop(3 / 6, '#00ffff');
    palette.addColorStop(4 / 6, '#0000ff');
    palette.addColorStop(5 / 6, '#ff00ff');
    palette.addColorStop(6 / 6, '#ff0000');
    context.fillStyle = palette;
    context.fillRect(0, 0, 360, 360);
    
    var overlay = context.createLinearGradient(0, 0, 0, 360);
    overlay.addColorStop(0, 'rgba(0, 0, 0, 0)');
    overlay.addColorStop(1, 'rgba(0, 0, 0, 1)');
    context.fillStyle = overlay;
    context.fillRect(0, 0, 360, 360);
    

    It works as well as the above 2 approaches, but I wonder whether I should use canvas to draw such a static image, shouldn't canvas be used in more dynamic and complex enviroment?

So which way should I go to implement a simple color palette, or is there a better approach?

If you wanted to use an image, but don't want the extra request, you could use a data URI:

<img width="184" height="184" title="" alt="" src="data:image/png;base64,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" />

Demo

How to avoid custom/Server error in web site?

8 votes

I have asp.net web application located on server I want to avoid all custom and server error from my site.

For that I have used

<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPage/TryAgainLater.aspx">   <error redirect="~/ErrorPage/PageNotFound.aspx" statusCode="404"/> </customErrors>

Using above code will able avoid some issue. ie.

Suppose "http://Exaple.com/Careers.aspx" Page available in my site then

Case 1. http://Exaple.com/Careersss.aspx "It was working correct as per above rule".

Case 2. http://Exaple.com/!@##Careersss.aspx "Not working" Note : Here I add special character

Case 3: http://Exaple.com/Careersss.aspxxxx "Not working" Note : add character after ".aspx"

case 4: http://Exaple.com/Careersss.aspx/!@!@!@! "Not works design breaking here". Note : Add '/' with special character.

please help me when user get case 2,3,4 then they automatically redirected to error page.

Thanks In advance.

For above problem we have to change IIS Setting please refer :

http://www.braintrove.com/id/46/page/2#Configure-IIS-for-custom-error-pages

http://blogs.msdn.com/b/webtopics/archive/2008/05/28/iis-7-0-http-error-pages.aspx

How is text thickness calculated according to css property "font-weight"?

7 votes

Font weight in Firefox:

font-weight in firefox

Font weight in Chrome:

font-weight in chrome

The font-weight value is in the order of 100,500,600,700,900, which is set according to the W3C standard.

You can clearly see that the text thickness is not changed linearly, and in different browser not exactly the same (it's almost the same from 100 to 500.). So I wonder, is there a standard on how the text is calculated according to font-weight?

The algorithm, at least in theory, is: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-weight

The CSS3 specification is similar - http://www.w3.org/TR/css3-fonts/#font-weight-prop

As it states, bold faces are often synthesized by user agents for faces that lack actual bold faces.

I've found its often better to avoid font-weights all together, and use a specific font face.

Can you create this shadowed gradient style line using CSS3?

7 votes

Here's a picture of exactly what I'm trying to produce.

I've been able to style a <hr /> using SVG as the background image to create this effect, but would like to be able to produce the same thing using CSS3 I've but have been having trouble.

I was wondering if any CSS gurus out there might know a way to achieve the same thing or if it's not really possible w/ pure CSS?

Thanks for any help.

I create the effect which you want please check this:

http://jsfiddle.net/fx5Lk/

Using Javascript: How to create a 'Go Back' link that takes the user to a link if there's no history for the tab or window?

7 votes

EDIT-2: None of the answers seem to work. Not even the one I previously marked as the answer of this question. Any help is appreciated. Thanks.

First, I have googled for a how-to on creating a 'Go Back' link that allows the user to return to the previous page, and these are two ways of doing it:

<a href="javascript:history.go(-1)">[Go Back]</a>

and...

<a href="#" onclick="history.go(-1);return false;">[Go Back]</a>

Which of these two is a better choice? And why? (Also, please shed some light on browser compatibility.)

That's one half of the question. Now if mine is the first page the user is visiting, the 'Go Back' link wouldn't work, right? (As there's no pre-existing history for the window or tab.) In that case, I want the link to fallback and take the user to http://example.com.

i.e. if history exists, the user is taken to the previous page, and if it doesn't he's taken to http://example.com.

How do I do that? Hope someone can help.

EDIT: Please note that I do not know JavaScript, so kindly make your answer explanative. Thanks.

You cannot check window.history.length as it contains the amount of pages in you visited in total in a given session:

window.history.length (Integer)

Read-only. Returns the number of elements in the session history, including the currently loaded page. For example, for a page loaded in a new tab this property returns 1. Cite 1

Lets say a user visits your page, clicks on some links and goes back:

www.mysite.com/index.html <-- first page and now current page                  <----+
www.mysite.com/about.html                                                           |
www.mysite.com/about.html#privacy                                                   | 
www.mysite.com/terms.html <-- user uses backbutton or your provided solution to go back

Now window.history.length is 4. You cannot traverse through the history items due to security reasons. Otherwise on could could read the user's history and get his online banking session id or other sensible information.

You can set a timeout, that will enable you to act if the previous page isn't loaded in a given time. However, if the user has a slow Internet connection and the timeout is to short, this method will redirect him to your default location all the time:

window.goBack = function (e){
    var defaultLocation = "http://www.mysite.com";
    var oldHash = window.location.hash;

    history.back(); // Try to go back

    var newHash = window.location.hash;

    /* If the previous page hasn't been loaded in a given time (in this case
    * 1000ms) the user is redirected to the default location given above.
    * This enables you to redirect the user to another page.
    *
    * However, you should check whether there was a referrer to the current
    * site. This is a good indicator for a previous entry in the history
    * session.
    *
    * Also you should check whether the old location differs only in the hash,
    * e.g. /index.html#top --> /index.html# shouldn't redirect to the default
    * location.
    */

    if(
        newHash === oldHash &&
        (typeof(document.referrer) !== "string" || document.referrer  === "")
    ){
        window.setTimeout(function(){
            // redirect to default location
            window.location.href = defaultLocation;
        },1000); // set timeout in ms
    }
    if(e){
        if(e.preventDefault)
            e.preventDefault();
        if(e.preventPropagation)
            e.preventPropagation();
    }
    return false; // stop event propagation and browser default event
}
<span class="goback" onclick="goBack();">Go back!</span>

Note that typeof(document.referrer) !== "string" is important, as browser vendors can disable the referrer due to security reasons (session hashes, custom GET URLs). But if we detect a referrer and it's empty, it's probaly save to say that there's no previous page (see note below). Still there could be some strange browser quirk going on, so it's safer to use the timeout than to use a simple redirection.

EDIT: Don't use <a href='#'>...</a>, as this will add another entry to the session history. It's better to use a <span> or some other element. Note that typeof document.referrer is always "string" and not empty if your page is inside of a (i)frame.

See also:

Best JavaScript WYSIWYG solution for a fixed box

7 votes

I have a box which is exactly 425px x 100px and I want my users to style this boxes content with a WYSIWYG editor. They should be able to use nearly every HTML inside of this box.

No, I'm looking for a proper WYSIWYG editor, I used to use TinyMCE for these kind of problems, but I think its best for a long continuous text, but right now I have a fixed box.

It would be great if the editor is able to position text and images absolute, so the user could position their contents wherever they want inside of this box.

http://ckeditor.com/

i found ckeditor useful, have rich functionality regarding image or text, allow you both WYSIWYG and html source formatting methods, and it also have fix sized "canvas" the user could customize according to need,

print screen of my practical use of it, enter image description here

and here is the source screen enter image description here and finally i am using 800x500 fixed size canvas

enter image description here

How to make hovering over one div to trigger changes in another div?

7 votes

I am looking to create the next effect for my next website:

  1. I have 3 DIVs with some text content in the left column.
  2. I have an image in a div in the right column.
  3. Image in the right div have 3 different independent image parts, each separate part has to be highlighted when I hover over one of the divs (related to that particular image part) in the column on the left. The DIV I am hovering over has to be highlighted as well on hover.
  4. I also want the same effect only this time when I hover over any of those image parts in DIV on in the right column. I want it to highlight the related div, as well as highlight image part itself.

I know it all might sound really confusing, so I made a picture hopefully explaining my project visually. (check the attached image).

Now I am not sure if this can be solely achieved with use of only CSS, or by combination of CSS and jQuery or smn.

If anyone ever encountered similar implementation, or knows where I can find a code example, or could direct me in the right direction, I would really appreciate it!!!

You could set up mouseover bindings on your continent image and its corresponding div on the left:

$('.div1').mouseover(hoverOne);
$('.continent1').mouseover(hoverOne);
var hoverOne = function(){
    //hightlight elements
}

//lather...rinse...repeat for the rest

XSLT to transform to HTML and format the HTML based on data in XML

6 votes

i am pretty new to XSLT / XML and HTML. I have a XML file that I currently convert to HTML in c# using an XSLT. The XML file represents nothing but data extracted from a table in a database. I can currently convert the XML file to HTML using XSLT fairly easily without much formating. the HTML when opened looks pretty ordinary. What i intend to is format the HTML i.e change the font, background color, font color etc based on certain key values in the XML document.

The XML is generated on a daily basis using C# code . the content of the XML file totally depends on the contents of the table in the database at that point in the day when the C# code is executed..

the XML looks something like this

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <defects>
    <Defectid>56</Defectid>
    <testid>111</testid>
    <summary>Release of DIT </summary>
    <DetectedDate>2011-09-21 </DetectedDate>
    <priority>2-Give High Attention</priority>
    <status>Ready to Test</status>
    <project>Business Intelligence</project>
    <assignedTo>peter</assignedTo>
    <detectedBy>john</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>829</Defectid>
    <testid>111</testid>
    <summary> Data request</summary>
    <DetectedDate>2012-01-12 </DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Open</status>
    <project>web</project>
    <assignedTo>tcm</assignedTo>
    <detectedBy>john</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>728</Defectid>
    <testid>999</testid>
    <summary>Data request</summary>
    <DetectedDate>2012-01-11</DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Fixed</status>
    <project>Business Intelligence</project>
    <assignedTo>chris</assignedTo>
    <detectedBy>peter</detectedBy>
    <severity>3-Average</severity>
  </defects>
</NewDataSet>

what i intend to do is generate and HTML table from this XML which would be in tabular format but the font color of the rows in the HTML table should be set based on "testid" attribute . i.e. for font color on the HTML should be unique per "testid" attribute. Since the rows per testid would change daily based on the data in the table in the database, I am not sure how this can be accomplished using XSLT.

the current XSLT looks something like this.. as you can see , I have hardcoded the font colors.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:template match="/">
    <table  BORDER="1" CELLPADDING="3" CELLSPACING="2" WIDTH="100">
      <tr>
        <td nowrap="nowrap" width = "70">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Defect ID</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "70">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Test ID</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "400">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Summary</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "150">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Detected Date</b>
          </h1>
        </td>
        <td width = "200">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Priority</b>
          </h1>
        </td>
        <td width = "200">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Status</b>
          </h1>
        </td>
        <td width = "200">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Project</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "100">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Assigned To</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "100">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Detected By</b>
          </h1>
        </td>
        <td nowrap="nowrap" width = "80">
          <h1 style="font-family:verdana ;font-size:60%;color:green">
            <b>Severity</b>
          </h1>
        </td>
      </tr>
      <xsl:for-each select="//defects">

        <tr>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="Defectid"></xsl:value-of>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="testid"/>
            </h1>
          </td>
          <td width = "400">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="summary"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="DetectedDate"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="priority"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="status"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="project"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="assignedTo"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="detectedBy"/>
            </h1>
          </td>
          <td width = "100">
            <h1 style="font-family:verdana ;font-size:60%;color:blue">
              <xsl:value-of select="severity"/>
            </h1>
          </td>

        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>

</xsl:stylesheet>

Does anybody know or could anybody guide me?

Below is a solution that applies up to 20 different colors - applying one particular color for each row with a specific testid.
Note that it is not important how many distinct testid's occur. Also note that color coding says nothing about the testid itself - but that's exactly the way you wanted it :-).

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
    version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:std="http://www.standardColors.com">

    <xsl:output method="html"/>

    <xsl:variable name="colors">
        <color>#0000FF</color>
        <color>#FF0000</color>
        <color>#00FFFF</color>
        <color>#FFFF00</color>
        <color>#347C2C</color>
        <color>#800080</color>
        <color>#3B9C9C</color>
        <color>#A52A2A</color>
        <color>#3BB9FF</color>
        <color>#FF00FF</color>
        <color>#6698FF</color>
        <color>#808000</color>
        <color>#8D38C9</color>
        <color>#ADD8E6</color>
        <color>#F660AB</color>
        <color>#F87217</color>
        <color>#F9B7FF</color>
        <color>#FFA500</color>
        <color>#FFE87C</color>
        <color>#8E35EF</color>
    </xsl:variable>

    <xsl:variable name="testIDs" select="distinct-values(//testid)"/>

    <xsl:variable name="colorList">
        <xsl:for-each select="$testIDs">
            <xsl:variable name="pos" select="position() mod 20"/>
            <xsl:copy-of select="$colors/color[$pos]"/>
        </xsl:for-each>
    </xsl:variable>

    <xsl:template match="/">
        <html>
            <head>
                <style>
                    th, td {
                        border: solid black 1px ;
                        padding: 3px;                       
                        border-spacing:2px;
                        border-collapse: collapse;
                        width: 100px;
                    }
                    th {
                        font-family:verdana;
                        font-size:60%;
                        color:green;
                        align:center;
                        white-space: nowrap;
                    }
                    <xsl:for-each select="$testIDs">
                    <xsl:variable name="pos" select="position()"/>
                     tr.testid<xsl:value-of select="."/> {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:<xsl:value-of select="$colorList/color[$pos]"/>;
                        align:center
                    }
                   </xsl:for-each>
                </style>
            </head>                
            <body>
                <table>
                    <tr>
                        <xsl:for-each select="/NewDataSet/defects[1]/*">
                            <th>
                                <xsl:value-of select="name(.)"/>
                            </th>
                        </xsl:for-each>
                    </tr>
                    <xsl:apply-templates select="*"/>
                </table>
            </body>
        </html>
   </xsl:template>

    <xsl:template match="/NewDataSet/defects">
        <tr>
            <xsl:attribute name="class">testid<xsl:value-of select="testid"/></xsl:attribute>
            <xsl:for-each select="*">
                <td>
                    <xsl:value-of select="."/>
                </td>
            </xsl:for-each>
        </tr>
    </xsl:template>

</xsl:stylesheet>

I applied this on the below xml:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <defects>
    <Defectid>56</Defectid>
    <testid>111</testid>
    <summary>Release of DIT </summary>
    <DetectedDate>2011-09-21 </DetectedDate>
    <priority>2-Give High Attention</priority>
    <status>Ready to Test</status>
    <project>Business Intelligence</project>
    <assignedTo>peter</assignedTo>
    <detectedBy>john</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>829</Defectid>
    <testid>111</testid>
    <summary> Data request</summary>
    <DetectedDate>2012-01-12 </DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Open</status>
    <project>web</project>
    <assignedTo>tcm</assignedTo>
    <detectedBy>john</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>728</Defectid>
    <testid>999</testid>
    <summary>Data request</summary>
    <DetectedDate>2012-01-11</DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Fixed</status>
    <project>Business Intelligence</project>
    <assignedTo>chris</assignedTo>
    <detectedBy>peter</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>728</Defectid>
    <testid>321</testid>
    <summary>Data request</summary>
    <DetectedDate>2012-01-11</DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Fixed</status>
    <project>Business Intelligence</project>
    <assignedTo>chris</assignedTo>
    <detectedBy>peter</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>728</Defectid>
    <testid>457</testid>
    <summary>Data request</summary>
    <DetectedDate>2012-01-11</DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Fixed</status>
    <project>Business Intelligence</project>
    <assignedTo>chris</assignedTo>
    <detectedBy>peter</detectedBy>
    <severity>3-Average</severity>
  </defects>
  <defects>
    <Defectid>728</Defectid>
    <testid>202</testid>
    <summary>Data request</summary>
    <DetectedDate>2012-01-11</DetectedDate>
    <priority>3-Normal Queue</priority>
    <status>Fixed</status>
    <project>Business Intelligence</project>
    <assignedTo>chris</assignedTo>
    <detectedBy>peter</detectedBy>
    <severity>3-Average</severity>
  </defects>
</NewDataSet>

And got as result

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
                    th, td {
                        border: solid black 1px ;
                        padding: 3px;                       
                        border-spacing:2px;
                        border-collapse: collapse;
                        width: 100px;
                    }
                    th {
                        font-family:verdana;
                        font-size:60%;
                        color:green;
                        align:center;
                        white-space: nowrap;
                    }

                     tr.testid111 {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:#0000FF;
                        align:center
                    }

                     tr.testid999 {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:#FF0000;
                        align:center
                    }

                     tr.testid321 {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:#00FFFF;
                        align:center
                    }

                     tr.testid457 {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:#FFFF00;
                        align:center
                    }

                     tr.testid202 {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:#347C2C;
                        align:center
                    }
                   </style>
    </head>
    <body>
        <table>
            <tr>
                <th>Defectid</th>
                <th>testid</th>
                <th>summary</th>
                <th>DetectedDate</th>
                <th>priority</th>
                <th>status</th>
                <th>project</th>
                <th>assignedTo</th>
                <th>detectedBy</th>
                <th>severity</th>
            </tr>
            <tr class="testid111">
                <td>56</td>
                <td>111</td>
                <td>Release of DIT </td>
                <td>2011-09-21 </td>
                <td>2-Give High Attention</td>
                <td>Ready to Test</td>
                <td>Business Intelligence</td>
                <td>peter</td>
                <td>john</td>
                <td>3-Average</td>
            </tr>
            <tr class="testid111">
                <td>829</td>
                <td>111</td>
                <td> Data request</td>
                <td>2012-01-12 </td>
                <td>3-Normal Queue</td>
                <td>Open</td>
                <td>web</td>
                <td>tcm</td>
                <td>john</td>
                <td>3-Average</td>
            </tr>
            <tr class="testid999">
                <td>728</td>
                <td>999</td>
                <td>Data request</td>
                <td>2012-01-11</td>
                <td>3-Normal Queue</td>
                <td>Fixed</td>
                <td>Business Intelligence</td>
                <td>chris</td>
                <td>peter</td>
                <td>3-Average</td>
            </tr>
            <tr class="testid321">
                <td>728</td>
                <td>321</td>
                <td>Data request</td>
                <td>2012-01-11</td>
                <td>3-Normal Queue</td>
                <td>Fixed</td>
                <td>Business Intelligence</td>
                <td>chris</td>
                <td>peter</td>
                <td>3-Average</td>
            </tr>
            <tr class="testid457">
                <td>728</td>
                <td>457</td>
                <td>Data request</td>
                <td>2012-01-11</td>
                <td>3-Normal Queue</td>
                <td>Fixed</td>
                <td>Business Intelligence</td>
                <td>chris</td>
                <td>peter</td>
                <td>3-Average</td>
            </tr>
            <tr class="testid202">
                <td>728</td>
                <td>202</td>
                <td>Data request</td>
                <td>2012-01-11</td>
                <td>3-Normal Queue</td>
                <td>Fixed</td>
                <td>Business Intelligence</td>
                <td>chris</td>
                <td>peter</td>
                <td>3-Average</td>
            </tr>
        </table>
    </body>
</html>

which in a browser looks as follows:

table view

ADDED variant using key

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:std="http://www.standardColors.com"
    exclude-result-prefixes="std">

    <xsl:output method="html"/>

    <xsl:variable name="colors">
        <color>#0000FF</color>
        <color>#FF0000</color>
        <color>#00FFFF</color>
        <color>#FFFF00</color>
        <color>#347C2C</color>
        <color>#800080</color>
        <color>#3B9C9C</color>
        <color>#A52A2A</color>
        <color>#3BB9FF</color>
        <color>#FF00FF</color>
        <color>#6698FF</color>
        <color>#808000</color>
        <color>#8D38C9</color>
        <color>#ADD8E6</color>
        <color>#F660AB</color>
        <color>#F87217</color>
        <color>#F9B7FF</color>
        <color>#FFA500</color>
        <color>#FFE87C</color>
        <color>#8E35EF</color>
    </xsl:variable>

    <!--<xsl:variable name="testIDs" select="distinct-values(//testid)"/>-->

    <xsl:key name="testidKey" match="testid" use="text()"/>

    <xsl:variable name="colorList">
        <xsl:for-each select="//testid">
            <xsl:if test="generate-id() = generate-id(key('testidKey', text())[1])">
                <xsl:variable name="pos" select="position() mod 20"/>
                <color>
                    <xsl:attribute name="testid"><xsl:value-of select="."/></xsl:attribute>
                    <xsl:value-of select="$colors/color[$pos]"/>
                </color>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>

    <xsl:template match="/">
        <html>
            <head>
                <style>
                    th, td {
                        border: solid black 1px ;
                        padding: 3px;                       
                        border-spacing:2px;
                        border-collapse: collapse;
                        width: 100px;
                    }
                    th {
                        font-family:verdana;
                        font-size:60%;
                        color:green;
                        align:center;
                        white-space: nowrap;
                    }
                    <xsl:for-each select="$colorList/color">
                     tr.testid<xsl:value-of select="@testid"/> {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        color:<xsl:value-of select="."/>;
                        align:center
                    }
                   </xsl:for-each>
                </style>
            </head>                
            <body>
                <table>
                    <tr>
                        <xsl:for-each select="/NewDataSet/defects[1]/*">
                            <th>
                                <xsl:value-of select="name(.)"/>
                            </th>
                        </xsl:for-each>
                    </tr>
                    <xsl:apply-templates select="*"/>
                </table>
            </body>
        </html>
   </xsl:template>

    <xsl:template match="/NewDataSet/defects">
        <tr>
            <xsl:attribute name="class">testid<xsl:value-of select="testid"/></xsl:attribute>
            <xsl:for-each select="*">
                <td>
                    <xsl:value-of select="."/>
                </td>
            </xsl:for-each>
        </tr>
    </xsl:template>

</xsl:stylesheet>

MSXML error prevention (and any other xsl engine used)

see convert RTF into node-set and RTF to node-set generic approach for further details.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:std="http://www.standardColors.com"
    xmlns:exslt="http://www.exslt.org/common"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="std">

    <xsl:output method="html"/>

    <std:colors>
        <color>#0000FF</color>
        <color>#FF0000</color>
        <color>#00FFFF</color>
        <color>#FFFF00</color>
        <color>#347C2C</color>
        <color>#800080</color>
        <color>#3B9C9C</color>
        <color>#A52A2A</color>
        <color>#3BB9FF</color>
        <color>#FF00FF</color>
        <color>#6698FF</color>
        <color>#808000</color>
        <color>#8D38C9</color>
        <color>#ADD8E6</color>
        <color>#F660AB</color>
        <color>#F87217</color>
        <color>#F9B7FF</color>
        <color>#FFA500</color>
        <color>#FFE87C</color>
        <color>#8E35EF</color>
    </std:colors>

    <xsl:variable name="colors" select="document('')/*/std:colors"/>

    <xsl:key name="testidKey" match="testid" use="text()"/>

    <xsl:variable name="std:colorList">
        <xsl:for-each select="//testid">
            <xsl:if test="generate-id() = generate-id(key('testidKey', text())[1])">
                <xsl:variable name="pos" select="position() mod 20"/>
                <xsl:element name="color">
                    <xsl:attribute name="testid"><xsl:value-of select="."/></xsl:attribute>
                    <xsl:value-of select="$colors/color[$pos + 1]"/>
                </xsl:element>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>

    <xsl:template match="/">
        <html>
            <head>
                <style>
                    table {
                        font-family:verdana;
                        font-size:60%;
                        font-weight:bold;
                        align:center;
                        white-space: nowrap;
                    }
                    th, td {
                        border: solid black 1px ;
                        padding: 3px;                       
                        border-spacing:2px;
                        border-collapse: collapse;
                        width: 100px;
                    }
                    th {
                        color:green;
                    }
                    <xsl:choose>
                        <xsl:when test="function-available('msxsl:node-set')">
                            <xsl:apply-templates select="msxsl:node-set($std:colorList)/color" mode="addTRclassToCSS"/>
                        </xsl:when>
                        <xsl:when test="function-available('exslt:node-set')">
                            <xsl:apply-templates select="exslt:node-set($std:colorList)/color" mode="addTRclassToCSS"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:variable name="colorList" select="$std:colorList"/>
                            <xsl:apply-templates select="$colorList" mode="addTRclassToCSS"/>
                        </xsl:otherwise>
                    </xsl:choose>

                </style>
            </head>                
            <body>
                <table>
                    <tr>
                        <xsl:for-each select="/NewDataSet/defects[1]/*">
                            <th>
                                <xsl:value-of select="name(.)"/>
                            </th>
                        </xsl:for-each>
                    </tr>
                    <xsl:apply-templates select="*"/>
                </table>
            </body>
        </html>
   </xsl:template>

    <xsl:template match="/NewDataSet/defects">
        <tr>
            <xsl:attribute name="class">testid<xsl:value-of select="testid"/></xsl:attribute>
            <xsl:for-each select="*">
                <td>
                    <xsl:value-of select="."/>
                </td>
            </xsl:for-each>
        </tr>
    </xsl:template>

    <xsl:template match="color" mode="addTRclassToCSS">
                    tr.testid<xsl:value-of select="@testid"/> {
                    color:<xsl:value-of select="."/>;
                    }
    </xsl:template>
</xsl:stylesheet>

Can this navigation be done completely in CSS

6 votes

I am a little stuck. I have created almost everything in the picture below. What I am stuck on is I am trying to figure out how I would set it up so that when a user clicks one of the links it makes the line below become red (after the next page loads). Obviously I would need to use Jquery to detect the page then add inline css, but what I am struggling with is I want this to be as easy as possible so that I can give this template to others and then they can add or remove items as necessary. I was trying to figure out if I could somehow use a li element to do this but I have not found a way yet. Does anyone have any ideas to help me?

enter image description here

Build your menu like this, in HTML:

<body id='Search' >
    <div id='menu'>
        <div class='bars'></div>
        <a href='/home/' title='Home'>Home</a>
        <a href='/community/' title='Community'>Community</a>
        <a href='/search/' title='Search'>Search</a>
        <a href='/contact/' title='Contact'>Contact</a>
        <div class='bars shift'></div>            
    </div>
</body>

Note that the body tag has a page-specific id (as Cody suggests). Also note that this id must be the same as the value of the title attribute for the menu link.

Then use this CSS:

.bars {border-top:1px solid #CCC;border-bottom:1px solid #CCC;height:5px;}
.shift {margin-top:-6px;}
#menu {font-family:arial;font-size:12pt;text-align:center;}    
#menu a {display:inline-block;padding:7px;text-decoration:none;color:#000;}
.active {border-bottom:5px solid red;}

Finally, add this jQuery to each page:

$(document).ready(function(){
    var id = $('body').attr('id');
    $('#menu a').each(function () {
        var title = $(this).attr('title');
        $(this).removeClass('active');
        if (title == id) $(this).addClass('active');
    });
});

You can see a live fiddle demo here. (To test, just change the id of the body element and press run.)

EDIT: The benefits of this method compared to Cody Grays' method is that you don't need to modify the css every time you change the HTML when you add, remove or edit a menu item. On the other hand it uses jQuery. However, if you want a pure css solution, just remove the jQuery, and the id of the body element, and instead directly apply the .active class to the particular link, depending on the particular page (similar to jackJoe's suggestion).

This can easily be modified if you must use <li> elements.