Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I override existing pseudo-elements?

I have two CSS rules following each other:

.some td:first-child:before {
    content:url('path/to/image.png')" " ;
}
.some .other:before {
    content:url('path/to/image2.png')" " ;
}

Here's the HTML snippet:

<table class="some">
<tr>
    <td class="other">Text goes here</td>
    <td>Some more text.</td>
</tr>
</table>

They're both supposed to be applied to the same table cell. The one without the class is meant as a fallback. But for some reason, it's always choosing the first rule over the second. I know the 2nd one works, since it will be used if i disable the first one in Firebug.

What am I missing here?

like image 286
DanMan Avatar asked Apr 07 '12 15:04

DanMan


People also ask

How do you change pseudo element?

In general, if we want to change anything in pseudo elements through JavaScript, we do it in the following way: Create CSS classes on element, which will change pseudo elements' UI. Get the element using querySelector. Modify the classes using classList.

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

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

Can pseudo elements and pseudo-classes be combined?

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.

Can you have multiple pseudo elements?

Multiple pseudo-elements can be created with the ::before(ordinal) and ::after(ordinal) notation, where 'ordinal' is a positive integer. ::before pseudo-elements are ordered descending by 'ordinal' from the host element's content edge.


2 Answers

Ok, to put this straight, after some reading, this is the specificity:

  • Id: 100
  • classes: 10
  • pseudo-classes: 10
  • pseudo-elements: 1
  • elements: 1

So that makes the first selector have a specificity of 22, and the 2nd of just 21. Apparently first-child seems to be a pseudo-class and not a pseudo-element.

Finally, adding a td before .other does the trick, since then document order takes precedence.

like image 134
DanMan Avatar answered Sep 28 '22 08:09

DanMan


The first rule is more specific than the second one, so in a case when both the selectors are valid, the more specific one overrides other.

Read this article to know how can we overcome such complications of having conflicting styles. To brief them, Here is how specificity are calculated.

+--------------------+--------------------+-----------------------------------+
|    Type            |   Specific Value   |  Example                          |
+--------------------+--------------------+-----------------------------------+
|  Inline Style      |   1000             | style="color: #f00;"              |
+--------------------+--------------------+-----------------------------------+
|  Id                |   100              | #text { color: #f00; }            |
+--------------------+--------------------+-----------------------------------+
|  Classes           |   10               | .text { color: #f00; }            |
+--------------------+--------------------+-----------------------------------+
|  Pseudo Classes    |   10               | a:hover { color: #f00; }          |
+--------------------+--------------------+-----------------------------------+
|  Pseudo Elements   |   10               | a:first-child { color: #f00; }    |
+--------------------+--------------------+-----------------------------------+
|  Elements (tag)    |   1                | a { color: #f00; }                |
+--------------------+--------------------+-----------------------------------+

Basically, Class Selectors are more specific than tag selectors. Lets calculate your specificity

  • For first rule: 31
  • For second rule: 30

SO the first rule wins.

You can increase the specificity of the second rule like

.some tr td.other:before {
    content:url('path/to/image2.png') ;
}

Its calculate to 33, to override the style first rule.

like image 39
Starx Avatar answered Sep 28 '22 08:09

Starx