What Happens If Multiple Classes of the Same Element Define a :Before Pseudo-Element

What happens if multiple classes of the same element define a :before pseudo-element?

The most specific selector takes precedence. This is mentioned in CSS2.1:

Pseudo-elements behave just like real elements in CSS with the exceptions described below and elsewhere.

In terms of actual browser behavior, as far as I know, this behavior is reliable on all browsers that support :before and :after on non-replaced elements like a, for which CSS2.1 does define behavior for those pseudo-elements, unlike replaced elements like img. This makes sense, because if more than one such pseudo-element were to be generated, the browser wouldn't know how it should lay them out in the formatting structure.

In the following example, by specificity and the cascade, a.inactive:before will take precedence and the :before pseudo-element for this link will have the matching content (since both selectors are equally specific — having a type selector, a class selector and a pseudo-element):



a.administrator:before {

content: '[Administrator] ';

}

a.inactive:before {

content: '[Inactive User] ';

}
<a class="administrator inactive" href="profile.php?userid=123">Username</a>

Can I have multiple :before pseudo-elements for the same element?

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.)

As a result, when you have multiple :before rules matching the same element, they will all cascade and apply to a single :before pseudo-element, as with a normal element. In your example, the end result looks like this:

.circle.now:before {
content: "Now";
font-size: 19px;
color: black;
}

As you can see, only the content declaration that has highest precedence (as mentioned, the one that comes last) will take effect — the rest of the declarations are discarded, as is the case with any other CSS property.

This behavior is described in the Selectors section of CSS2.1:

Pseudo-elements behave just like real elements in CSS with the exceptions described below and elsewhere.

This implies that selectors with pseudo-elements work just like selectors for normal elements. It also means the cascade should work the same way. Strangely, CSS2.1 appears to be the only reference; neither css3-selectors nor css3-cascade mention this at all, and it remains to be seen whether it will be clarified in a future specification.

If an element can match more than one selector with the same pseudo-element, and you want all of them to apply somehow, you will need to create additional CSS rules with combined selectors so that you can specify exactly what the browser should do in those cases. I can't provide a complete example including the content property here, since it's not clear for instance whether the symbol or the text should come first. But the selector you need for this combined rule is either .circle.now:before or .now.circle:before — whichever selector you choose is personal preference as both selectors are equivalent, it's only the value of the content property that you will need to define yourself.

If you still need a concrete example, see my answer to this similar question.

The legacy css3-content specification contains a section on inserting multiple ::before and ::after pseudo-elements using a notation that's compatible with the CSS2.1 cascade, but note that that particular document is obsolete — it hasn't been updated since 2003, and no one has implemented that feature in the past decade. The good news is that the abandoned document is actively undergoing a rewrite in the guise of css-content-3 and css-pseudo-4. The bad news is that the multiple pseudo-elements feature is nowhere to be found in either specification, presumably owing, again, to lack of implementer interest.

define pseudo class and pseudo element in same element

Interesting question. If you're able to show us a working example we could probably be of more help.

However, in theory there's nothing wrong with what you're attempting to do (although not all browsers will like it: particularly IE8 and below).

The important thing to understand here is that :hover is a pseudo-class, whereas :before is a pseudo-element.

Here's a quick excerpt from the standard (with thanks to this answer previously on Stack Overflow):

Pseudo-classes are allowed anywhere in selectors while pseudo-elements
may only be appended after the last simple selector of the selector.

The mistake you're making is in your syntax: the order that you're appending them.

Try this instead:

#sidebar .widget li a:hover:before,
#sidebar .widget li a.active:before {
background-position: 65% 65.7%;
}

That should do as you wish. However this isn't going to give you great cross-browser coverage, it's not something that all browsers support of have implemented.

A better approach would be to:

  • reset the :before element to nothing (overwrite the styles you can't access);
  • use a non-repeated background image on the anchor instead (to display the image), and padding-left to give the indentation;
  • You can then switch the background-image in whatever fashion you see fit using :hover on the anchor in your CSS.

This will give you far better cross-browser compatibility.

How to use the CSS pseudo element :before in multiple classes of same element

Here you are SIR

demo: http://jsfiddle.net/7UjgL/

the style:

.letter{
width:40px;
height:20px;
position:relative;
letter-spacing: 26px;
}

.letter:first-letter{
color:red;
}

.letter:before,.letter:after{
position:absolute;
top: 0px;
}
.letter:before{
content: 'o';
color: green;
left: 11px;
}

.letter:after{
content:'n';
color:blue;
left: 22px;
}

the markup:

<div class=letter>ze</div>

How could I use pseudo-element :after :before conditionally

In general it is not possible to select elements based on their next sibling.

In your specific case, you can use ul li a:not(:last-child)::after, because it happens that your anchors that are not followed by an <ul> element are also the last child element.

Can I use multiple pseudo selectors focus with before/after on the same element?

Pseudo elements can only be defined on container elements. Because of the way they are rendered within the container itself as a DOM element. inputs cannot contain other elements hence they're not supported. A button on the other hand, although a form element, supports them because it's a container of other sub elements.

More from the 2.1 spec

The ::after and ::before pseudo-elements are now using the double-colon to avoid confusion with pseudo-classes (which obviously use :), although older version of IE (7,8) won't recognize the double colons .. keep that in mind if your trying to support them.



Related Topics



Leave a reply



Submit