user7786890
user7786890

Reputation:

How can I set different icons for visited and unvisited external links with CSS?

I'm trying to set different icons for visited and unvisited external links. At first, I tried this:

a[href^="http"] {
    padding-right: 1.1em;
    background-image: url(external_link.gif);
    background-repeat: no-repeat;
    background-position: center right;
}
a[href^="http"]:visited {
    background-image: url(visited_external_link.gif);
}

— but, obviously, it didn't work.

This:

a {
    padding-right: 1.1em;
    background-image: url(external_link.gif);
    background-repeat: no-repeat;
    background-position: center right;
}
a:visited {
    background-image: url(visited_external_link.gif);
}
a:not([href^="http"]) {
    background-image: none;
    padding-right: 0;
}

— didn't work too.

So, how can I to set different icons or, in other words, change icon only for visited external links? Is it possible without classes?

Upvotes: 1

Views: 1355

Answers (2)

Extricate
Extricate

Reputation: 811

In theory you could try using the a:visited:before or the :after selector in combination with an icon font like Font Awesome, which would look something like:

a:visited:before {
   content: "\icon-code";
}

Or you could use your background-image:

a:visited:before {
   content: " ";
   background-image: url('your-background-image.jpg');
   height: 10px;
   width: 10px;
}

However, beware that the :visited selectors have restrictions regarding psuedo-elements in modern browsers (to protect your privacy); for example in Firefox 4 you are only allowed to change an a:visited links' (border) colors (look here and here for reference).

Thus, as mentioned by other answers, the above will not work in production because popular browsers will not render it (per W3 school and Mozilla Developer Network).

Direct quote from the Mozilla Developer Network on the issue:

Note: For privacy reasons, browsers strictly limit the styles you can apply using an element selected by this pseudo-class: only color, background-color, border-color, border-bottom-color, border-left-color, border-right-color, border-top-color, outline-color, column-rule-color, fill and stroke. Note also that the alpha component will be ignored: the alpha component of the not-visited rule is used instead (except when the opacity is 0, in that case the whole color is ignored, and the one of the not-visited rule is used).

And you'd say that's the end of that, but it's not! There (1) are (2) a lot (3) of interesting ways to circumvent these restrictions (for a detailed blog post with a lot of references to this issue, you can look here on CSS-tricks).

For example, one of the tricks is to style two a elements that link to the same href, and style the first one to be an icon. When someone clicks on the link with text, the a in front also gets affected.

Here's an example from the previously linked Quora post (which is based on the DuckDuckGo's visited feature) (which sadly won't work as a working snippit due to it working with links):

<h2 class="result__title">
   <a class="result__a" href="https://google.com">Link to Google
   </a>
   <a class="result__check" href="https://google.com">
       <span class="result__check__tt">Link icon</span>
   </a>
</h2>

Now in your CSS you make the .result__check only show up (in your stylesheet) if you've visited the link!

.result__check:before{
    content: "\2611";
}
.result__check {
    color: #fff;
    position: absolute;
    right: 100%;
    top: 0.3em;
    margin-right: 1em;
    font-size: 0.8em;
    width: 1em;
    white-space: nowrap;
}
.result__check:before{
    display: inline-block;
    float: right;
}
// This is what gives the color to the visited item
.result__check:visited {
    color: #c3c3c3;
}
.result__check__tt {
    visibility: hidden;
    opacity: 0;
    background-color: #a3a3a3;
    background-color: rgba(138,138,138,0.9);
    padding: 0 1em;
    font-size: 0.76em;
    line-height: 2;
    position: absolute;
    bottom: 2.5em;
    left: -0.95em;
    z-index: 200
}
.result__check__tt:before {
    content: "";
    display: block;
    position: absolute;
    margin-left: -0.5em;
    bottom: -0.5em;
    left: 1.5em;
    border: 0.5em solid transparent;
    border-bottom-width: 0;
    border-top-color: #a3a3a3;
    border-top-color: rgba(138,138,138,0.9)
}
.result__check:hover .result__check__tt {
    visibility: visible;
    opacity: 1
}

That way, you are able to style the :visited element, even though browsers restrict it. Hope it helps!

Upvotes: 4

Julie
Julie

Reputation: 2011

The pseudo element suggestions in other answers or other approaches (short of perhaps JavaScript) will not work. Per W3 schools https://www.w3schools.com/cssref/sel_visited.asp:

Browsers limits the styles that can be set for a:visited links, due to security issues.

Allowed styles are:

  • color
  • background-color
  • border-color (and border-color for separate sides)
  • outline color
  • column-rule-color
  • the color parts of fill and stroke

All other styles are inherited from a:link.

Even using pseudo elements as others have recommended do not work since you still need to include :visited in the css declaration, which continues to prevent you from adding background images.

Upvotes: 1

Related Questions