CSS selector to check if an attribute does not contain both values
I have a rather strange CSS problem that I want to solve.
I'm looking for any html element that doesn't have display: none
(in any of its valid forms) embedded in an attribute style
.
Some examples:
-
<foo style="display:none" />
-
<foo style="display: none" />
-
<foo style="display : none" />
-
<foo style="display : none" />
-
<foo style="bar:baz; display:none" />
I have been :not()
tinkering with the negation alias , but the following selector seems to be invalid:
:not([style*='display'][style*='none'])
It doesn't look like you can combine other selectors within the same not()
I know that even if it worked it could create false positives for things like <foo style="border: none; display: inline" />
, but I'm fine with that.
So ... is there a way to do what I want other than hardcoding a bunch of options?
I really don't want to resort to this:
:not([style*='display:none']):not([style*='display :none']):not([style*='display: none']:not([style*='display : none']):not([style*='display: none'])...
Update:
The selector suggested in the comments ( :not([style*=display]):not([style*=none])
) won't actually work for me
Consider the following:
-
<p></p>
-
<p style=""></p>
-
<p style="border: none;"></p>
-
<p style="border: none;"></p>
-
<p style="display: inline;"></p>
-
<p style="border: none; display: inline"></p>
-
<p style="display: none;"></p>
-
<p style="display : none;"></p>
-
<p style="display :none;"></p>
:not([style*=display]):not([style*=none])
will only select the first 2 p
.
I want him to pick the top 6 (or top 5 if that's the best I can get)!
source to share
As you mentioned, you want something equivalent :not([style*='display'][style*='none'])
, which is not valid in CSS since it :not()
does not contain combined selectors.
The laws of logic help us here. Remember that !(a AND b) == !a OR !b
, therefore, we can write
:not([style*='display']), :not([style*='none'])
because in CSS a, b
matches elements that match a selector a
OR a selector b
.
Again, as said in the question, this does not take into account word order. The latter is not possible in CSS, since none of the CSS attribute selectors respect word order.
source to share
It would be better to do it with JavaScript ... but here is one possible CSS solution:
p:not([style*=display]):not([style*=none]),
p[style*=display]:not([style*=none]),
p[style*=none]:not([style*=display]),
p[style*=border][style*=none] {
color: red;
}
As you can see, this is a bit tedious. It covers most cases, including the ones you listed. The more cases you want to cover, the more selectors you will need.
source to share