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)!

+3


source to share


2 answers


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.

+14


source


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;
}

      



Example here

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.

+4


source







All Articles