To figure out why the not
operator might not be working with and
and/or or
operators in your CSS @supports
query, you can check for the following:
Check for Missing Whitespace
Whitespace is required after not
and on both sides of and
or or
. Therefore, as a first step, please make sure you're following the correct syntax.
Check for Invalid Use of Parentheses
A layer of parentheses must be added when mixing and
, or
, and not
operators based on the following rules:
- When combining
and
andor
you must wrap them in parentheses to define the order in which they apply, otherwise the whole rule is ignored; - When using
not
withand
oror
, you must wrap the entirenot
expression in parentheses (unless it exists on its own at the top level). Otherwise, the whole rule is ignored.
Keeping that in view, consider the following examples:
Combining not
With and
:
To check if one property/value is supported while the other is not, you can do the following:
@supports (...) and (not (...)) { /* ... */ }
Notice the use of parentheses around the whole not
expression. You may reverse the order of the two expressions, but you will still have to wrap the entire not
expression in parentheses. For example:
@supports (not (...)) and (...) { /* ... */ }
You may negate an entire expression (in which case you do not need to wrap the not
within parentheses, as it exists on its own at the top level):
@supports not ((...) and (...)) { /* ... */ }
Combining not
With or
:
Same rules apply as with combining not
with and
. For example, to check if a property/value pair exists, or another pair that does not exist, you can do something like the following:
@supports (...) or (not (...)) { /* ... */ }
Notice the use of parentheses around the whole not
expression. You may reverse the order of the two expressions, but you will still have to wrap the entire not
expression in parentheses. For example:
@supports (not (...)) or (...) { /* ... */ }
You may negate an entire expression (in which case you do not need to wrap the not
within parentheses, as it exists on its own at the top level):
@supports not ((...) or (...)) { /* ... */ }
Mixing not
, and
and or
:
When mixing an arbitrary number of conjunctions (and
), disjunctions (or
), and/or negations (not
) in a single @supports
query, you need to make sure you use parentheses correctly. In the following example for instance, either the first expression containing not
and and
should be true, or the second expression:
@supports ((not (...)) and (...)) or (...) { /* ... */ }
Based on the rules about parentheses, in the example above you can see:
- How the
not
expression is wrapped in parentheses (as it is being mixed with theand
operator), and; - How the first expression itself is wrapped in parentheses to define the order of precedence between the conjunction (
and
) and disjunction (or
).
Similarly, you can combine not
and or
as well. For example, in the following @supports
query, the first expression containing not
and or
should be true, as well as the second expression:
@supports ((not (...)) or (...)) and (...) { /* ... */ }
However, when the not
operator exists on its own at the top level, you do not need to wrap the negation in parentheses (as shown below):
@supports not ((...) and ((...) or (...))) { /* ... */ }
Check for Browser Support
If the first two steps don't resolve the problem for you, then it could be that the browser you're testing on does not support @supports
. Have a look at the browser support chart for @supports
to be sure.
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.