The only reliable way to create two mutually exclusive @media
blocks for any given media query is to use not
to negate it in one of the blocks. Unfortunately, this means repeating your media query once for each @media
block. So, instead of this for example:
@media (max-width: 49.9375em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
You would have this:
/*
* Note: Media Queries 4 still requires 'not' to be followed by a
* media type (e.g. 'all' or 'screen') for reasons I cannot comprehend.
*/
@media not all and (min-width: 50em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
Interactive jsFiddle demo
This is very effective at closing the gap with range media features like width
and height
since it essentially turns this into an either-or scenario. But, like your first two options, it isn't perfect: as mentioned, you have to repeat the same media query twice, and add not
to one of them. There is no if/else construct for @media
as described in Conditional Rules 3.
Although I mention this in my answer to your previous question:
From my experiments it would seem Safari on iOS rounds all fractional pixel values to ensure that either one of max-width: 799px
and min-width: 800px
will match, even if the viewport is really 799.5px (which apparently matches the former).
It should be noted, still, that I've noticed some quirks when it comes to rounding. That said, I haven't been able to find a fractional value that would evade both media queries and end up not receiving styles from either set of rules (which, by the way, is the worst that can happen, so don't worry about potentially creating a space-time rift). That must mean browsers — at least, Safari as I've tested — do a reasonable job of ensuring they satisfy media queries even if you have values that differ (by exactly 1 CSS pixel).
When it comes to units with larger gaps that can be observed on desktop browsers, though, like ems, there is a much larger margin of error. For example, one comment suggests using 49.99999em instead of something more arbitrary than 49.9375em, but apparently there is a difference, at least with a default font size of 16px.
I simplified your code, changed the media queries to use decimal values, and put the code in jsFiddle:
@media (max-width: 49.9375em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
If you resize the Result pane to exactly 800 pixels (the text will update to guide you along), you actually end up with different results depending on whether @media (max-width: 49.9375em)
is used, or @media (max-width: 49.99999em)
is used (I was surprised by this too)...
Either way, you're right: option 2 has its drawbacks too. I'm not particularly fond of it, to be honest, because I wouldn't want to crack my head over device and user agent quirks which are out of my control. If you're like me, I suppose it would be better to go through the inconvenience of redeclaring your rules at the cost (?) of being more vigilant around your code, as that's at least still within your control as an author.