What is the reason for the .foo a:link, .foo a:visited {} selector taking precedence over the a:hover, a:active {} selector in CSS?

Sample code: http://jsfiddle.net/RuQNP/

<!DOCTYPE html>
<html>
<head>
    <title>Foo</title>
    <style type="text/css">
        a:link, a:visited {
            color: blue;
        }

        a:hover, a:active {
            color: red; 
        }

        .foo a:link, .foo a:visited {
            color: green;
        }

        /* A possible fix */
        /*
        .foo a:hover, .foo a:active {
            color: red;
        }
        */
    </style>
</head>
<body>
    <div class="foo">
        <a href="http://example.com/">Example</a>
    </div>
</body>
</html>

Anticipated Outcome:

The link would change to red upon hovering.

Actual Result:

The link changes to green when hovered over.

Inquiries:

  1. Why does the color specified in the selector .foo a:link, .foo a:visited override the one in a:hover, a:active? What seems to be happening?
  2. I grasp that I could resolve this by uncommenting the commented code. However, I'm curious about how we can adjust the .foo a:link, .foo a:visited selector so it doesn't take precedence over the color defined in a:hover, a:active?

If my comprehension of http://www.w3.org/TR/CSS21/cascade.html#specificity is correct (Thanks, BoltClock), here's the specificity table for the different selectors in the code.

a:link         - 0 0 1 1
a:visited      - 0 0 1 1
a:hover        - 0 0 1 1
a:active       - 0 0 1 1
.foo a:link    - 0 0 2 1
.foo a:visited - 0 0 2 1

Therefore, the style set for .foo a:link takes precedence over the style for a:hover when both link and hover pseudo-classes are applied to an A element with the class foo.

Similarly, the style designated for .foo a:visited overrides the style for a:hover when both visited and hover pseudo-classes are applicable to an A element with the class foo.

Answer №1

When you delved into the world of CSS for the first time, you may have come across the mnemonic LoVe-HAte as a guide for the order in which to specify link selectors (a:link, a:visited, a:hover, a:active). Have you ever pondered why this specific mnemonic was chosen?

There's actually a interesting point made in the specification document about how link and dynamic pseudo-classes are handled when multiple rules with all of them are applied to the same element, which sheds light on the necessity of setting link selectors in that particular sequence:

It's crucial that A:hover comes after A:link and A:visited rules, as failing to do so would result in the 'color' property of the A:hover rule being obscured by cascading rules. Likewise, since A:active follows A:hover, the active color (lime) takes precedence when the user both activates and hovers over the A element.

The main takeaway here is that despite all four pseudo-classes having equal specificity, the last rule prevails among equally specific selectors. The triggering of each pseudo-class is irrelevant in determining the application of styles.

With the introduction of the simple .foo selector, your second set of link/visited rules supersedes the initial set of link/visited styles and the hover/active styles. Consequently, links within elements carrying that class will consistently appear green until additional hover/active styles are specified using the .foo selector.


I apologize if my response seems a bit rushed or disjointed; I'm currently typing this on my iPhone and it's quite challenging to gather my thoughts under these circumstances...

Answer №2

My interpretation is that all these pseudo classes have equal specificity, so the one written last takes precedence. Now, let's explore the functionality of pseudo-classes

:link, :visited, :focus, :hover, :active
individually.

a: link{color: red} instructs the user agent to make the anchor element red in any state. Execute the following script:

  a:link {
  color: red;
  
  }
<a href="www.stackoverflow.com">Go to stackoverflow </a>

The anchor element turns red in the following states only if the link is unvisited,

  • Unvisited
  • Hovered
  • Focused(Tabbed)
  • Active(Clicked)

Therefore, a: link{color: red} directs the user agent to apply a red color to the anchor element in the aforementioned states. Now, let's compare it with the a:hover pseudo-class. Run the following script

a:hover {
  color: red;
  
}
<a href="www.stackoverflow.com">Go to stackoverflow </a>

The anchor element turns red when hovered and clicked.

  • Hovered
  • Active(clicked)

We observe that both :link and :hover pseudo classes can affect the hover state -- Therefore, if you assign these two pseudo-classes to the same element, the one mentioned later in the CSS file will take precedence. This principle applies to other pseudo-classes as well. Let's outline the actions of each pseudo class.


a:link {...} defines behaviors for an unvisited link in various states:
- Focused(Tabbed)
- Hovered
- Active(Clicked)

The link state supersedes all other states.


a:visited {...} sets the behavior for visited links in the following states:
- Focused(Tabbed)
- Hovered
- Active(Clicked)

a:visited {...} prevails over all states except :link only when the link has been visited.

Please note that a link may be considered visited or unvisited based on the user agent's cache. For example, a website visited ten days ago might not be stored in the user agent's cache, thus technically remaining categorized as unvisited.


a:focus {...} dictates the behavior for visited and unvisited links in various states:
- Focused(Tabbed)
- Hovered
- Active(Clicked)

a:focus {...} takes priority over :hover and :active states.


a:hover {...} determines the behavior for visited and unvisited links when hovered:
- Hovered
- Active(Clicked)

a:hover {...} supersedes the :active state


a:active {...} specifies the behavior for visited and unvisited links when active:

  • Active(Clicked)

Answer №3

To rectify the issue, ensure that the .foo ... selector is placed first and include !important to the color value for the other link/visited selector. Here's an example:

    a:link, a:visited {
        color: blue;
    }

    a:hover, a:active {
        color: red !important; 
    }
    .foo a:link, .foo a:visited {
        color: green;
    }

