5

I was playing with pseudo-elements styles and came across a behavior that puzzled me

Consider the following css and html

HTML:

 <p>
        Note: As a rule, double colons (::) should be used instead of a single colon (:). This distinguishes pseudo-classes from pseudo-elements. However, since this distinction was not present in older versions of the W3C spec, most browsers support both syntaxes for the sake of compatibility. Note that ::selection must always start with double colons ::.
    </p>

and styles

p::first-letter {
    font-size: 20px;
    color: red;
}

p::first-line {
    font-variant: small-caps;
    color: green;
}

p::before {
    content: 'Start';
    color: blue;
}

In Chrome the behavior is the following: First letter of ::before content is colored red even though its not content of p and ::before styles do not overwrite color to blue. enter image description here

Also when there is no letter in ::before content and I put & or * there - all first-line becomes green and no ::first-letter and ::before styles applied.

In Firefox the result of the code provided would be the following: enter image description here

I'm using latest browser versions under Ubuntu 17.04

So could anyone explain why ::before content is selected by other pseudo-elements selectors and there styles applied and why own ::before styles do not overwrite them even though they are "later" styles.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Olena Horal
  • 1,166
  • 3
  • 11
  • 26
  • The specificity for all selectors is 2. so I'd say the last one wins. But it does not – Olena Horal Jul 26 '17 at 11:57
  • No, my first letter is red and not blue – Olena Horal Jul 26 '17 at 12:00
  • ah apologies, misread your post haha will remove my comments :) – treyBake Jul 26 '17 at 12:11
  • 1
    Pseudo-elements contribute to selector specificity, but two rules with different pseudo-elements do not compete with each other, even when the rest of each selector is the same. So specificity isn't relevant here. This issue of ::first-line styles "overriding" ::before and ::after styles in Chrome is [not new](https://stackoverflow.com/questions/19867655/can-you-prevent-first-line-styles-from-applying-to-after-elements-in-opera-and), but there doesn't appear to be any discussion of this on the issue tracker or in www-style. – BoltClock Jul 26 '17 at 12:15

1 Answers1

3

As for the first line and first letter, this isn't really a problem of specificity. It's just specified like this:

As with the content of regular elements, the generated content of ::before and :after pseudo-elements may be included in any ::first-line and ::first-letter pseudo-elements applied to its originating element.

(source)

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Thanks, this does explain why styles of ::first-line and ::first-letter are applied. But why the last one (which is ::before) does not win? – Olena Horal Jul 26 '17 at 12:02
  • @OlenaHoral I'm unsure regarding this one. It looks like there's a lot of unspecified (or at least unclear) behavior when you style pseudo-elements because they're themselves existing as results of rules. – Denys Séguret Jul 26 '17 at 12:05
  • @OlenaHoral Don't accept my answer now in any case, your question deserves a better answer. – Denys Séguret Jul 26 '17 at 12:08
  • 2
    This is as good of an answer as it gets. The dreaded "may" wording (only made worse by the omission of fictional tag sequences for when ::before/::after is involved) means that no browser is either right or wrong. Chrome's behavior is closer to spec, but everyone else's behavior appears to be closer to author expectations, for some reason. IMO it makes no sense for only ::first-letter but not ::first-line to take precedence over ::before/::after styles. – BoltClock Jul 26 '17 at 12:26