如何避免媒体查询重叠? [英] How can I avoid media query overlap?

查看:126
本文介绍了如何避免媒体查询重叠?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

级联是什么使CSS特别和强大。但在媒体查询的情况下,重叠可能似乎有问题。



考虑以下CSS(继续 CSS媒体查询重叠):

  / *标准 - 对于20em以下的所有屏幕* / 

body {color:black; font-size:1em; }

/ *查询A - 稍宽的移动视口* /

@media(min-width:20em)and(max-width:45em){
body {color:red; } / *应该对于这个宽度是唯一的* /
}

/ *查询B - 所有其他* /

@media(min-width:45em ){
body {font-size:larger; } / *因为视口更大* /
}

宽,45em的重叠将根据标准CSS级联处理




  • 首先应用所有 max-width:45em 定义,

  • min-width:45em






  • 所有文本通常都是 black ,但 / em>是唯一的,并且具有 color:red

  • 由于查询B 适用于较大的视口,因此其文字有CSS font-size:larger



因此,在正好45em的宽度上,我们会得到大和红色文字






我看到两种可能性:


  1. 重新声明文字在中的 color:black 查询B ,但是如果您以后选择更改 color ,那么您将管理两个声明。 (当然,这一行代码不是这样的问题,但想象还有很多其他声明和选择器。)


  2. 使用pixel避免重叠像 max-width:799px min-width:800px 的值,但是你使用像素它们可以分别是49.9375em和50em。虽然如果默认不再是16em,什么东西被四舍五入?我们仍然不确定在该差距发生了什么。 (打破时空连续体的黑洞?)


两者都有自己的缺点...任何其他想法?

解决方案

创建两个互斥 @任何给定媒体查询的媒体块是使用而不是在其中一个块中取消它。不幸的是,这意味着对于每个 @media 块重复您的媒体查询一次。所以,而不是这个例子:

  @media(max-width:49.9375em){ 
body {
color:red;
}
}

@media(min-width:50em){
body {
font-size:larger;
}
}

您将有:

  / * 
*注意:Media Queries 4仍然需要'not'后跟
*媒体类型(例如全部或屏幕),因为我不能理解。
* /
@media不全部和(min-width:50em){
body {
color:red;
}
}

@media(min-width:50em){
body {
font-size:larger;
}
}

交互式jsFiddle演示



这是非常有效的缩小范围媒体功能,如 width height ,因为它本质上把这变成一个或者场景。但是,像你的前两个选项一样,它不是完美的:如上所述,你必须重复相同的媒体查询两次,并添加到其中之一。没有 @media 的if /媒体rel =nofollow>条件规则3






虽然我在我的回答您之前的问题:


根据我的实验,iOS上的Safari会将所有分数像素值舍入,以确保 max-width:799px min-width:800px 将匹配,即使视口真的是799.5px )。


应该注意的是,当我谈到舍入时我注意到一些怪癖。也就是说,我没有能够找到一个小数值,可以逃避媒体查询,并最终没有从任何一组规则(这是顺便说一下,是最糟糕的发生,所以不要担心可能会造成时空裂口)。这必定意味着浏览器 - 至少,我测试过的Safari - 做一个合理的工作,确保他们满足媒体查询,即使你有不同的值(正好1个CSS像素)。



当涉及到可以在桌面浏览器上观察到的更大间隙的单位,虽然像ems,有一个更大的误差范围。例如,一个评论建议使用49.99999em而不是比49.9375em更任意的东西,但显然有一个差异,至少默认的字体大小为16px。



我简化了你的代码,改变媒体查询使用十进制值,并将代码放在jsFiddle:

  @media(max-width:49.9375em){
body {
color:red;
}
}

@media(min-width:50em){
body {
font-size:larger;
}
}



如果您将结果窗格调整为正好800像素文字会更新以指导您),实际上最终会得到不同的结果,具体取决于 @媒体(最大宽度:49.9375em)被使用,或 @media(max-width:49.99999em)使用(我也很惊讶)...



无论如何,你是对的:选项2也有它的缺点。我不是特别喜欢它,说实话,因为我不想破解我的头超过设备和用户代理怪异,这是我的控制。如果你像我一样,我认为最好是通过重新声明你的规则带来的不便,代价是更加谨慎,因为这至少仍然是作者的控制。 p>

The cascade is what makes CSS special and powerful. But in the case of media queries, overlap can seem problematic.

Consider the following CSS (continuing rules for CSS media query overlap):

/* Standard - for all screens below 20em */

body { color: black; font-size: 1em; }

/* Query A - slightly wider, mobile viewport */

@media (min-width: 20em) and (max-width: 45em) {
    body { color: red; } /* supposed to be unique for this width */
}

/* Query B - everything else */

@media (min-width: 45em) {
    body { font-size: larger; } /* because viewport is bigger */
}

So when the screen is exactly 45em wide, the overlap at 45em will be treated according to the standard CSS cascade:

  • All max-width: 45em definitions will be applied first,
  • and all min-width: 45em will be applied thereafter.

Consider these two conditions:

  • All text would normally be black, but Query A is unique and has color: red.
  • Since Query B is for larger viewports, it's text has the CSS font-size: larger.

Therefore, at a width of exactly 45em, we'd get big and red text. What would be the best solution to avoid this?


I see two possibilities:

  1. Re-declare the text to have color: black in Query B, but then you're managing two declarations if you choose to change the color in the future. (Of course, not such a problem with this single line of code, but imagine there's a lot of other declarations and selectors.)

  2. Avoid overlap by using pixel values like max-width: 799px and min-width: 800px, but then you're using pixels — I guess they could be 49.9375em and 50em, respectively. Though what if the default is no longer 16em and something gets rounded? And we're still not certain what happens at that gap. (A black hole that breaks the space-time continuum?)

Both have their drawbacks... any other ideas?

解决方案

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.

这篇关于如何避免媒体查询重叠?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