views:

793

answers:

2

I have some mark up and I am trying to have the "hints for some input" light up when the accosicated text input has focus. I am trying to use the focus pseudo class along with a sibling selector. If i just use one or the other it works just fine. However, when combining them in IE8 it apears as if that style doesn't get updated when you tab through the textboxes. NOTE: that if you click away from the textbox and back they style is updated.

Here is the markup:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        html { font-family: Arial; }
        .lineItem {padding:5px; clear:both; }
     .label { display:block; font-size:large; color: #2C2F36; font-weight:bold; padding:5px 0px 3px 0px; }
     .textbox:focus { background-color: #FFFFBF; }  
     .textbox { font-size: large; color: #2C2F36; width:300px; background-color: #FFFFE8; padding:3px 5px; border:solid 2px #cecece; float:left; }
     .hint {  margin-left:10px; width:175px; font-size:smaller; display:block; float:left; color: #466E62; }
     .textbox:focus+.hint {color: Red; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <div class="lineItem">
      <label for="ListName" class="label">List Name</label>
      <input id="Name" name="ListName" type="text" class="textbox" />
      <span class="hint" id="NameHint">This is the title of your List.</span>
     </div>
     <div class="lineItem">
      <label for="ListSlug" class="label">http://List/Username/&lt;/label&gt;
      <input id="Slug" name="ListSlug" type="text" class="textbox" />
      <span class="hint" id="SlugHint">The URL that you will use to share your list with others.</span>
     </div>
    </div>
    </form>
</body>
</html>

Here is a screenshot of what I'm seeing:


Screenshot

NOTE: Works in other browsers :( and other pseudo classes such as hover work

+4  A: 

According to http://www.quirksmode.org/css/contents.html Adjacent Sibling Selectors are not correctly supported by IE browsers, and based on that I am afraid I must say - sorry, you cannot achive what you want using CSS only.

But you can use jQuery, and this is how you can do it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        html { font-family: Arial; }
        .lineItem {padding:5px; clear:both; }
        .label { display:block; font-size:large; color: #2C2F36; font-weight:bold; padding:5px 0px 3px 0px; }
        /* .textbox:focus { background-color: #FFFFBF; } */
        .textbox { font-size: large; color: #2C2F36; width:300px; background-color: #FFFFE8; padding:3px 5px; border:solid 2px #cecece; float:left; }
        .hint {  margin-left:10px; width:175px; font-size:smaller; display:block; float:left; color: #466E62; }
        /* .textbox:focus + .hint {color: Red; } */
        .hintOn { color:Red; }
        .textboxOn { background-color: #FFFFBF; }
    </style>
    <script type="text/javascript" src="http://ajax.Microsoft.com/ajax/jQuery/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript">
        var Hints = {
            Swap: function(obj) {
                $(obj).parent().find('.hint').toggleClass("hintOn");
                $(obj).toggleClass("textboxOn");
            },
            Init: function() {
                $(function() {
                    $('.textbox').focus(function() {
                        Hints.Swap(this);
                    }).blur(function() {
                        Hints.Swap(this);
                    });
                });
            }
        };
        Hints.Init();
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div class="lineItem">
                <label for="ListName" class="label">List Name</label>
                <input id="Name" name="ListName" type="text" class="textbox" />
                <span class="hint" id="NameHint">This is the title of your List.</span>
        </div>
        <div class="lineItem">
                <label for="ListSlug" class="label">http://List/Username/&lt;/label&gt;
                <input id="Slug" name="ListSlug" type="text" class="textbox" />
                <span class="hint" id="SlugHint">The URL that you will use to share your list with others.</span>
        </div>
    </div>
    </form>
</body>
</html>

In my solution I included reference to Microsoft hosted jQuery, and wrote simple method to apply styles you need. You can easily modify "highlighted" state of hint and input box by amending your CSS classes.

I have tested my solution on IE6, IE7, IE8, Firefox, Opera, Chrome and Safari and it is working correctly.

rochal
+1 for your detailed explanation and testing
Seb
+1  A: 

I did some research and did some testings. It seemed that the problem is that IE8 won't update the status unless the element is specifically blurred before the next element gains the focus. I tested a targeted IE8 fix, but it does require javascript. It is up to you if the trade off is worth it:

CSS:

/* Add a 'normal' selector for IE8, leave sibling selector for other browsers */
.lineItem.focus .hint, 
.textbox:focus + .hint {color: Red;}

JS:

<!--[if IE 8]>
<script type="text/javascript" charset="utf-8">
    var els = document.getElementsByTagName('input');
    for(var i = 0; i < els.length; i++){
        var el = els[i];
        if(!/textbox/.test(el.className)) continue;
        el.attachEvent('onblur', function(){
            event.srcElement.parentNode.className = event.srcElement.parentNode.className.replace(' focus','');
        });
        el.attachEvent('onfocus', function(){
            event.srcElement.parentNode.className += ' focus';
        });
    };
</script>
<![endif]-->

Insert this script before the closing body tag, or after the last input.textbox element. It will look through the tags, only ones containing a class of textbox will be processed. It simply adds a class to the parent element, and removes the class when the input element has blurred. By using a standard parent/child selector, we force IE8 to do what is desired.

Doug Neiner