say something

:focus and :not

This an old entry that I am resurrecting since I am sure many of us need a reminder of these two useful CSS classes.

:focus

We are all familiar with the pseudo classes :link, :active, :visited, and :hover that can effect the properties of links on our pages, but while going through some geek reading over at the W3C CSS-3 recommendations I found a pseudo class called :focus. From the W3C site:

The :focus pseudo-class applies while an element has the focus (accepts keyboard or mouse events, or other forms of input).

So :focus would not be helpful when used with links, but it can be very useful on form inputs. When clicking on a textbox you can change the property of that textbox. For example, click on the textbox and the background color should change to a light gray.



This can be very useful for all forms because it gives the user an idea of where they are on the form. If they decide to leave they can easily come back and continue filling out the form. If your users like to TAB through their forms they no longer have to guess where the next TAB is going to take them, they will see it right before their eyes without searching for the cursor. The CSS used to implement this is:


input:focus, textarea:focus { background-color: #eee; }

:not

First I got this idea from reading Andy Budd’s entry on CSS attribute selectors and also Jason’s beautiful blog where he places external images to links that go outside of his site. I wanted to have images on my links to tell readers which links go outside of my site because I have lot of links that reference both external and internal material and it could be helpful to differentiate between the two. Jason uses classes in his links to depict which ones are external. Being the lazy person I am I knew there would be more than a couple of times that I would forget to use the class within the link. I then saw Andy’s blog and read a comment (first one) showing how you can add images to links that are pdf’s (another useful feature). I could easily do this with links on my site. The problem occurs when I want to differentiate between external and internal. I could easily show the internal links through:


a[href*="9rules"] {
padding-right: 12px;
background: transparent url(”images/aoutside.gif”) center right no-repeat;
white-space: nowrap;
}

This places the image on all links that contain “9rules” in their href. That is obviously what I did not want to do. I needed a “not equals” function in CSS. Well there is one, it just took me a while to find it. Here is the code.


a:not[href*="9rules"] {
padding-right: 12px;
background: transparent url(”images/aoutside.gif”) center right no-repeat;
white-space: nowrap;
}

An alternative that does not place any space between the image and link:


a:not([href*="9rules"])::after {
content: url(”images/aoutside.gif”);
}

Now I am getting the desired effect. Users who read my link heavy entries will know just by looking at the link whether it is external or internal. The possibilites of this are endless. You can have different colors, sizes, decorations or anything else you could think of in one stylesheet.

19 people says things!

  1. “So :focus would not be helpful when used with links”

    Not true, links get focus as well keyboard events. If you tab through links on a site, you do not get :hover effects because you havn’t hovered over the links. However you can style these links with :hover and you get the same benefits you describe with tabbing through form elements. The common LVHA (LoVe HA!) rule for link psuedo-class ordering has been commonly replaced with LVFHA (Lord Vader’s Former Handle Anakin).

    By Chris Griego on May 18, 2005 12:41 am

  2. Interesting, thanks for the heads up Chris.

    By Scrivs on May 18, 2005 12:48 am

  3. As Chris (comment 1) says, you can use the :focus for links, in good browsers. This is an invaluable help for keyboard users. Sadly, not so unusual, that feature doesn’t work in that browser-with-way-to-much-market share. However, it can be simulated: that particular browser has a broken a:active implementation. I f you sue the same style for your a:fous and a:active, users of ‘that’ browser will enjoy it as well
    a:focus, a:active { /* style here */}

    By Philippe on May 18, 2005 2:14 am

  4. Great tip espcially “:not”. Will have to start using that.

    By Scott Mackenzie on May 18, 2005 3:27 am

  5. I’m guessing LVFHA is (Link, Visited, Focus, Hover,
    Active). I’ve never seen the logic behind this order. Can anybody fill me in there.

    Do :not and ::after function in IE and IE/mac? They are new to me but seem very helpful

    By Keith Free Ellis on May 18, 2005 9:26 am

  6. “Do :not and ::after function in IE and IE/mac? They are new to me but seem very helpful”

    I know they don’t work in IE/Win, and I’m pretty sure they do not work in IE/Mac. IE/Mac has complete CSS1 support, but beyond that it’s still pretty iffy.

    By Vinnie Garcia on May 18, 2005 9:47 am

  7. PS: Scrivs, your :not example won’t work too well under a relative linking structure. A link to /archives/whatever.html won’t have 9rules in the href so it would get the “external” badging.

    By Vinnie Garcia on May 18, 2005 9:48 am

  8. Good call Vinnie, will have to update entry with that information.

    By Scrivs on May 18, 2005 9:54 am

  9. I’m finding some inconsistent functionality of :focus with fields. If I tab to them, the bg color does not show up. If I mouse-click to it, it does.

    Any thoughts?

    By Danny on May 18, 2005 10:18 am

  10. D’oh, I got me some brackets stripped.

    What that used to say was that the :focus does not seem to work with input fields of type=password, when you tab to them. If you mouse-click to them, the colors shows up fine. But not if you tab.

    I was wondering if anyone knows of a fix. Thanks.

    By Danny on May 18, 2005 11:29 am

  11. I can’t say that I know of any fixes right off the bat since I haven’t played with this in a while, so hopefully someone can shed some light on the issue.

    By Scrivs on May 18, 2005 11:34 am

  12. This is great… Do you know of any Javascript fixes to make :not work in IE?

    By Andrew Maddox on May 18, 2005 11:35 am

  13. Well, for the record, while Safari 1.3 is reported to not support bg colors on form fields at all, Safari 2.0 (w/Tiger) seems to support bg colors on some fields but not others (e.g. not password fields).

    In other words, when I tested it on Firefox it worked fine.

    Thanks!

    By Danny on May 18, 2005 2:08 pm

  14. CSS attribute selectors don’t work in IE. So your readers using IE (poor souls) will not see your images.

    By Matt on May 18, 2005 2:09 pm

  15. Andrew,
    I have been writing about similar stuff on several occasions.

    I guess it would be something like:

    onload = function() {
    var links = document.getElementsByTagName(’a');
    for (var i = 0; i < links.length; i++) {
    if (links[i].href.indexOf(enter_your_domain_here) == -1) {
    links[i].className += links[i].className ? ‘ external’ : ‘external’;
    }
    }
    }

    …and style it however you want to with CSS:

    a.external { … }

    By Marko on May 18, 2005 2:41 pm

  16. Oh, that was a little bit sloppy, here it is:

    function external_links() {
    if (!document.getElementsByTagName) return;
    var links = document.getElementsByTagName(’a');
    for (var i = 0; i < links.length; i++) {
    if (links[i].href.indexOf(enter_your_domain_here) == -1) {
    links[i].className += links[i].className ? ‘ external’ : ‘external’;
    }
    }
    }
    window.onload = function() {
    /* place here the rest of your onload
    functions, if you have any */
    external_links();
    }

    By Marko on May 18, 2005 2:47 pm

  17. As noted by Vinnie above, looking for your-domain-name in the href of links only works if you specify the whole URL in your <a href=> tags in the first place. That’s rather a waste of bandwidth in most situations, and most sites I see (my own included) either use relative URLs: “somepage.htm” or URLs relative to the document root: “/somedir/somepage.htm”.

    If all your internal links are like that, you can identify external links really easily by looking for a “http”:

    a[href*="http://"] { … external link rules here … }

    Which isn’t to say that :not isn’t gonna be useful somewhere, but it’s the wrong tool here.

    By Chris Hunt on May 19, 2005 9:07 am

  18. I’m guessing LVFHA is (Link, Visited, Focus, Hover,
    Active). I’ve never seen the logic behind this order. Can anybody fill me in there.

    The reason is that, rather unintuitively, :hover, :visited, etc all have the same specificity. This means that, all other things being equal, the rule that appears last in the stylesheet takes precedence.

    Therefore the following would do the wrong thing:

    :hover { color: red; }
    :visited { color: green; }

    …since the :visited rule takes precedence over the :hover rule.

    By Jim Dabell on May 19, 2005 12:08 pm

  19. Unforunly, focus is not woking in IE.

    I used like this in my site:

    a:focus {color:green;}

    in FF is working, but in IE not.

    vic@ Web Hosting Link exchange

    By Link Exchange on December 1, 2005 7:02 am

  20. Subscribe to comments via RSS!