One of the most common things you’ll see on any website is a navigation bar that has a different set of CSS styles applied to the link that represents the current page the user is on. (Maybe I’ll actually get around to doing this on my own site!) There are a few ways you can do this with HTML and CSS, which I’ll outline here.
Using a Unique Link Class
Probably the most common and easiest way to do this is by simply applying a different class with appropriate styles on the current page link. So in your HTML you would see something like this:
<ul class="nav"> <li><a href="index.html">Home</a></li> <li><a href="about.html">About</a></li> <li><a href="services.html">Services</a></li> <li><a href="products.html" class="current">Products</a></li> <li><a href="contact.html">Contact</a></li> </ul>
The CSS would then require something like the following:
a:link, a:visited { color: blue; } a.current:link, a.current:visited { color: white; background-color: blue; }
Now all links with a class of “current” will have white text on a blue background, while all other links will have just blue text.
The only thing you have to make sure of is that the location of the class gets changed depending on the page you’re on. For example, the HTML shown above would appear on the “Products” page, but on the “Contact” page the “current” class would be moved to the “Contact” link.
Adding a Class to the <body>
This next method is a lot messier, but is an option if you don’t mind more HTML. You can add a unique class to the <body>
tag and then have a different class for each link. The body class would change depending on what page the user was viewing. So on the “About” page, your <body>
tag would look like this:
<body class="about">
The HTML for your links would look like this:
<ul class="nav"> <li><a href="index.html" class="home">Home</a></li> <li><a href="about.html" class="about">About</a></li> <li><a href="services.html" class="services">Services</a></li> <li><a href="products.html" class="products">Products</a></li> <li><a href="contact.html" class="contact">Contact</a></li> </ul>
Then in your CSS you would have the following:
a:link, a:visited { color: blue; } body.home a.home:link, body.about a.about:link, body.services a.services:link, body.products a.services:link, body.contact a.contact:link { color: white; background-color: blue; }
This includes a separate selector for each nav item. So although the different unique link classes will appear in the HTML on every page, the unique “current page” styles will only take effect on the page that has the matching <body>
class.
Final Notes
A few things can be noted about the technique outlined here:
- If you are using PHP (or some other back-end language), you can generate the classes dynamically based on the current page
- Although I’m applying the unique classes to the link elements, you can use the
<li>
elements if you want - I’ve seen people use a class of “active” instead of the class of “current” that I’m using here; I think “current” (or something else other than “active”) is better because CSS already has a pseudo-class called
:active
that means something completely different, so that might be confusing for beginners - I suppose you could use the
:nth-child()
pseudo-class to target the current link by number in the list, but that seems a little convoluted and not very convenient or maintainable - If you want to do this on a WordPress site, this article covers that topic
nice article. thanks for writing this up. you could also make use of CSS attribute Selectors like this…
i’d be a little wary of using this on a really large app for fear of collisions with other links on the page with the same href. to mitigate, i’d more thoroughly qualify my selector by including the nav class like this…
surprisingly, this stuff is compatible down to IE7. Chris Coyier has a really good run down here – http://css-tricks.com/attribute-selectors/
cheers.
@Mundi I definitely agree with you here.
Why?
– Adding another unique class to each of the navigation links is superfluous, and hard to manage especially with dynamic content.
– like you said, attribute selectors are supported in IE7+ (That’s plenty browser support for me)!
This is how I would do the selector block:
…Or you could use it on the
<html>
element:The reasons for using it on the
<html>
element would be the same reasons why IE conditional comments are put around the<html>
element instead of the<body>
element in Paul Irish’s browser-specific CSS solution:http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/
I agree that the
html
element is more appropriate thanbody
element, but for this reason: The tagging applies to the whole page, hence the root element should carry that tag. (Keep in mind that at some point you might want to display content of thehead
element which is outside thebody
element.)And for the tagging, an ID is appropriate, not a class. You want to identify, not classify a page of your website. (Classes might be used for groups of pages, eg. product overwiew and product details pages belonging to a class “shop”, various checkout step pages belonging to a class “checkout”:
<html id="product-overview" class="shop">
and
<html id="product-details" class="shop">
and
<html id="submit-order" class="checkout">
respectively. Both ID and class can be used for styling.)
My understanding as to why class was used instead of id is because it allows for greater specificity when cascading. Class is given higher precedence than id, but there are other ways to attain specificity also. I agree that classes should be used to classify multiple elements and id is used to identify a specific element.
Joel, I think you have it backwards. IDs are more specific than classes. That’s why OOCSS discourages the use of IDs, because they’re too specific, and cause specificity wars.
I wrote about this here:
http://www.impressivewebs.com/css-specificity-irrelevant/
I would be more comfortable using HTML data attributes than href attributes.
[data-current] { }
Please give a complete example.
I find no information about this [data-current]
Thank you
See:
https://www.sitepoint.com/use-html5-data-attributes/
You can also do this easily on the client side with jquery, or if desired vanilla javascript.Kevin Leary has a nice jQuery tutorial- http://www.kevinleary.net/highlighting-the-current-page-with-php-jquery/ .
You could argue that you shouldn’t be doing this on the client side, but it might be easier if you can’t access the server side code and you don’t want to add classes by hand for each page.
My method of choice is to replace the “current page” link with some other element. That used to be <strong> until the meaning changed in HTML5 – I now use <em> to emphasize “you are here.” You could also use the neutral <b> element.
You don’t need PHP to automate this – I have used good old Server-Side Includes to do it.
I agree that “current” is a better class name than “active”. However, instead of a class you could use the
@rel
attribute<a rel="self">
in the markup and the attribute selectora[rel="self"]
in the stylesheet.But that should not be necessary. “Never have a link that points to the current page,” says Jakob Nielsen.
Following this advice, you’ll end up with markup like
Then you can style the menu item (not link) for the current page using a selector like
nav li
and overwrite the styles for the other menu items usingnav a
(ornav li a
).Or you keep the
a
element for the current page, but without a@href
attribute:This allows to discriminate the menu item for the current page from the others using selectors like
nav a
vs.nav a[href]
.Perfect, cheers!
Thanks for writing the blog post.
I realised it’s an older post but your taking the time to share your ideas helped.
what if i am inside the dreamweaver template? I can only edit in template pages but not in child pages. So, i cannot add class in each child pages?
It wont work with site layout or master page
10/04/2017
Hello,
I tried this and it didn’t work. What am I doing wrong please?
Thank you.
body.PageDesign a.PageDesign:link,
body.PageProduction a.PageProduction:link,
body.PageWeb a.PageWeb:link,
body.PageLogoDesign a.PageLogoDesign:link,
body.PageEndorsements a.PageEndorsements:link,
body.PageResume a.PageResume:link,
{
font-weight: bold;
}