Is there a reason why this CSS doesn't work?
http://jsfiddle.net/6v5BZ/
a[href^="http"]:after { content:""; width:10px; height:10px; display:inline-block; background-color:red; } a[href^="http"] img ~ :after { display:none; }
.. on this HTML?
<a href="http://google.com">Test</a> <a href="http://google.com"> <img src="https://www.google.com/logos/classicplus.png"> </a>
The idea is to have a pseudo-element on matching anchor tags. But I do not want it to apply to anchor tags that wrap an image. And since I can't target anchors using something like a < img
, I figured the maybe I could target the :after pseudo-element by finding an image that it's a sibling of.
Any insight would be greatly appreciated.
In CSS2. 1, an element can only have at most one of any kind of pseudo-element at any time. (This means an element can have both a :before and an :after pseudo-element — it just cannot have more than one of each kind.)
CSS ::before and ::after pseudo-elements allow you to insert “content” before and after any non-replaced element (e.g. they work on a <div> but not an <input> ). This effectively allows you to show something on a web page that might not be present in the HTML content.
The ::before pseudo-element can be used to insert some content before the content of an element.
There are no special rules around combining pseudo-classes and pseudo-elements, besides the one rule that says there can only be one pseudo-element per complex selector and it must appear at the very end.
You can't target :after since it's content is not rendered in the DOM and it does not manipulate it - for this to work the DOM would have to be re-rendered and CSS can't manipulate it like this.
Check the specification for detailed understanding: http://www.w3.org/TR/CSS2/generate.html#propdef-content
Generated content does not alter the document tree. In particular, it is not fed back to the document language processor (e.g., for reparsing).
I suggest you use JavaScript to do the job for you.
You cannot use a combinator to target a pseudo-element relative to elements other than its generating element.
This is because they're pseudo-elements, not actual elements, and combinators only work by establishing relationships between actual elements. A pseudo-element, on the other hand, can only be applied to the subject of a selector (the rightmost compound selector), and this happens only after matching is processed on the real elements. In other words, matching is done first as though the pseudo-element wasn't there, then the pseudo-element, if it's indicated within the selector, is applied to each match.
In your code, the following selector:
a[href^="http"] img ~ :after
Does not actually look for an :after
pseudo-element that comes after an img
within the a
, even though it appears that way as both are rendered as children of the a
element.
It can be rewritten into the following:
a[href^="http"] img ~ *:after
Notice the *
selector, which is implied. Similarly to how you can omit *
before any other simple selectors for it to be implied, omitting *
from a pseudo-element also makes it implied to be there. See the spec for details.
Now, even though it appears *:after
should still match a:after
(since a
would match *
), it still doesn't work that way. If you remove the :after
pseudo-element from the selector:
a[href^="http"] img ~ *
You'll notice that the meaning of the selector changes entirely:
Select any element
that appears as a following sibling of animg
that is a descendant of ana
(whosehref
starts with "http").
Since the img
is the last child of the a
element in your HTML, there are no following siblings to match, and therefore no :after
pseudo-elements can be generated.
In the case of a :before
or :after
pseudo-element, one might think of matching the pseudo-element's generating element relative to the pseudo-element's "sibling", but as the OP has correctly pointed out, there is no parent selector, so they're out of luck there, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With