In this article, I want to introduce you to a really powerful CSS3 pseudo selector called :target. Much like :hover, :target is invoked during certain interactions with the website. Specifically, when applied to a fragment identifier. On a page such as http://example.com/index.html#hello-world, the id=”hello-world” element is the target and any matching :target styles would be applied.
I am going to demonstrate two examples of when and how :target can be used. Hopefully, this introduction will get you thinking about some of simple ways :target can add benefit your customers.
Tabs in CSS
A well structured document is one that makes sense in the ordering of sections and topics. It works well when there is no CSS and no JavaScript. Tabbed systems make use of some sort of display tab which shows the current section, and in doing so hides the other sections. We’ve all seen a tabbed system before, and probably plenty of poor implementations as well. Sometimes when you click the tab, it calls a JavaScript function to populate the area below the tab. The downside is that when there is no JavaScript the data does not appear.
The ideal way to build a tab system is to have all your data in the HTML, then use JavaScript to hide the other tab panes and build the tabs themselves dynamically. That way if there is no JavaScript, it just defaults to a linear set of text blocks. This is progressive enhancement; build for the lowest common denominator and add more functionality and styling as you go — no one is left behind, not even googlebot.
Instead of using JavaScript to do this show/hide, it is possible to use CSS3 using the :target selector. Before you get too excited, it must be said that the :target selector is not supported in IE6 or IE7, so the practical uses for this are pretty slim. Instead this can be used for user chrome type objects which don’t effect functionality, but improve usability. You can add the :target info today, and when browsers implementations catch-up they get the bells and whistles auto-magically. It is important to not use :target for mission critical things, but there are plenty of other possibilities. As an example, I will show you how make a simple tab system based on Daniel Glazman’s example.
First we should create the basic un-styled HTML.
Topic 1
This is the text for topic 1. Hello World!
Topic 2
Different text for topic 2. Ah, foobar.
Without CSS or JavaScript this text is completely accessible and reads normally, it just makes the page longer. Tabs are a way to compact the information into a smaller space, so lets proceed to do this.
If we add some simple styles to the page, we can get the two headings to appear and act like tabs through positioning. The interesting part is the :target selector.
// set the default state first
p {
display: none;
}
// When the link is clicked, set the contents to display
p:target {
display: block;
}
When the fragment (#content1) is not part of the URL, the :target selector does not match the
element, so it is set the default view of display: none. This is a very simple way to create a tabbed system. You can view a working example and see for yourself.
The Yellow Fade Technique
There is a popular usability feature called the “Yellow Fade Technique”. This is used to direct the user’s attention back to a specific area subtly. For example, when you want to edit a piece of a page you may click edit which takes to a new page with form fields. When you press save you are returned to the original page where there is a brief yellow fade of the area that was just edited. It brings your eye to the area, possibly to confirm the changes look correctly in the template, or to just make people aware the change took place at all. Either way, it seems to be a welcomed usability feature that has been picked-up by several web applications.
Normally, this is accomplished through the use of JavaScript and page IDs or classes. The JavaScript runs an onload function looking for those classes or ID and once the parts of the page have been identified, the script runs a timer and ever few microseconds change the background color from pure yellow to white. This create a smooth, not too annoying, yellow fade effect.
The downside to all this is that there are several resources at work, including onload functions (which might be happening every time the page loads, not just the times when a form is submitted) and hooks into the classes and IDs and JavaScript timers. All this adds to the client download and subtracts from the speed of the page.
With CSS3 there is a much easier and simpler solution. Using the :target pseudo class it is possible to emulate the yellow fade without a single line of JavaScript.
First, you need to create (or download) a tiny 1 pixel-wide yellow animated gif. This will fade from yellow to white. The animated gif isn’t repeating, so it will fade once and then stay pure white. This also defines the length of the fade, so there is no need to for a JavaScript timer.
Second, we need to set this as the background image for the area which has been changed. To do this, we use the CSS3 :target pseudo selector.
#here:target {
background-image: url('yellow-fade.gif');
}
This will fade the element with an id=”here”, the URL would look like http://example.com/#here. It is good web architecture to use fragment identifiers for each of your headings and to use RESTful URLs.
Now, the downside to that CSS statement is that it will only fade the area with the ID.
Hello World
I am saying Hello to everyone in the World!
Only the heading element would get the yellow fade. So how do we fix this? Well, we could change the ID to a class and create something like:
.here:target {
background-image: url('yellow-fade.gif');
}
But then on the server, we’d have to add classes dynamically to all our elements.
Hello World
I am saying Hello to everyone in the World!
We could put a wrapper around both the heading and the paragraph.
Hello World
I am saying Hello to everyone in the World!
But that seems too much work. Instead, we can make use of another CSS combinator, the adjacent sibling selector:
#here:target, #here:target p {
background-image: url('yellow-fade.gif');
}
This targets both the heading with the ID ‘here’ and the first sibling paragraph. So both will get the background image and the subsequent fade. You can easily change your CSS to fit your HTML design, but this is a quick and simple alternative to the Yellow Fade technique in JavaScript used on so many sites.
In CSS there is also a wildcard * to stand for all nodes. So you could further take the example to
#here:target, #here:target * {
background-image: url('yellow-fade.gif');
}
This would match the first sibling of #here no matter what the type of element it might be. Firefox correctly supports this, but as of writing, Safari does not.
You can see an example of this in action and view the source to see how it all works.
Blurring the lines between behaviour and presentation
I am obligated by the behaviorists to mention that there is a debate over presentation and behavior, where does one stop and the other start? By adding the :target selector into your CSS, you are styling the HTML based on the behavior of the browser and the users. We talk about the “holy trinity” of web design, and we have spent the last few years campaigning to divide data, presentation and behavior into their respective HTML, CSS and JavaScript camps. The :target, as well as the :hover, selectors blur that line between presentation and behavior. Depending on how comfortable or how much of a purist you are, you may or may not agree with what has been demonstrated.
These examples were written to better understand the CSS3 :target element and to explore those blurry grey-areas. Hopefully, a discussion will emerge with even more ideas, caveats and problems that were not originally thought of. Together we can create some best practices on when to best use CSS behavior and JavaScript presentation.
Conclusion
Over a year ago, Andy Budd demonstrated the yellow-fade technique with :target and I was impressed! (http://www.andybudd.com/presentations/css3/) In the time in between, I have seen very little attention or articles on this little known selector. As I was started working on this article, I found several examples some from as early as January 2003 that talk about uses for the :target selector. The reason for not getting the traction it deserves could be the lack of information about when and how to use it correctly or documentation on the poor CSS3 implementations in browsers.
CSS3 is closer than you think, many of the selectors and attributes are available in several major browsers today. They can be used with progressive enhancement to add more style to your design at little cost, when other browsers catch-up they get the benefits of your progressive code for free. The CSS3 :target selector is just one example of some of the new selectors arriving that can be taken advantage of in interesting new ways.




I have found the scriptaculous Effect.Highlight much more versatile for the ‘yellow fade technique’. No pixel-gif required (those remind me of the 90s too much), the colors are customizable and it it just a tiny call to a JS library that’s already loaded.
Effect.Highlight is fine, but as Brian mentioned quite a few times, what if the user does not have javascript enabled? the yellow fade technique will still work, you could maybe code it so that it uses Effect.Highlight if javascript is present and falls back to CSS if not.
Great post. I think I’ll be playing with this at some stage. One interesting thing I noticed is that due to the changing of the url it keeps back button behaviour intact in the browser. Now I’m not overly sure if this is the right thing to do, but it’s certainly interesting (click on the examples a few times and it takes a lot more back clicks than I’m used to to get to the article for example…).
[…] There’s a good article online at Vitamin, Stay On :Target, about the CSS3 :target pseudo selector, which provides a good explanation and some working examples. :target is supported by all current browsers, except - well, I don’t need to say it, do I? - so you can start using it straight away. […]
MooTools also an Effects helper that allows to highlight an element with s simple el.highlight(color).
But this yellow fade technique is a great unobtrusive solution that applies without one line js, applying events or applying an effect to multiple elements. Nice work.
This is great. An easy way to have tabs that instantly switch with no extra page loading, and that still makes each tab have its own URL.
Simply dropping IE support, or at least partially, is so tempting (not for commercial sites, obviously).
[…] Stay on :target […]
Better article on by Bruce Lawson http://dev.opera.com/articles/view/improving-the-usability-of-within-page-l/ on different using :target to highlight inpage links.
The yellow fade only seems to work the first time (Safari on Leopard).
I guess this is because the second time I click on a link the animation has already played out, and so I simply see the image in its finished, white, state.
Another great article about good CSS techniques, and another one making me sigh how the world could look like. Well, you can do things much simplier and cleaner way saving your time, and users time, but… When it comes to bussiness, you have to assume over 60% of users use… I don’t need to say… :) And you have to do it the quirksmode-way… First - tabbed system. Done this way - it’s totally inaccessible by that 60% of (l)users. And our goal is to make our work accessible to all. I personally make sites which looks uglier in… you know… but sill usable. The second technique is still usefull. That’s the spirit :) When you use normal browser - you’ll see all.
BTW, the pictures are (possibly the best) way to make lots of presentation effect possible in every browser capable of displaying graphics. I’ve realised that when I “wasted” a lot of time making cool hover effect buttons with pure CSS, and of course it worked only in real browsers. 5 minutes more with GIMP (or PS), a few pixel more to size and we have the same working everywhere… What’s important - done in much cleaner and simplier way
“The reason for not getting the traction it deserves could be the lack of information about when and how to use it correctly or documentation on the poor CSS3 implementations in browsers.”
I think in this case it’s browser support. Your examples don’t work in Opera 9.25 and the last one works incompletely in Safari which only leaves Firefox with full support. Opera & Safari certainly aren’t shoddy in their implementations of other parts of CSS3 so I’d say until those two come fully on board, it’s take-up will be small.
[…] So che il titolo del post non è molto invitante ma volevo solo segnalare questo articolo su :target. […]
I like the idea of target but I just dont think CSS3 will happen any time soon!
I have read your css3 :target article and have put the html in a file called markup.html and put the css in a file called main.css, have put a link rel etc to link the files but from what you describe in the article when clicking on a h2 link the content for that section should not be displayed but for some reason its not working for me…….. I’m using Mozilla Firefox 2.0.0.4,I’ve just noticed that its automatically downloading 2.0.0.11 so will try it in this newer version. Am I doing something wrong?
Interesting article - probably the first decent discussion about the possibilities of the new CSS3 psuedoclasses I have seen. To me the yellow fade effect seems more like a satisfactory fallback from Scriptaculous for a user with no JS than an actual robust solution to provide a fade to an area just updated - using gifs for this makes me shudder.
[…] CSS3 ile birlikte gelen sözde seçicisi :target hakkında güzel bir makale. Bağlantı […]
Feeling free to add (again) that the :target pseudo-class will indeed bring many benefits – but also specific problems. (A former German article might show some other use cases.)
I wonder how long it will take before CSS3 really takes off.
[…] Brian Suda gives examples of how to use the target pseudo selector. It will be quite some time before this will work cross-browser. Roll on IE8. […]
Great article Brian. I’ve been using the target pseudo selector for years, to similar effect. The only draw back has been the straggler browsers.
I’m not a purist in the sense you describe and I think it’s always good practice to use your tools to the fullest. If you can do something with CSS, why bing in something else?
I think it’s also important to consider that CSS is very much about the user’s behavior. We use CSS to style our interfaces. Often, this styling is to match a design. The design, at best, aims to influence user behavior. That, is so ingrained in every aspect of what we do.
[…] I can’t wait for CSS3 […]
[…] Stay on :target […]
[…] Brian Suda’s STAY ON: TARGET introduces the CSS 3 :target selector. […]
[…] Suda Brian, (2008), Stay On :Target on Vitamin. Accessed on Feb 11, 2008 […]
[…] Vitamin Features » Stay on :target (tags: css css3 tutorial target tabs) […]
[…] Vitamin Features » Stay on :target Nice CSS3 Article on Vitamin. Bookmarked for 2027 (tags: css3 css vitamin webdesign article design) […]
[…] div#box will have a pink background where div#box is a target of a fragment identifier (that is, in a url such as http://www.url.org/index.html#box). Mozilla and Safari users can use this pseudo class straight away. As usual IE6/IE7 users can go to hell. See this article for a useful explanation. […]
[…] Read: Stay On:target […]
[…] Stay on :target […]
[…] Stay on :target […]
Great article Brian!
One thing I particularly like about :target is that it provides a standards based method to apply styling when a page loads and not just in response to a click within a page. For example, if you had a small image gallery page; all images might easily fit on a typical screen resolution, but you want to highlight a particular image.
Anyway, inspired by this article, and with just such a requirement, I wrote some support JavaScript to provide :target like functionality to older browsers.
[…] 14.Stay on :target with CSS3 […]
[…] 14.Stay on :target with CSS3 […]