jeudi 13 août 2015

Interaction of pseudo-elements with :not pseudo-class

Short version:

Using Chrome, I noticed that the selector

#main-content p:first-of-type::first-letter:not(.subhead) { ... }

seems to fail to apply first-letter styles regardless of the class of the paragraph, but if I place the :not pseudo-class earlier, as in either of

#main-content p:first-of-type:not(.subhead)::first-letter { ... }
#main-content p:not(.subhead):first-of-type::first-letter { ... }

then it works as I would expect. Is this an issue in Chrome, or is there some aspect of CSS selectors which explains this, that I just don't understand?

(Additionally, if it's not just an issue in Chrome, can someone suggest a better title for this question?)


Long version:

The short version seems like a good self-contained question to lead with, but there's some more complicated background info which might have its own interesting ramifications. (And which might warrant its own separate question, or be another bug. Help very much appreciated???)

Originally I was trying to apply initial drop-caps to the first paragraph in a div and any subsequent paragraphs that immediately followed a horizontal rule, unless they were part of a subheading. Here's a highly-abbreviated mock of the page structure:

<div id="main-content">
<section class="panel">
  <header>
    <h1>Welcome Friend!</h1>
    <p class="subhead">This is a subheader! (0)</p>
  </header>
  <div class="customhr"></div> <!-- consciously NOT an hr tag -->
  <p>Here's a paragraph (1)</p>
  <hr>
  <p>First paragraph of a new content section (2)</p>
  <p>And another paragraph. (3)</p>
</section>
</div>

And the extremely-abbreviated CSS:

#main-content p:first-of-type::first-letter,
#main-content hr + p::first-letter {
  /* Drop-cap styles */
}
.subhead::before {
  /* Indent sub-headings with a cute fleuron */
  content: "\00a0\00a0\2767\00a0";
}

While testing in Firefox, this resulted in paragraphs (1) and (2) having drop-caps, which is what I desired. In Chrome however, the fleuron from the ::before rule for paragraph (0) also has the drop-cap styles applied. I'm fairly confident Firefox is in error here, as :first-letter should match text from the ::before pseudo-element if it is present, but instead the ::before causes :first-letter not to match anything.

In trying to fix it for Chrome, I added the :not pseudo-class to the end of the first selector (see the first CSS rule in the short version). In Firefox, ironically, this produces the desired effect just as before, but in Chrome, this now caused paragraph (1) to no longer have the drop-cap styles applied. That, I have no explanation for, but I determined it has nothing to do with the .subhead element; Chrome apparently just never applies the rule, and paragraphs following a horizontal rule are the only ones that get styled. But if I move the :not pseudo-class earlier in the rule, as in the two alternatives I gave in the short version, it once again works as expected.

I feel as though I somehow simultaneously stumbled onto two different bugs in Firefox and Chrome, but the use of pseudo-classes and pseudo-elements is slightly arcane to me and I'm not fully confident with them. So I'm curious a) whether there's anything in-spec that would explain this CSS behavior in either browser as being correct, and b) if not, whether these are already known bugs with consistent behavior that has been documented somewhere. [And c) if not, let me know whether you plan to report said bugs so that I don't accidentally file a duplicate.]



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire