I have a pretty odd CSS problem I want to solve.
I'm looking for any html element which does not have display: none
(in any of its valid forms) inline in a style
attribute.
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've been tinkering with the :not()
negation pseudo-class but the following selector is apparently invalid:
:not([style*='display'][style*='none'])
It doesn't look like you can combine other selectors within a single not()
I know that even if it worked, this could potentially create false positives for things like <foo style="border: none; display: inline" />
, but I'm somewhat OK with that.
So... is there any way to do what I want aside from hard-coding a bunch of the variations?
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'])...
The selector suggested in the comments (:not([style*=display]):not([style*=none])
) will not 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
's.
I want it to select the first 6 (or top 5 if thats the best I can get)!
As you mentioned, you want something equivalent to :not([style*='display'][style*='none'])
, which is invalid in CSS, since :not()
allows no combined selectors.
The laws of logic help us out here. Remember that !(a AND b) == !a OR !b
, so we can write
:not([style*='display']), :not([style*='none'])
since in CSS, a, b
matches elements that satisfy selector a
OR selector b
.
Again, as said in the question, this does not take the order of the words into consideration. The latter is impossible in CSS, since none of the CSS attribute selectors consider word order.
It would clearly be better to do this 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;
}
Example Here
As you can see, it is a little tedious. It covers a majority of cases, including the ones you listed. The more cases you want to cover, the more selectors you would need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With