ChatGPT解决这个技术问题 Extra ChatGPT

How can I write a ':hover' condition for 'a:before' and 'a:after'?

How can I write :hover and :visited condition for a:before?

I'm trying a:before:hover, but it's not working.


C
Community

This depends on what you're actually trying to do.

If you simply wish to apply styles to a :before pseudo-element when the a element matches a pseudo-class, you need to write a:hover:before or a:visited:before instead. Notice the pseudo-element comes after the pseudo-class (and in fact, at the very end of the entire selector). Notice also that they are two different things; calling them both "pseudo-selectors" is going to confuse you once you run into syntax problems such as this one.

If you're writing CSS3, you can denote a pseudo-element with double colons to make this distinction clearer. Hence, a:hover::before and a:visited::before. But if you're developing for legacy browsers such as IE8 and older, then you can get away with using single colons just fine.

This specific order of pseudo-classes and pseudo-elements is stated in the spec:

One pseudo-element may be appended to the last sequence of simple selectors in a selector. A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence. A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

A pseudo-class is a simple selector. A pseudo-element, however, is not, even though it resembles a simple selector.

However, for user-action pseudo-classes such as :hover1, if you need this effect to apply only when the user interacts with the pseudo-element itself but not the a element, then this is not possible other than through some obscure layout-dependent workaround. As implied by the text, standard CSS pseudo-elements cannot currently have pseudo-classes. In that case, you will need to apply :hover to an actual child element instead of a pseudo-element.

1 Of course, this does not apply to link pseudo-classes such as :visited as in the question, since pseudo-elements aren't links.


It should be pointed out that that puts the hover on the parent element - which causes the decoration to be applied even if the ::after pseudoelement is not under the mouse, as long as its parent is.
It should also be noted that there are a number of things that don't respond to this because of the way the layout rules are specified – e.g. text-decoration.
@Chris Krycho: Indeed - I actually happen to have an explanation for this specific issue with regard to pseudo-elements here. Of course, it's worth clarifying that the issue itself has no connection with pseudo-class/pseudo-element selectors, but is as you point out, a layout issue.
Sinlge colon (:) designates pseudo-classes and double colon (::) designates pseudo-elements. So it should be a:hover::before
@mwb: Of course, assuming IE8 support is not needed. This answer was posted several months before Selectors 3 even became a recommendation, and I'm not inclined to change it given that IE8 is still significantly used.
T
T.Todua

Write a:hover::before instead of a::before:hover: example.


@mikkelbreum do you have a reference to prove that?
@bungeshea: That is CSS3 syntax. See the comments under my answer (as well as my recent edit). It's a little inaccurate to call it "the" correct syntax though because both single and double colons are permitted for CSS1/2 pseudo-elements. I would call it the recommended syntax instead, because the only reason to continue using the legacy syntax today is for supporting IE8 and older.
@mikkelbreum @sheabunge more info on CSS2 :after vs CSS3 ::after developer.mozilla.org/en-US/docs/Web/CSS/::after (single : has better support)
it is not working for underline :( jsfiddle.net/porzechowski/u5dhthvq Please add also display: inline-block; jsfiddle.net/porzechowski/u89fo4oq
P
Peter Mortensen

To change a menu link's text on mouseover (different language text on hover), here is the

jsfiddle example

HTML:

<a align="center" href="#"><span>kannada</span></a>

CSS:

span {
    font-size: 12px;
}
a {
    color: green;
}
a:hover span {
    display: none;
}
a:hover:before {
    color: red;
    font-size: 24px;
    content: "ಕನ್ನಡ";
}

This is a lovely answer. In fact, it inspired me to extend your fiddle slightly by boosting the font-size of the span text to 24px to match the replacement text, added 3 non-breaking spaces before and after the replacement text so that they occupy the same width, and styled a:hover::before with text-decoration: underline, which causes the underline to pick up the red color of the replacement text.
The syntax highlighter does not like it (near "color: red;"). What is the reason?
P
Peter Mortensen

Try to use .card-listing:hover::after, hover, and after using ::. It will work.


P
Peter Mortensen

Or you can set pointer-events:none to your a element and pointer-event:all to your a:before element, and then add hover CSS to a element:

a{
    pointer-events: none;
}
a:before{
    pointer-events: all
}
a:hover:before{
    background: blue;
}

Is this working to anyone?
@Jagath: Good question. The syntax highlighting is off, hinting at a problem.
Why isn't there a semicolon after pointer-events: all?
P
Peter Mortensen

BoltClock's answer is correct. The only thing I want to append is that if you want to only select the pseudo element, put in a span.

For example:

<li><span data-icon='u'></span> List Element </li>

instead of:

<li> data-icon='u' List Element</li>

This way you can simply say

ul [data-icon]:hover::before {color: #f7f7f7;}

which will only highlight the pseudo element, not the entire li element.


P
Peter Mortensen

You can also restrict your action to just one class using the right pointed bracket (">"), as I have done in this code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    span {
      font-size: 12px;
    }
    a {
      color: green;
    }
    .test1>a:hover span {
      display: none;
    }
    .test1>a:hover:before {
      color: red;
      content: "Apple";
    }
  </style>
</head>

<body>
  <div class="test1">
    <a href="#"><span>Google</span></a>
  </div>
  <div class="test2">
    <a href="#"><span>Apple</span></a>
  </div>
</body>

</html>

Note: The hover:before switch works only on the .test1 class


The syntax highlighter does not like it (near "color: red;"). What is the reason?