The CSS pseudo-class :target to highlight linked content

- 👤 Andrés Cruz

🇪🇸 En español

The CSS pseudo-class :target to highlight linked content

The :target pseudo-class in CSS is one of those tools that go unnoticed until you need it… and then you realize how powerful it can be. It allows you to apply styles to an HTML element when its id matches the fragment (#) of the URL, which opens the door to creating visual states, highlighting sections, or even building small interaction patterns without the need for JavaScript.

In this post, I am going to explain what the :target pseudo-class or selector is, how it really works, and how I have used it in practice with clear and applicable examples to use in our web designs.

What is the :target pseudo-class in CSS?

The :target pseudo-class selects the element whose id attribute matches the current URL fragment. That fragment is the part that appears after the # character.

In other words: when you navigate to a URL like page.html#section, the element with id="section" automatically moves to the :target state.

This turns the browser itself into a very basic, but surprisingly useful, "state manager."

This selector or pseudo-class is used to select or style a single element whose id matches one of the HTML elements; in other words the :target selector is used to style the currently activated HTML element.

URLs preceded by the # character followed by an identifier allow linking to elements within the HTML document; let's see an example.

How does :target work with the URL fragment (#)?

If we wanted to link the following element through a link:

<h2 id="cuatro">Example four</h2>

We would have to create a link like the following:

<a href="#cuatro"">Using the :target pseudo-class to apply an overlay</a>

Where the text following the # character corresponds to the element's identifier.

When the user clicks, the browser:

  • Updates the URL by adding #cuatro
  • Scrolls to the element
  • Activates the :target pseudo-class on that element

And from CSS you can react to that state:

#cuatro:target { background: yellow;}

In practice, this is ideal for visually highlighting the section the user has just arrived at, something I have used many times in long documents and FAQs.

Basic syntax of the :target selector

The syntax is very straightforward:

element:target { /* styles */}

Or combining it with classes:

.part:target { border: 2px solid red;}

Minimal example with HTML and CSS

.part:target { border: 2px solid #f00;}

This type of rule is so simple that when I first tried it, I was surprised at how easy it was to achieve a clear visual effect without writing a single line of JavaScript.

What happens when there are several links and only one :target

There can only be one active :target at a time because there can only be one fragment in the URL. This is an important limitation… but also a hint as to how it should be used: :target is intended for exclusive states, not multiple selections.

The :target pseudo-class in practice

The :target pseudo-class is very useful when we click on links to activate sections in a document; indicating the selected section in a more visual way to draw the user's attention to an area of interest; click on the following links:

In the previous example, we are creating a region of interest through the border property according to the element activated through the link clicked by the user.

The CSS for the previous example is as follows:

.part:target {border: 2px solid #F00;}

Really simple and requires no extra explanation; as for the HTML, it is divided into two blocks:

The menu that references each of the text blocks in the document:

 <nav>
     <ul>
         <li><a href="#part1">part 1</a></li>
         <li><a href="#part2">part 2</a></li>
         <li><a href="#part3">part 3</a></li>
         <li><a href="#part4">part 4</a></li>
     </ul>
 </nav>

And the text blocks of the document:

   <div id="part1" class="part">
       <span><a href="">X</a>
           <h1>part 1</h1>
           <p>Esto es un monto de texto sin sentido que tiene la finalidad
               de llenar espacio para mostrar un contenido.</p>
           ...
       </span>
   </div>
   <div id="part2" class="part">
       <span><a href="">X</a>
           <h1>part 2</h1>
           <p>Esto es un monto de texto sin sentido que tiene la finalidad
               de llenar espacio para mostrar un contenido.</p>
           ...
       </span>
   </div>
   <div id="part3" class="part">
       <span><a href="">X</a>
           <h1>part 3</h1>
           <p>Esto es un monto de texto sin sentido que tiene la finalidad
               de llenar espacio para mostrar un contenido.</p>
           ...
       </span>
   </div>
   <div id="part4" class="part">
       <span><a href="">X</a>
           <h1>part 4</h1>
           <p>Esto es un monto de texto sin sentido que tiene la finalidad
               de llenar espacio para mostrar un contenido.</p>
           ...
       </span>
   </div>

The HTML shown above will not have any variation in the experiments (except for the last one) presented in this post.

The :target pseudo-class and animations

We can use CSS animations to create more subtle and non-persistent changes over time:

We specify the animation property:

.part:target { animation: glow 1s ease-out;}

The properties defined in the @keyframes simply change the background color:

@keyframes glow { 0% { background-color: rgba(255,0,0,0.2); } 100% { background-color: #FFFFFF; }}

:target and CSS animations

This is where things get interesting.

.part:target {
 animation: brillar 1s ease-out;
}
@keyframes brillar {
 0% { background-color: rgba(255, 0, 0, 0.2); }
 100% { background-color: #fff; }
}

Applying animations with @keyframes

This pattern has worked very well for me to draw attention without the effect being persistent. The user notices the change, but the design returns to normal.

  • Non-persistent visual effects
    • Unlike other states, the animation runs only when :target is activated, making it perfect for informative flashes.
  • When to use animations with :target
    • To highlight linked sections
    • To indicate context after a jump
    • As progressive enhancement

The :target pseudo-class and transitions

In this third example, we will see how to use the selector in conjunction with CSS transitions; by default, we will hide all content blocks using the opacity property set to zero:

.part {/*other rules*/opacity: 0;transition: opacity 1s;}

When clicking on a link, we will show the content block progressively using the following rule that increases the opacity of the activated block:

.part:target {opacity: 1;}

Using the :target pseudo-class to apply an overlay

As a final example, we will see how to create a simple modal-like effect by activating the text block:

selector target in CSS - example 4

The main thing you should keep in mind about this experiment that you can see below:

Is that we completely override the behavior of the activated text block; that is, its position relative to the rest of the document is altered with the position property, as well as its size, which is configured to occupy 100% of the screen:

.part:target {
	background: rgba(0, 0, 0, 0.5);
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 5px;
	box-shadow: 0 0 15px #666;
}

And the content to be displayed, embedded within the span element, is located in the middle of the screen:

.part:target span {
	background: #FFF;
	padding: 10px;
	margin: 20% auto 0 auto;
	display: block;
	width: 50%;
	height: auto;
}

The other rules are easy to understand and allow for defining a better aesthetic for the experiment.

Visually highlighting the active element

A simple example I often use as a starting point is this:

.part:target { border: 2px solid #f00;}

It is direct, clear, and fulfills its function: telling the user "you are here."

Use of border, background, and box-shadow

The most common properties for :target are:

  • border
  • background-color
  • box-shadow
  • small transformations (transform)

Do not overdo it: in my experience, subtle effects work better than aggressive changes.

:target and CSS transitions

In another experiment, I decided to initially hide all blocks:

.part { opacity: 0; transition: opacity 1s;}

And then show only the active block:

.part:target { opacity: 1;}

Showing content progressively with opacity

This approach is ideal for simple interfaces where you want to reveal content progressively.

Best practices for guiding user attention

Something I learned quickly is that :target should not "break" the design. It is better to use it as a temporary visual reinforcement, not as a permanent layout change.

Differences between animations and transitions

  • Animations: total control of the effect
  • Transitions: simple and more predictable
  • Both work well with :target, depending on the result you are looking for.
  • Common mistakes when using transitions with :target

The most common mistake is trying to use display: none, which breaks the transition. opacity is usually a better option.

Creating an overlay or modal using :target

This is probably the most striking use.

.part:target { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; left: 0; width: 100%; height: 100%;}

Overriding the document flow with position: fixed

Here we completely override the normal behavior of the block, taking it out of the document flow.

Center content on screen.part

:target span { background: #fff; padding: 10px; margin: 20% auto 0; display: block; width: 50%;}

This pattern is simple, but it works surprisingly well for basic modals.

Real-world use cases of :target in CSS

Highlighting linked sections within a document

One of the most common (and most effective) uses is to highlight the section that an internal link points to. In long documents, this helps a lot to not lose context after the page jump.

On more than one occasion, I have used :target simply to add a temporary border or background that guides the user's view right after the click.

Internal navigation and anchor menus

A very typical pattern is combining a menu with internal links:

<nav>
 <ul>
   <li><a href="#part1">part 1</a></li>
   <li><a href="#part2">part 2</a></li>
   <li><a href="#part3">part 3</a></li>
   <li><a href="#part4">part 4</a></li>
 </ul>
</nav>

Each link activates its corresponding section, and from CSS you can make it clear which part is active at any given time.

Showing and hiding content without JavaScript

Although it does not replace a full state system, :target works surprisingly well for:

  • simple dropdowns
  • conditional sections
  • interactive examples

As long as you accept its rules of the game.

Limitations of this approach

It is not a replacement for a full modal:

  • it does not manage focus
  • it depends on history
  • it has scroll effects

But for prototypes or quick solutions, it fulfills its function.

Advantages and disadvantages of using :target

When :target is a good option

I usually use it when:

  • I need a simple state.
  • The scroll jump is acceptable.
  • I don't want to add JavaScript.

Scroll issues and page jumps

The jumping behavior is part of the :target contract. Sometimes it is useful, other times not so much. Ignoring it usually leads to confusing results.

Impact on browser history

Each change of :target affects the URL, and therefore the history. This can be an advantage… or a problem, depending on the case.

:target versus other CSS pseudo-classes

  • Differences between :target, :hover, and :focus
    • :hover: specific interaction
    • :focus: accessibility and keyboard
    • :target: URL-based state

They are different tools, not interchangeable.

When to choose :target and when not

If you need multiple simultaneous states or fine control, :target is not the best option. But for single states, it remains an elegant solution.

Browser compatibility and accessibility

  • Support in modern browsers
    • :target has been supported for years in all modern browsers, making it very safe in terms of compatibility.
  • Accessibility considerations
    • Never rely solely on color to indicate state. Combine visual changes with clear structure and understandable content.

Frequently asked questions about the :target pseudo-class

  • Can :target be used without links?
    • No. It needs a fragment in the URL.
  • Can I have several active :target elements?
    • No, only one at a time.
  • Is it an alternative to JavaScript?
    • Not entirely, but it can avoid it in simple cases.

Conclusion

The :target pseudo-class in CSS is a simple but very powerful tool when used with judgment. In my experience, it works best as a progressive enhancement and as a lightweight solution for single states. It does not replace JavaScript, but in many cases, it allows you to do more with less.

If you know when to use it (and when not to), :target can become a very useful ally in your web designs.

As a more advanced experiment, create a 3D carousel or slider using HTML5 and CSS.

I agree to receive announcements of interest about this Blog.

Learn what the `:target` pseudo-class is in CSS, how it works, and when to use it. Practical examples, animations, transitions, and modals without JavaScript.

| 👤 Andrés Cruz

🇪🇸 En español