Dynamically Highlighting Page Sections - CSS3

You’ve now seen two examples of how CSS3’s structural pseudoclasses can add visual enhancements to your pages while keeping your code free of classes and IDs, and without using JavaScript. Other CSS3 pseudo-classes can also add much more dynamic-looking effects to your pages, such as highlighting the current section when you use a within-page link to jump down the page. This is not only a visual enhancement, but a usability one, as it helps orient the viewer to where they are in the page.

For instance, when you click on a citation number in a Wikipedia article, the page jumps down to that note at the end of the page. Wikipedia highlights the note you clicked on so you don’t have to locate it among the potentially hundreds of other notes.

Wikipedia uses the :target pseudo-class to highlight the selected footnote in blue.

Wikipedia uses the :target pseudo-class to highlight the selected footnote in blue.
This is especially helpful in orienting the viewer when the selected item is too close to the bottom of the page to be brought all the way up to the top of the browser window.

You can highlight the selected footnote, heading, or section on a page with JavaScript. But it’s so much more efficient—both in terms of your development time and in terms of page loading speeds—to do it with the CSS3 :target pseudo-class.

The :target Pseudo-class
Some URLs have fragment identifiers, represented by an octothorp (the character #, commonly called a pound sign, number sign, or hash mark) followed by an anchor name or element ID, to link to a certain element in the page. Figure below is an example of this type of URL. The :target pseudo-class selects the element being linked to, and lets you style it.

On Wikipedia, when you click a footnote number, the li element for the footnote you’re taken to becomes the target. Here’s how Wikipedia styles those footnote targets:

We can also use the :target pseudo-class for a similar effect in our article page

Adding the Table of Contents
Right now, the article page doesn’t have any fragment identifiers we can link to. Let’s add IDs to all of the subheads in the page, since they naturally divide it up into sections.
If you’ve been working along with the rotate_start.html file, you can continue making changes to it now, or you can open the file target_start.html from the exercise files for this chapter; both should be the same. In your page, add id attributes to each h2 element, starting with the “Derbyshire” one, with the values shown:

Now add a table of contents to the top of the page that will link to each of these h2 elements. Add the following list right before the “Itinerary” h2 element:

Save the page, and view it in a browser. Thelinks in the table of contents should take you down to the corresponding subheading in the page. We haven’t yet given any special styles to the targeted or current subheading, but before we do that, let’s style the table of contents itself.

The table of contents list already has some non-standard styling because of the existing rules for ul and a elements; the links are all on one line and spaced out from each other . Let’s enhance the styles further.

The table of contents before any special styling is applied

The table of contents before any special styling is applied

Add a background image of a hand-drawn arrow to the list:

Next, get rid of the left padding on the li and a elements and use right padding instead, so the list as a whole is aligned on the left side:

This is also a good opportunity to use another CSS3 pseudo-class. The :last-child pseudo-class lets you apply unique styles to the last child of a parent element. Here, we can use it to remove the right padding from the last list item:

Removing this right padding decreases the amount of space the last list item takes up, reducing the chance that it will drop down onto a second line before it really needs to. The :last-child pseudo-class is very handy for removing padding, margins, borders, or other styles from the last item in a list, div, or table row.

Figure below shows the results of our styles thus far. The list looks better, but is still quite plain. How about we add a little icon or number in front of each item in the list?

The table of contents now has a background image and better spacing between links.

The table of contents now has a background image and better spacing between links.

To create numbers in front of the list items, we could use an ordered list (ol element) instead of an unordered list (ul element). But there’s no way to directly style the list marker numbers that the browser adds. There are ways to hack around this, but they limit the looks we can achieve and add junk to the markup.

Another option is to use background images of numbers. This has the disadvantage, though, of adding five more HTTP requests to the page. To minimize this, you could use a technique called “CSS sprites” where you combine all the images into one and then use background positioning to reveal the portion of this big image that you want to show on each list item. But even using sprites, you still have to deal with one extra HTTP request that you don’t really need, plus some complicated CSS to make the technique work.

Instead of using images, let’s use generated content like we did to insert the numbers for us. But we’ll take it a step further this time. Instead of hard-coding the actual numbers in the content property—which would require five different rules for the five different list items—we’ll use CSS counters, a CSS 2.1 feature, to dynamically generate and increment the numbers.

To use counters, you must first create a set of counters with a name of your choosing, using the counter-reset property:

This establishes a set of counters, arbitrarily named “list,” that you can now apply to a sequence of elements. (You can also set a base value to start counting from in the counter-reset property, but it’s zero by default, which is what I want, so I haven’t included a number here.) The elements we want to apply the “list” set of counters to are the sequence of li elements inside the table of contents list. To apply the counters, use the counter-increment property in the #toc li rule:

This tells the browser that you want to increment the counter on each li element, but it doesn’t actually display the counter. You need to use the content property to do that. Create a new rule using the :before pseudo-class on the li elements to make the counters display before each list item’s content:

This tells the browser that the content you want to display is a counter, and the name of that counter is “list.” And with that, the numbers magically appear before each list item, starting at one and incrementing by one on each new list item .

The CSS counters make incrementing numbers display before the links.

The CSS counters make incrementing numbers display before the links

We can style these numbers just like any other pieces of content in our pages. First, let’s get them on the same line as the text, by floating both the numbers andtext and adding a little left padding to the list items:

Now let’s give each number a circular background using borderradius, in the same shade of blue as the links, but semitransparent:

As explained in the “Creating ovals and circles with border-radius” sidebar, you can turn blocks into circles by setting the same width and height (here, 1.6em) and then setting the borderradius to half of this value (.8em).

Below it shows that the numbers do indeed have circular backgrounds now, but the text needs some further alignment within those circles. Add these new declarations to the #toc li:before rule:

Using border-radius gives circular backgrounds to the numbers.

Using border-radius gives circular backgrounds to the numbers.

Now the numbers look positively image-like . We’ve created the appearance of icons without needing any images or touching the HTML.

With some CSS3 styling, the numbers look like image icons.

With some CSS3 styling, the numbers look like image icons

Browsers that don’t understand generated content will not see the numbers, let alone their styles. In this case, the numbers are decorative, not essential content, so this is an acceptable instance of progressive enhancement.

IE 6 and IE 7 (top) don’t show the numbers, while IE 9 and IE 8 (bottom) do, but without all of their styling.

IE 6 and IE 7 (top) don’t show the numbers, while IE 9 and IE 8 (bottom) do, but without all of their styling.

Changing Background Color on the Jumped-to Section
All of this work on the table of contents was just a prelude to what we really came here to do: highlight the section of the page that you jump to when you click one of the links in the table of contents. The element that is targeted when you click a link is an h2 element, so the selector we need is h2:target. Create a new rule with this selector, and assign it a background color of the same shade of blue used for the number icons, but at a more semitransparent level:

Its as simple as that. Save the page, view it in a browser, and click on one of the links. The corresponding heading will display a semitransparent light blue background.

The browser not only brings the targeted heading to the top of the window, but also applies a background color.

The browser not only brings the targeted heading to the top of the window, but also applies a background color

To spruce up the appearance a bit, you can add some left padding and a shadow to the text:

We now have a noticeable but not obtrusive highlight on the current heading to help orient the user when the focus jumps down the page. The style also applies when you enter the page with the fragment identifier in the URL to begin with.

The highlighted heading now has a subtle text shadow and padding to move it away from the left edge of the background strip.

The highlighted heading now has a subtle text shadow and padding to move it away from the left edge of the background strip.

:target browser support

target browser support

IE 8 and earlier don’t support the :target pseudo-class; the table of contents links will still work to jump IE users to the corresponding headings, of course, but the headings won’t be highlighted. Since this is how most in-page links work, there’s little chance that users of IE 8 and earlier are going to suspect something is missing. Nor is it likely that users who don’t see the highlight are going to get very disoriented in our page of limited content.

In a real page with far more content, however, the highlight could be a much more important usability feature. Think about the Wikipedia example with hundreds of footnotes—that highlight really comes in handy. Or what if the section being jumped to is so close to the bottom of the page that the browser can’t bring it all the way up to the top of the viewport—this can be pretty disorienting, too. If your page does warrant an IE workaround, you’ll need to use JavaScript. Here are a few scripts that would work:

“Suckerfish :target” by Patrick Griffiths and Dan Webb
“Improving the usability of within-page links” by Bruce Lawson
“Fragment Highlight” by David Dorward

Animating the Change with Pure CSS
Another nice enhancement to our heading highlight would be to either fade in or fade out the background color; the “movement” created by the gradually changing color might direct the viewer’s attention even more effectively than the abrupt change.

You can do this with JavaScript. One popular implementation of such an effect is called the “Yellow Fade Technique.” It was named and started by 37signals in their popular web app Basecamp. When you made a change, that change would be highlighted with a yellow background for a moment, and then the yellow color would fade away.

This brought more attention to the item that was changed, enhancing the usability goal of helping the user orient herself or notice the most important information on the page.

And yes, of course, we can accomplish a similar effect using CSS3 instead of JavaScript. Webkit-based browsers, Opera, and Firefox 4 support transitions, and Webkit-based browsers also support animations created with pure CSS. Transitions can be used here to fade in the color when the heading is targeted, and then fade it out again when the target is removed. Animations can be used to either fade in or fade out the color—or both, in succession—when the heading is targeted.
Let’s check out both options.

Before we go any further, let me pause and assuage your potential anxiety. I know that CSS transitions and animations make some people uneasy.

For one thing, they don’t have great browser support. At the time of this writing, transitions are supported only in Webkit-based browsers, Opera 10.5 and later versions, and Firefox 4—a small chunk of overall browser user-share. Animations are supported only in Webkit-based browsers. Because of this, I think you should use them more sparingly than most of the other pieces of CSS3. But I don’t think poor browser support should keep you from using them entirely, as long as you’re certain that the effects you’re using them for are truly non-essential enhancements. That way, adding them doesn’t hurt anyone, and only costs you a little bit of time and effort. Plus, as soon as support does improve, your pages—and your CSS skills—will be ahead of the curve.

Another concern some people have with CSS transitions and animations is that both—but particularly animation—tread into the territory of “behavior,” not “style.” Thus (some argue) these effects should not be included in CSS; they’re the job of JavaScript, other scripting or programming languages, or Flash.

I agree with this argument to a point. Animation is very often behavior.
But it’s very often style, too. Think about a button with a glow that pulses. Is this pulsing glow a behavior of the button? Or is it simply a visual effect—a visual style? Jimmy Cuadra, in his article “CSS3 transitions and animation: Presentation or behavior?”, calls these sorts of effects “presentational behavior.”
I like the distinction he makes between presentation and behavior:

Instead of thinking of presentation as what things look like and behavior as what things do, we should think of presentation as anything that doesn’t fundamentally alter the page, and behavior as anything that manipulates document structure or data, or that facilitates explicit user interaction.

This idea of “presentational behavior” or “effects” is not new to CSS3. CSS 2.1 has a taste of behavior-like styles using the :hover, :focus, and :active pseudo-classes. A button that changes color when you hover over it is displaying a behavior, but the behavior is a decorative and usability enhancement, not essential to the content or functionality of the page. CSS3 simply extends this further, giving you the ability to control a wider range of dynamic stylistic effects with CSS. I think it makes sense and is acceptable to have simple, decorative animations controlled by a styling language; the more complex or behavioral animations should stay in the domain of scripting languages or Flash.

Yes, CSS animation can be abused. It shouldn’t be used for essential behaviors, or for very complex animations that something like Flash could handle more gracefully and efficiently, although a few people will likely use it in these ways. That’s a shame, but it’s a fact of life with just about any CSS technique. Evil web designers can always twist virtuous CSS into work on their dastardly web sites. Don’t worry about what evil web designers might do with CSS animations and transitions. Just worry about using them responsibly and effectively yourself. After all, they’re not without their benefits.

One of the greatest advantages to you of CSS transitions and animations is that once you know the syntax, they can be a lot easier to implement and later modify than equivalent effects in JavaScript or Flash. (Just make sure you’re using CSS3 animations appropriately— a very complex animation is going to be easier to create in Flash, but you shouldn’t be using CSS3 animation for something complex anyway.) CSS is also free, whereas using Flash for creating animations is definitely not free.

In terms of benefits to your users, CSS transitions and animations don’t rely on having JavaScript enabled or the Flash plugin installed; the effects run off built-in browser functionality. Some users have JavaScript disabled, and Flash does not and apparently never will work on the iOS for iPhone, iPod Touch, and iPad. So although browser support is poor for CSS animation now, in the future, when support has increased, it may be the best way to show the widest possible audience your simple decorative effects.

CSS3 transitions and animations can also have performance benefits.
You don’t need any external JS or SWF files to run them, so there are less HTTP requests. They also sometimes take less of the user’s machine’s performing power to run, at least compared to a JavaScript version. But this largely depends on the particular animation and the alternate technology you’re comparing it to—Flash is often less processor-intensive than the CSS3 equivalent. So again, be sure to use transitions and animations only on relatively simple effects and to test them well.

We are not suggesting that CSS transitions and animations are a magic bullet, or that they have no disadvantages. But they’re another great tool that we can use carefully in appropriate situations. Let’s see how to do that now.

The first option for fading in the background color of the current heading is to use transitions. These are essentially the simplest type of CSS animation. Transitions let you ease the change between two different styles of an element gradually and smoothly, instead of seeing an immediate and abrupt difference in style when an element is hovered, targeted, or has its state otherwise changed.

You apply a transition by telling the browser which property you want to gradually change (using transition-property) and how long the change should take in seconds (using transition-duration). You can optionally add a delay to the start of the transition (transitiondelay) and vary the speed of change over the duration of the transition (transition-timing-function).

All of these properties can also be combined into the shorthand transition property. Add it, and the three browser-specific equivalents, to the h2 rule:

Here, we’ve told the browsers that any time the background-color value of an h2 element changes, we want it to make that change happen gradually over the course of one second. We’ve also specified a transition-timing-function of ease-out so that the animation will slow down slightly at the end.

Transitions are hard to illustrate in a static book, the gradual change in color when a heading is targeted. The transition runs in reverse, from blue to transparent, when you use the Back button in your browser to remove the target from the heading.

Over the one-second course of the transition, the background of the heading darkens from fully transparent to blue.

Over the one-second course of the transition, the background of the heading darkens from fully transparent to blue.

We could have put the transition on the h2:target rule instead of the h2 rule. But if we did this, the transition would run only when a heading became targeted; it wouldn’t run in reverse when the target is removed, but would instead abruptly change back to transparent.

Also, currently, Opera supports transitions only when you place them on the original state of the element, not on the changed state, so the transition wouldn’t work in Opera if it were applied to the h2:target rule. This seems to be incorrect behavior, but the in-progress W3C spec doesn’t make this clear.

In addition to the background color transition, we can make the left padding added to the highlighted headings transition too, to create the appearance that the text is sliding to the right. You can do this by simply writing the padding transition in the same transition property, separated by a comma:

transition browser support

transition browser support

Now the padding change from zero to ten pixels happens gradually along with the gradual background color change . How smoothly both of these transitions run depends a bit on your browser (Webkit seems to be the smoothest and Firefox the most jerky), but all the supporting browsers perform well on these simple effects.

Over the course of the transition, the background of the heading darkens and its text moves ten pixels to the right.

Over the course of the transition, the background of the heading darkens and its text moves ten pixels to the right.

We think briefly showing the background color on the current heading and then fading it out would be even more effective and attractive than fading it in. It would be great if we could use transitions to do this, as transitions have better browser support than animations (remember, only Webkit supports animation right now).

Unfortunately, transitions won’t work here, because we need each heading to go from transparent (before it’s targeted) to blue (when it’s targeted) to transparent again (a second after its targeted). That’s three points of change, and transitions can only handle changing between two values.

CSS3 animations can change between as many values as you want.
They do this by letting you set up a series of keyframes, or points in time within the animation, each with its own set of styles. The browser then smoothly transitions between the keyframes in order, gradually changing all the properties included in each one.

To create an animation in CSS, you first need to give it a name of your choosing and define what it will do at each keyframe. You do this using an @keyframes rule, but since only Webkit supports it right now, we need to create two rules, one with the -webkit- browser prefix and one without, for future compatibility. Add this new rule to CSS in the page:

This assigns a name of “fade” to our animation and specifies two keyframes: one zero percent of the way through the duration (in other words, at the very beginning) and one 100 percent of the way through the duration (in other words, at the very end). We could also have used the keywords from and to in place of 0% and 100% to denote the starting and ending states.

Now that we’ve defined what we want our animation to do, we need to apply it to an element. We want the animation to occur on targeted h2 elements, so create a new h2:target rule and place it under the existing one (soon you’ll see why we don’t want to add on to the existing h2:target rule):

This tells the browser that the animation we want to run on this element is named “fade” (using -webkit-animation-name). We want the animation to take two seconds (the -webkit-animation-duration value) and run only once (the -webkit-animation-iteration-count value). We’ve also told the browser we want the animation to ease in, making it slightly slower at the beginning than the end.

You can combine all these properties into the animation shorthand property. Combine the -webkit- prefixed properties into the -webkit- animation property, and also add the non-prefixed animation property to the

This second h2:target rule also removes the left padding and background color declared in the first one. If we didn’t remove the background, the animation would run once, and then once it was over, it would display the static background color of the h2, popping back to blue suddenly and staying blue. We need the heading to have no background so the animation can control the background entirely; once the animation is over, we want the heading to remain transparent.

Removing the padding, on the other hand, is optional. We have chosen to remove it because it doesn’t make sense to have the heading text indented once the background color has faded away. To fix this, it’s possible to animate the padding, having it decrease from ten pixels to zero, just as we transitioned the padding in the opposite direction, but we found the padding movement to be more distracting in this case—it looked good with the fade-in, but we didn’t like it with the fadeout. We opted for simplicity and decided to nix the padding altogether.

Save the page, and view it in Safari or Chrome. When you click on a link, the background of the selected heading will immediately become blue and then fade away smoothly.(This looks just like the sequence in Figure below, but in reverse.)

What would be even nicer is if the blue color stayed in place for a moment, and then faded away. The animation-delay property allows you to delay the beginning of the animation, but that’s not appropriate in this case, because the heading has no background color to start with. Before the animation starts, the user would not see blue, but just a lack of any background at all.

animation browser support

animation browser support

Instead of using animation-delay to put off the start of the animation, we can create a delay within the animation itself by adding another keyframe to the animation that keeps the color the same shade of blue:

Now the animation will start immediately by displaying a blue background, keep showing that background until 20 percent of the way through the animation’s duration (.4 seconds), and then start fading to transparent.

The fade-out animation is now working great in Safari and Chrome, but what about other browsers? We had to remove the background color from the targeted h2 elements to make the animation work, so now nothing changes in non-Webkit browsers when you click on one
of the table of contents links; they just remain transparent. What we need is a way to let browsers that don’t support CSS animations see the first h2:target rule with the blue background color, and browsers that do support CSS animations see the second h2:target rule with the transparent background color.

This script is included in the exercise files you downloaded for this chapter, so add a link to it in the head of the page:

<script src=”scripts/modernizr-1.6.min.js”></script>

This script adds classes to the html element of the page the correspond to what the browser does and doesn’t support. So, for instance, Modernizr will add a class of “cssanimations” to the html element in Safari and Chrome, and all other browsers will get a class of “no-cssanimations”.

This allows us to change the second h2:target selector to apply only when the cssanimations class is present:

Save your page, and view it in both a Webkit-based browser and a non-Webkit browser. In the former, you’ll see the fade-out animation run when a heading is targeted. In the latter, you’ll see the fade-in transition run when a heading is targeted. In browsers that don’t support either transitions or animations, but do support :target (such as IE 9 and Firefox 3.6 and earlier), you’ll see the blue background immediately appear on the targeted heading. And finally, in browsers that support none of the above (such as IE 8 and earlier), you’ll see nothing special happen when you click a table of contents link.

The table of contents links will still work, of course—they’ll still jump people down the page, just as we’re all used to, so there’s no reason users of less capable browsers will know anything is missing. If you really must have a fade effect on the targeted heading in these browsers, you have a couple workaround options:

Use an animated GIF. Yes, it’s a bit old-school, but it’s still a perfectly valid technique. Be aware that this works only on browsers that support :target. All you have to do is add an animated GIF of the color change as the background image in the h2:target rule.

You can read an entire tutorial about this method in “Star on :target” by Brian Suda at http://thinkvitamin.com/dev/stay-on-target.

Use a script. This will work regardless of whether or not the browser supports :target (as long as the user has JavaScript enabled, of course, and as long as the script was written to support that user’s browser). Also consider Googling “javascript animation framework.” Finally, if you’re just interested in a fade technique, Google “yellow fade technique” and you’ll find a bunch of scripts—some standalone, some related to a particular framework—that you can choose from.

In either of these options, remember to hide the extra CSS or scripts from browsers that don’t need them, using either IE conditional comments or Modernizr.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

CSS3 Topics