Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can CSS :not selector target :before and :after selectors

I am looking to to use CSS :not() to target the before selector. Is this possible?

Example: https://jsfiddle.net/uuq62b8d/

a.button:before {
  content: "Show Text";
}

a.button:not(:before) {
  display: none;
}

<a href="#" class="button">Hide Text</a>
like image 288
wbdlc Avatar asked Nov 16 '15 12:11

wbdlc


People also ask

Can a CSS rule have multiple selectors?

A CSS selector can contain more than one simple selector. Between the simple selectors, we can include a combinator. There are four different combinators in CSS: descendant selector (space)

What is before and after selector in CSS?

The ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.

What is the precedence of CSS selectors?

Below are the order of specificity rule which has precedence respectively: 1) Inline style: Inline style has highest priority among all. 2) Id Selector: It has second highest priority. 3) Classes, pseudo-classes and attributes: These selectors has lowest priority.


1 Answers

As per W3C Spec:

The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

As you can see from the above statements, :not() takes in only a simple selector as argument and pseudo-elements do not fall under the simple selector category. Hence, no, you cannot achieve what you are trying in the way you are trying.

One way to hide the element's default content but get the pseudo-element's content to be displayed would be to set font-size: 0px on the element and then over-ride it to the required size within the pseudo-element's selector like in the below snippet:

a.button:before {
  content: "Show Text";
  font-size: 16px;
}
a.button {
  font-size: 0px;
}
<a href="#" class="button">Hide Text</a>

Note: As pointed out by Rob in his comments to the question, it is better to start using the :: (double colon) syntax for pseudo-elements going forward. Developers tend to stick with the : (single colon) version when IE8 support is required but with Microsoft themselves stopping support for it in Jan '16, it might be the right time to start using the double colon syntax. But choice is upto the developer, just in-case, you have a client who still needs IE8 support.

The below is what the Selectors Spec has to say about this:

A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.

This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.

like image 65
Harry Avatar answered Oct 24 '22 07:10

Harry