Cutting the Mustard is a term coined by Tom Maslen at the BBC. The method uses JavaScript that checks for browser capabilities before loading further CSS and JavaScript to give the user an ‘enhanced’ experience, otherwise the browser will only load the files necessary for a ‘core’ experience.
切芥末酱是汤姆·马斯伦(Tom Maslen)在英国广播公司(BBC)创造的一个术语。 该方法使用JavaScript来检查浏览器功能,然后再加载CSS和JavaScript,以为用户提供“增强”的体验,否则浏览器将仅加载“核心”体验所需的文件。
There has been a flurry of interest in cutting the mustard of late, for example Migrating to Flexbox by Cutting the Mustard and Server Side Mustard Cut, and in Progressive Enhancement in general.
最近,人们对切割芥末产生了浓厚的兴趣,例如,通过切割芥末和服务器端芥末切割 来迁移到Flexbox以及总体上进行逐步增强 。
In my experience, however, even a very basic ‘core’ experience can cause problems on some very old browsers, so I wanted to build on this idea and see if it was possible to deny really old browsers any CSS at all, leaving them with only the HTML.
但是,以我的经验来看,即使是非常基本的“核心”体验也会在某些非常老的浏览器上引起问题,因此我想以此为基础,看看是否有可能完全拒绝真正的老浏览器使用任何CSS,而将它们保留下来。只有HTML。
Of course, the obvious solution is to use JavaScript to conditionally load all the CSS if the browser cuts the mustard, but this felt too heavy-handed for my liking; modern, capable browsers that didn’t load the JavaScript would be penalised by having no styles at all. So I looked for a CSS-only approach to the problem and I found an old post by Craig Buckler. After a fair bit of experimentation and adaptation, I came up with this:
当然,显而易见的解决方案是使用JavaScript来在浏览器切芥末的情况下有条件地加载所有 CSS,但这对我来说实在是太笨拙了。 现代化的,功能强大的,不加载JavaScript的浏览器将因为完全没有样式而受到惩罚。 因此,我寻找了一种仅CSS的方法来解决该问题,并且发现了Craig Buckler的一篇旧文章 。 经过大量的试验和调整,我想到了:
<!-- in the <head> --> <link rel="stylesheet" href="css/your-stylesheet.css" media="only screen and (min-resolution: 0.1dpcm)"> <link rel="stylesheet" href="css/your-stylesheet.css" media="only screen and (-webkit-min-device-pixel-ratio:0) and (min-color-index:0)">Let’s examine what’s happening here.
让我们检查一下这里发生了什么。
The first <link> element’s media query allows the stylesheet to load only in the following browsers:
第一个<link>元素的媒体查询允许样式表仅在以下浏览器中加载:
IE 9+ IE 9+ FF 8+ FF 8+ Opera 12 歌剧12 Chrome 29+ Chrome29+ Android 4.4+ Android 4.4以上The second <link> element’s media query allows the stylesheet to load only in:
第二个<link>元素的媒体查询允许样式表仅加载到:
Chrome 29+ Chrome29+ Opera 16+ 歌剧16+ Safari 6.1+ Safari 6.1+ iOS 7+ iOS 7以上 Android 4.4+ Android 4.4以上When combined, this technique will not load the stylesheet unless the browser is:
结合使用时,除非浏览器为:否则,此技术将不会加载样式表。
IE 9+ IE 9+ FF 8+ FF 8+ Opera 12, 16+ Opera 12、16+ Chrome 29+ Chrome29+ Safari 6.1+ Safari 6.1+ iOS 7+ iOS 7以上 Android 4.4+ Android 4.4以上Note: the stylesheet is only loaded once no matter how many <link> elements there are.
注意:样式表仅加载一次,无论有多少<link>元素。
It’s possible to combine the media queries into one link element by separating the declarations with a comma, like so:
通过用逗号分隔声明,可以将媒体查询组合到一个链接元素中,如下所示:
<link rel="stylesheet" href="css/your-stylesheet.css" media="only screen and (min-resolution: 0.1dpcm), only screen and (-webkit-min-device-pixel-ratio:0) and (min-color-index:0)">However, I personally like to keep them separate as I find it easier to see what’s going on.
但是,我个人喜欢将它们分开,因为我发现更容易看到正在发生的事情。
So if you structure your markup in a semantic and accessible way, older browsers should still be able to see your un-styled content in plain HTML.
因此,如果您以语义和可访问的方式构造标记,则较旧的浏览器仍应能够以纯HTML格式查看未样式化的内容。
This is of course very opinionated, but it’s my view that anyone using these browsers still deserves to be able to get to what they need. It’s quite likely that by giving these browsers CSS intended for newer browsers, some things will just break, and that could mean a totally unusable page. Using this method they at least get a clean slate. More importantly, you’ll never need to test in those browsers again. You’re done with them! At least, that’s the theory.
当然,这是很自以为是的,但是我认为,使用这些浏览器的任何人仍然应该能够获得所需的东西。 通过为这些浏览器提供旨在用于较新的浏览器CSS,很可能会破坏某些事情,这可能意味着页面完全无法使用。 使用这种方法,他们至少会得到一个干净的状态。 更重要的是, 您无需再在这些浏览器中进行测试 。 你已经完成了! 至少,这就是理论。
Of course, your support needs are likely to vary, but the great thing about this technique is that you can build on it. For example, if you need to add support for IE8, you can use a conditional comment to load the same stylesheet only for that browser:
当然,您的支持需求可能会有所不同,但是此技术的妙处在于您可以在此基础上进行构建。 例如,如果您需要添加对IE8的支持,则可以使用条件注释仅为该浏览器加载相同的样式表:
<!--[if IE 8]> <link rel="stylesheet" href="css/your-stylesheet.css"> <![endif]-->Or, if you need to support older WebKit devices with a pixel ratio of greater than 1, you could add another <link> element with a targeted media query, like this:
或者,如果您需要支持像素比率大于1的旧版WebKit设备,则可以添加另一个<link>元素和目标媒体查询,如下所示:
<link rel="stylesheet" href="css/your-stylesheet.css" media="only screen and (-webkit-min-device-pixel-ratio:1.1)">By itself, this will load the stylesheet only for Android 2.2+ (I wasn’t able to test earlier versions), but since it’s included in addition to the other <link> elements, it’s effectively just adding support for this other group of browsers.
就其本身而言,这只会加载适用于Android 2.2+的样式表(我无法测试较早的版本),但是由于除其他<link>元素之外还包括该样式表,因此实际上只是添加了对另一组浏览器的支持。
It’s also possible that you can alter the main <link> element’s media queries from how I’ve presented them here to get the custom support you need. However, it took quite a lot of testing to get this right, so be warned!
您也可以根据我在此处介绍的方式更改主要<link>元素的媒体查询,以获得所需的自定义支持。 但是,需要花费大量的时间才能正确地完成此操作,因此请注意!
Yes, I suppose they are, though that depends on your definition. Media Queries are designed to test the capabilities of the browser before applying the CSS, and that’s exactly what we want to do in this case, albeit indirectly.
是的,我想是的,尽管这取决于您的定义。 媒体查询旨在在应用CSS之前测试浏览器的功能,这正是我们在这种情况下想要做的,尽管是间接的。
Still, hack or not, I’m pleased with this technique and it’s been working well for me in all the testing I’ve done so far, and I plan to use it on a production site soon.
尽管如此,无论是否受到黑客攻击,我都对这种技术感到满意,并且到目前为止,在我进行的所有测试中,该技术一直很好,我计划很快在生产现场使用它。
In all my testing to date, I’ve found only one case where things don’t work as expected. On Android 4.4 the UC Browser doesn’t respond to the media query. From what I can tell, the UC Browser uses an older version of WebKit, which would explain things.
迄今为止,在我所有的测试中,我仅发现一种情况无法按预期进行的情况。 在Android 4.4上,UC浏览器不响应媒体查询。 据我所知,UC浏览器使用的是WebKit的较旧版本,它将解释一些问题。
If you want to support this browser, it’s possible to resort to a little user agent sniffing to force the CSS to load:
如果您想支持此浏览器,可以通过一点用户代理嗅探来强制CSS加载:
if (navigator.userAgent.indexOf('UCBrowser') > -1) { var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'css/your-stylesheet.css'; document.getElementsByTagName('head')[0].appendChild(link); }As a bonus, as far as I can tell there’s no way to disable JavaScript in the Android UC Browser, so the stylesheet should always be loaded, barring network failures and such.
另外,据我所知,无法在Android UC浏览器中禁用JavaScript,因此应始终加载样式表,除非出现网络故障等。
Of course, if you find there are other specific browsers you need to support, you can always add to the user agent sniff condition but I caution you to use it sparingly as it defeats the purpose of this being a CSS-only technique.
当然,如果您发现需要支持其他特定的浏览器,则可以始终将其添加到用户代理嗅探条件中,但是我告诫您谨慎使用它,因为它违反了仅CSS技术的目的。
I’ve made a test page to test the base method on different browsers. If you find any browsers where things don’t work as expected, or if you find any other Media Queries that can add support for a particular browser or range of browsers, please let me know in the comments or raise an issue on the GitHub repository.
我制作了一个测试页面,以测试不同浏览器上的基本方法。 如果您发现任何浏览器无法正常工作,或者发现任何其他可以添加对特定浏览器或一系列浏览器的支持的媒体查询,请在评论中让我知道或在GitHub存储库上提出问题。
Ok, so if you’re using CSS to detect browser support, there’s a good chance you’ll want to load or run some or all of your scripts only in browsers that you’re supporting. So how do we do that?
好的,因此,如果您使用CSS来检测浏览器支持,则很有可能只在支持的浏览器中加载或运行部分或全部脚本。 那么我们该怎么做呢?
Well, there are several ways this can be achieved, but the simplest one I’ve found works like this:
好吧,有几种方法可以实现,但是我发现的最简单的方法是这样的:
In your stylesheet, insert a harmless, non-default CSS property on the body element.
在样式表中,在body元素上插入无害的非默认CSS属性。
Use JavaScript and getComputedStyle on the body element to determine if your property is set.
在body元素上使用JavaScript和getComputedStyle确定是否设置了属性。
If it is, run or load your other JavaScript. 如果是这样,请运行或加载其他JavaScript。For example, the clear property has a default value of none. Setting it to both on the body is unlikely to have any impact on the display of your page (if it does then you’ll have to use a different property). So the code would look like this in your stylesheet:
例如, clear属性的默认值为none 。 将其both设置为body不会对页面的显示产生任何影响(如果确实如此,则必须使用其他属性)。 因此,代码在样式表中将如下所示:
body { clear: both; }And on your page (or in a script file):
在您的页面上(或在脚本文件中):
var is_supported = false , val = ''; if (window.getComputedStyle) { val = window.getComputedStyle(document.body, null).getPropertyValue('clear'); } else if (document.body.currentStyle) { val = document.body.currentStyle.clear; } if (val == 'both') { is_supported = true; }Hacky or not, what I’ve tried to show here is a reusable way to detect a relatively modern browser and to prevent older browsers from applying styles or running scripts, causing them to display only the HTML of your page. The code required is quite minimal and it should allow you to concentrate your efforts on building wonderful things for more modern browsers using more modern techniques without worry.
是否受到黑客攻击,我试图在这里展示的是一种可重用的方法,用于检测相对较新的浏览器并防止较旧的浏览器应用样式或运行脚本,从而使它们仅显示页面HTML。 所需的代码非常少,它应该使您能够集中精力使用更现代的技术为更现代的浏览器构建精彩的东西。
Although you may not need everything I’ve presented here, putting all the pieces together gives us this:
尽管您可能不需要我在这里介绍的所有内容,但将所有内容放在一起可以得到以下结果:
<head> <link rel="stylesheet" href="mq-test.css" media="only screen and (min-resolution: 0.1dpcm)"> <link rel="stylesheet" href="mq-test.css" media="only screen and (-webkit-min-device-pixel-ratio:0) and (min-color-index:0)"> <link rel="stylesheet" href="mq-test.css" media="only screen and (-webkit-min-device-pixel-ratio:1.1)"> <!--[if IE 8]> <link rel="stylesheet" href="mq-test.css"> <![endif]--> <script> if (navigator.userAgent.indexOf('UCBrowser') > -1) { var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'mq-test.css'; document.getElementsByTagName('head')[0].appendChild(link); } </script> </head> <body> <!-- content here... --> <script> var is_supported = false , val = ''; if (window.getComputedStyle) { val = window.getComputedStyle(document.body, null).getPropertyValue('clear'); } else if (document.body.currentStyle) { val = document.body.currentStyle.clear; } if (val == 'both') { is_supported = true; } if (is_supported) { // Load or run JavaScript for supported browsers here. } </script> </body>I’ve made another test page with all of the extras.
我用所有其他内容制作了另一个测试页 。
I couldn’t have done this without the use of BrowserStack, Can I Use and the work of the folks at Browserhacks and Jeff Clayton, so thanks to all those involved, and please let me know if you have any thoughts or feeback.
如果没有使用BrowserStack , 我可以使用以及Browserhacks和Jeff Clayton的同事们的工作, 我 做不到 ,因此感谢所有相关人员,如果您有任何想法或想法,请告诉我。
翻译自: https://www.sitepoint.com/cutting-the-mustard-with-css-media-queries/