The reason why the .foo a:link, .foo a:visited selector takes precedence over the other selector regardless of its position is because .foo a:link has higher specificity than a:link. The same applies for :visited. Therefore, the .foo ... selector will always override the a:link,a:visited selector due to its parent class name, making it more specific.
(For further clarification, refer to @BoltClock's explanation on LoVe - HAte - as it plays a role in this issue.)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Missing Home and Search icons on Jquery mobileNavigationBar

I am having an issue where the Home and search icons are not displaying properly in the output. Instead, they are showing up as hyperlinks. Can someone please help me with this? Here is the code I am using: <meta name="viewport" content="width=device ...

The body content is stopping halfway down the page, causing my footer to appear in the middle of the page

For some reason, I'm having trouble getting the footer to properly align at the bottom of the page. My body only seems to go halfway up the page. I tried wrapping everything in a main tag and setting a height on that, but it always ends up stopping at ...

Concealed div obstructing access to dropdown menu

I'm having some trouble creating a dropdown menu. The submenu I've created is appearing behind my wrapper, page, and content. I've attempted to adjust the z-index of various elements and have even tried setting the z-index of my menu and sub ...

What purpose does the asterisk have in CSS?

Similar Question: Understanding the star-preceded property in CSS I recently came across a CSS file for a jQuery script and discovered the following code snippet: .usual div { *margin-top:-15px; clear:left; background:snow; font:10pt Georgia; ...

A div set to absolute positioning and a width of 100% will exceed the boundaries of a Bootstrap 4

I am attempting to position a div with 100 percent width within a Bootstrap 4.1 col using absolute positioning in order to attach it to the bottom. However, I am encountering an issue where it overflows on the right side of the screen. I have tried assigni ...

Building a bespoke pagination feature with react-table

Looking to personalize the pagination with links for "Previous," page numbers, and "Next" like this example: I'm currently using react-table version 7 but have been unable to replicate the desired pagination style. I need it to be dynamic based on th ...

Enhancing your grasp on CSS grid columns - mastering columns through float usage

Struggling to grasp the concepts of using http://semantic.gs alongside LESS.js. The documentation provided isn't quite clear, and I haven't delved deep into understanding LESS.js. However, I have gone through the Semantic Grid System website&apos ...

Tips for adjusting the hue of a single color in a JPEG image

Is there a way to transform white color to red using only CSS, while leaving the rest of the colors unaffected? This should be accomplished without changing any other elements. ...

What strategies can I implement to ensure my modal dialog box remains responsive? Adjusting the window size causes the modal box to malfunction and lose its structure

Whenever I adjust the size of the browser window, the elements inside the modal box become misaligned. HTML <div class='modal'> <div class='modal-content'> </div> </div> Below is the CSS for the modal ...

Error in viewpoint/transformation transition on Microsoft Edge

Encountering a peculiar issue with MS Edge involving the animation of a door (a div tag) around the Y axis using the css rotateY() function in combination with perspective properties. The problem arises when transitioning an angle from a positive value to ...

Arranging Divs with Right Float Alignment

I am running into issues trying to align and float certain divs properly. Currently, I have two divs with images that are displaying correctly, and now I need to add two more divs with images that behave in the same way. Even though I attempted to use th ...

Interactive Form directly linked to SQLite3 database

Looking for assistance with converting a modal from static, fake data to dynamic data from an SQLite3 database. The goal is to display a table of existing data and allow users to add new rows by clicking a +New button. However, when trying to incorporate ...

Disappearing PHP Session following a redirection

I'm encountering an issue with the LDAP Authentication redirection in my system. When I access Index.php, it correctly redirects me to the login page (login.php). However, after entering my credentials, it fails to redirect me back to the Index Page. ...

Is it possible to switch the placement of my sidebar and content?

For some reason unbeknownst to me, I have created two distinct CSS classes called content and sidebar1. My original intention was to position the sidebar on the right side of the page. However, no matter what adjustments I make, the sidebar stubbornly rema ...

What is the best way to assign a dynamic width to a block element?

In my project, I am working with 30 elements that have the class .lollipop and are styled with line-height: 30px; height: 30px;. <a class="lollipop">Random text</a> <a class="lollipop">Random text longer</a> <a class="lollipop"& ...

Text alignment below a div with absolute positioning

Presently, my setup looks something like this: <div class="mycol" id="mycanvas" style="z-index: -1; top:150px;left:240px;width:88%; height:80%; position: absolute;background-color:red;"> </div> <div class="testclass"> He ...

a pair of columns next to each other

I am having trouble getting two lists to display side by side. The second list keeps appearing below the first list. I need them to be in separate divs because they will have different colors and content. Additionally, the lists will be dynamically populat ...

Avoid choosing the menuItem when clicking on the icon within the Material UI select component

I am trying to create a dropdown menu that allows users to delete items. However, when I click on the delete icon within a menu item, the entire menu item gets selected automatically. How can I prevent this default behavior? Here is my code: { dropd ...

Is it possible to use calc with the display property set to table-cell?

I have created a structure using divs to mimic table elements for an entry form. My goal is to make the left column, where field labels are located, 50% wide with an additional 2 em space to accommodate an asterisk marking required fields. The right column ...

Using the getElementById function in javascript to modify CSS properties

Here is the setup I am working with: <div id="admin"> This element has the following style applied to it: display: none; I am attempting to change the display property when a button is pressed by defining and utilizing the following JavaScript co ...