CSS attribute selector + descendant gives a bug in

2019-02-16 14:45发布

问题:

Consider this CSS:

[data-color="red"] h1 {
background-color:red;
}

[data-color="blue"] h1 {
background-color:blue;
}

And this HTML:

<div data-color="red">
<h1>red</h1>
</div>

<div data-color="blue">
<h1>blue</h1>
</div>

<div data-color="blue">
<h1>blue</h1>
</div>

Now take a look at the following demo of the above code in Webkit and any other browser:
http://jsfiddle.net/aUCkn/

What's strange is that if you put each h1 on the same line, i.e.:

<div data-color="red"><h1>red</h1>
</div>

<div data-color="blue"><h1>blue</h1>
</div>

<div data-color="blue"><h1>blue</h1>
</div>

It works in Webkit too:
http://jsfiddle.net/aUCkn/1/

Does anyone know where this comes from? Am I doing something wrong or is Webkit acting stupid here?

回答1:

The first jsFiddle is broken in my Chrome 12.0.742.112 (stable).

However, it works in my Chrome 14.0.803.0 dev-m.

So, they're already aware of and have fixed the bug. You just have to wait for the fix to land in the stable channel.

I'll try to find a link to a bug report, if one exists.



回答2:

Try adding [_] {} to your CSS (doesn't matter where).

In reality, it can be any attribute selector rule, without a descendant clause, that will potentially match the attributed elements selected by the original selectors, i.e.: [data-color] {} and div[data-color] {} will fix the others, but a[data-color] {} will not fix it.

I've tested it on the posted fiddle (http://jsfiddle.net/aUCkn/) and it works for Safari (5.1.2).

My co-worker and I found it after playing with lots of random ideas for workarounds.



回答3:

When using Chrome (Webkit) I get this issue as well, though it seems to work fine in Firefox and IE9. It definitely appears to be a problem with Webkit that the extra whitespaces cause problems.



回答4:

--- UPDATE ---

This issue is fixed in Chrome as of version ~18, it continues to be an issue in other WebKit based browsers.

As far as solutions for this issue, Michael Morton's answer above is the best one here - it is more flexible and performant than mine. I have upvoted Michael's answer and suggest you use it.


Here's a CSS hack that fixes the issue: http://jsfiddle.net/aUCkn/101/

You just need to put * + before the selector. Now before you all grab your pitchforks and torches over the use of the star selector, remember that it is all the way to the left, so it shouldn't affect performance in any meaningful way ;)

PS - I can also confirm this bug affects ALL versions of ALL WebKit browsers on ALL platforms and devices - other than Chrome 14+. What an absolutely terrible bug, now the majority of WebKit browsers need to retract the claim they support even the now-ancient CSS2.1 spec. Wow, LOL.