{"action":"opened","issue":{"url":"https://api.github.com/repos/cssmagic/CSS-Secrets/issues/12","labels_url":"https://api.github.com/repos/cssmagic/CSS-Secrets/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/cssmagic/CSS-Secrets/issues/12/comments","events_url":"https://api.github.com/repos/cssmagic/CSS-Secrets/issues/12/events","html_url":"https://github.com/cssmagic/CSS-Secrets/issues/12","id":107466506,"number":12,"title":"[译] [404] [#18] 毛玻璃效果","user":{"login":"cssmagic","id":1231359,"avatar_url":"https://avatars.githubusercontent.com/u/1231359?v=3","gravatar_id":"","url":"https://api.github.com/users/cssmagic","html_url":"https://github.com/cssmagic","followers_url":"https://api.github.com/users/cssmagic/followers","following_url":"https://api.github.com/users/cssmagic/following{/other_user}","gists_url":"https://api.github.com/users/cssmagic/gists{/gist_id}","starred_url":"https://api.github.com/users/cssmagic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cssmagic/subscriptions","organizations_url":"https://api.github.com/users/cssmagic/orgs","repos_url":"https://api.github.com/users/cssmagic/repos","events_url":"https://api.github.com/users/cssmagic/events{/privacy}","received_events_url":"https://api.github.com/users/cssmagic/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/cssmagic/CSS-Secrets/labels/%E8%AF%95%E8%AF%BB%E6%A0%B7%E7%AB%A0","name":"试读样章","color":"159818"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-09-21T08:38:48Z","updated_at":"2015-09-21T08:38:48Z","closed_at":null,"body":"***\r\n\r\n> 本文是早期译版，未经校审。仅供参考。\r\n\r\n***\r\n\r\n# Frosted glass effect\r\n# 毛玻璃效果\r\n\r\n> #### Prerequisites\r\n\r\n> * RGBA/HSLA colors\r\n\r\n> #### {prerequisite}\r\n\r\n> * RGBA/HSLA 颜色\r\n\r\n## The problem\r\n## 难题\r\n\r\n> {原书注释!}\r\n\r\n> We are using the term “backdrop” here to mean **the part of the page that is underneath an element**, which shows through its semi-transparent background.\r\n> \r\n> 我们在这里用了 “背层（backdrop）” 一词，它表示**页面被某个上层元素遮住的部分**，这部分区域透过该元素的半透明背景显现出来。\r\n\r\nOne of the first use cases of semi-transparent colors was using them as backgrounds, over photographic or otherwise busy backdrops, to decrease contrast and make the text possible to read. The result is quite impressive, but can still be hard to read, especially with very low opacity colors and/or busy backdrops. For example, take a look at **Figure XX.XX**, where the main element has a semi-transparent white background. The markup looks like this:\r\n\r\n半透明颜色最初的使用场景之一就是把它们作为背景，当叠放在照片类或其它花哨的背层之上时，可以减少对比度，确保文本的可读性。这种效果确实很有视觉冲击力，但仍然可能导致文字很难阅读，特别是当颜色的透明度较低或底层太过花哨时。举个例子，我们来看看 **图 4.14**，图中 `main` 元素的背景是半透明的白色。结构大致是这样的：\r\n\r\n```html\r\n<main>\r\n\t<blockquote>\r\n\t\t“The only way to get rid of a temptation[...]”\r\n\t\t<footer>--\r\n\t\t\t<cite>\r\n\t\t\t\tOscar Wilde,\r\n\t\t\t\tThe Picture of Dorian Gray\r\n\t\t\t</cite>\r\n\t\t</footer>\r\n\t</blockquote>\r\n</main>\r\n```\r\n\r\nAnd the CSS looks like this (with all irrelevant bits omitted for brevity):\r\n\r\n而 CSS 代码可能是这样的（简短起见，这里只列出了关键样式）：\r\n\r\n```css\r\nbody {\r\n\tbackground: url(\"tiger.jpg\") 0 / cover fixed;\r\n}\r\n\r\nmain {\r\n\tbackground: hsla(0,0%,100%,.3);\r\n}\r\n```\r\n\r\n> ##### 图 4.14\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.14.png)\r\n\r\n> Our semi-transparent white background makes the text hard to read\r\n> \r\n> 半透明白色背景使文字很难阅读。\r\n\r\nAs you can observe, the text is really hard to read, due to the image behind it being busy and the background color only being 25% opaque. We could of course improve readability by increasing the alpha parameter of the background color, but then the effect will not be as interesting (see **Figure XX.XX**).\r\n\r\n相信你可以察觉出来，文字确实难以看清，因为它后面的图片太过花哨了，而它的背景色只有 25% 的不透明度。当然我们可以通过提升背景色的不透明度来增加文本的可读性，不过这样一来整个效果就没有那么生动了（参见 **图 4.15**）。\r\n\r\n> ##### 图 4.15\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.15.png)\r\n\r\n> Increasing the alpha value of our background color does fix the readability issue, but also makes our design less interesting\r\n> \r\n> 增加背景色的 alpha 值（不透明度）可以改善文本可读性的问题，但同时也让整个设计变得无趣了。\r\n\r\nIn traditional print design, this issue is often addressed by **blurring the part of the photo that is underneath our text container**. Blurred backgrounds are not as busy, and thus, text on them is easier to read. Because blurring is computationally expensive, in the past its toll on resources was prohibitive for using this technique in websites and UI design. However, with GPUs improving and hardware acceleration becoming more commonplace for more and more things, these days it’s used quite frequently. In the past few years, we have seen this technique in newer versions of both Microsoft Windows, as well as Apple iOS and Mac OS X (**Figure XX.XX**).\r\n\r\n在传统的平面设计中，这个问题的解决方案通常是**把文本层所覆盖的那部分图片区域作模糊处理**。模糊的背景看起来就不那么花哨了，因此，在它之上的文本就相对比较易读了。在过去，由于模糊运算的性能消耗极其巨大，以致于这个技巧在网页设计和 UI 设计中鲜有用武之地。不过，随着 GPU 的不断进化以及硬件加速的不断普及，眼下这个技巧已经逐渐流行起来。在过去这几年里，我们已经可以在较新的 Microsoft Windows 系统中看到这个技巧的身影，而苹果的 iOS 和 Mac OS X 操作系统也不例外（**图 4.16**）。\r\n\r\n> ##### 图 4.16\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.16.1.png)\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.16.2.png)\r\n\r\n> Translucent UIs with a blurred backdrop have been becoming increasingly common in the past few years, as the toll of blurring on resources has stopped being prohibitively expensive (**Apple iOS 8.1** is shown on the left and **Apple OS X Yosemite** is shown on the right)\r\n> \r\n> 在过去这几年间，由于模糊处理的资源消耗已经不再像以前那么高不可攀了，由模糊背层所构成的半透明 UI 已经变得越来越常见了（左图是 **Apple iOS 8.1**，右图是 **Apple OS X Yosemite**）。\r\n\r\nWe also got the ability to blur elements in CSS, via the `blur()` filter, which is essentially a hardware-accelerated version of the corresponding SVG blur filter primitive that we always had for SVG elements. However, if we directly apply a `blur()` filter to our example, the entire element is blurred, which makes it even less readable. (**Figure XX.XX**). Is there any way to just apply it to the element’s backdrop (i.e., the part of the background that is **behind** our element)?\r\n\r\n借助 `blur()` 滤镜，我们还在 CSS 中获得了对元素进行模糊处理的能力。我们在 SVG 中很早就可以使用模糊滤镜了，而这个 CSS 滤镜本质上就是它的硬件加速对应版本。不过，如果我们直接在这个例子中使用 `blur()` 滤镜，那整个元素都会被模糊，文本反而变得更加无法阅读了（**图 4.17**）。有没有某种方法可以只对元素的背层（即被该元素遮住的那部分背景）应用这个滤镜呢？\r\n\r\n> ##### 图 4.17\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.17.png)\r\n\r\n> Applying a `blur()` filter to the element itself makes things worse\r\n> \r\n> 对这个元素应用一个 `blur()` 滤镜反而会把事情搞砸。\r\n\r\n\r\n## The solution\r\n## 解决方案\r\n\r\n> {原书注释!}\r\n\r\n> It’s also possible even with non-fixed backgrounds, just messier.\r\n> \r\n> 对非固定的背景来说也是有办法实现的，只不过难搞一些。\r\n\r\nProvided that our element has a `background-attachment` of `fixed`, this is possible, albeit a bit tricky. Because we cannot apply the blurring to our element itself, **we will apply it to a pseudo-element that is positioned behind the element and whose background seamlessly matches the one on `<body>`**.\r\n\r\n假设大背景的 `background-attachment` 值是 `fixed`，这是有可能的，只不过不太常见%%。由于我们不能直接对元素本身进行模糊处理，那**我们就对一个伪元素进行处理，然后将其定位到元素的下层，而它的背景将会无缝匹配 `<body>` 的背景**。\r\n\r\nFirst, we add the pseudo-element and position it absolutely, with all offsets being `0`, so that it covers the entire `<main>` element:\r\n\r\n首先，我们添加一个伪元素，将其绝对定位，并把所有偏移量置为 `0`，这样就可以将它完整地覆盖到 `<main>` 元素之上：\r\n\r\n```css\r\nmain {\r\n\tposition: relative;\r\n\t/* [Rest of styling] */\r\n\t/* [其它样式] */\r\n}\r\n\r\nmain::before {\r\n\tcontent: '';\r\n\tposition: absolute;\r\n\ttop: 0; right: 0; bottom: 0; left: 0;\r\n\t                              /* for debugging */\r\n\tbackground: rgba(255,0,0,.5); /* 仅用于调试 */\r\n}\r\n```\r\n\r\n> {警告!!}\r\n\r\n> Be careful when using a negative `z-index` to move a child underneath its parent: if said parent is nested within other elements with backgrounds, the child will go below those as well.\r\n> \r\n> 在使用负的 `z-index` 来把一个子元素移动到它的父元素下层时，请务必小心：如果父元素的上级元素有背景，则这个子元素将出现在它们之后。\r\n\r\nWe also applied a semi-transparent `red` background, so we can see what we’re doing, otherwise debugging becomes difficult when we’re dealing with a transparent (and therefore, invisible) element. As you can see in **Figure XX.XX**, our pseudo-element is currently **above** our content, thus obscuring it. We can fix this by adding `z-index: -1;` (**Figure XX.XX**).\r\n\r\n我们同时还给它设置了一层半透明的 `red` 背景，这样我们就可以看清楚我们做了什么，不然我们很难调试透明的（即不可见的）元素。如你在 **图 4.18** 中所见，我们的伪元素现在就覆盖在内容元素**之上**。我们可以用 `z-index: -1;` 来修正这个问题（参见 **图 4.20**）。\r\n\r\n> ##### 图 4.18\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.18.png)\r\n\r\n> The pseudo-element is currently obscuring the text\r\n> \r\n> 伪元素现在正覆盖在文本之上。\r\n\r\n***\r\n\r\n> ##### 图 4.20\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.20.png)\r\n\r\n> Moving the pseudo-element behind its parent, with `z-index: -1;`\r\n> \r\n> 使用 `z-index: -1;` 来把伪元素移动到宿主元素的后面。\r\n\r\n***\r\n\r\n> {原书注释!}\r\n\r\n> Why not just use `background: inherit` on `main::before`? Because then it will inherit from `main`, not `body`, so the pseudo-element will get a semi-transparent white background as well.\r\n> \r\n> 为什么不对 `main::before` 使用 `background: inherit` 呢？因为伪元素会从 `main`（而不是 `body`）那里继承样式，这样它只能得到一个半透明的白色背景。\r\n\r\nNow it’s time to replace that semi-transparent red background, with one that actually matches our backdrop, either by copying over the `<body>` background, or by splitting it into its own rule. Can we blur now? Let’s try it:\r\n\r\n现在该把半透明红色背景换掉了，换成跟背层完全匹配的背景。要实现这一点，我们要么把 `<body>` 的背景复制过来，要么把伪元素的背景声明合并过去。我们现在可以进行模糊处理吗？来试试看：\r\n\r\n```css\r\nbody, main::before {\r\n\tbackground: url(\"tiger.jpg\") 0 / cover fixed;\r\n}\r\n\r\nmain {\r\n\tposition: relative;\r\n\tbackground: hsla(0,0%,100%,.3);\r\n}\r\n\r\nmain::before {\r\n\tcontent: '';\r\n\tposition: absolute;\r\n\ttop: 0; right: 0; bottom: 0; left: 0;\r\n\tfilter: blur(20px);\r\n}\r\n```\r\n\r\nAs you can see in **Figure XX.XX**, we’re pretty much there. The blurring effect looks perfect toward the middle, but is less blurred closer to the edges. This happens because blurring reduces the area that is covered by a solid color by the blur radius. Applying a `red` background to our pseudo-element helps clarify what’s going on (**Figure XX.XX**).\r\n\r\n如你在 **图 4.21** 中所看到的，这跟我们的期望已经相当接近了。模糊效果在中心区域看起来非常完美，但在接近边缘处会逐渐消退。这是因为模糊效果会削减实色像素所能覆盖的范围，削减的幅度正是模糊半径的长度。对伪元素应用一个 `red` 背景将有助于我们看清事情的真相（**图 4.22**）。\r\n\r\n> ##### 图 4.21\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.21.png)\r\n\r\n> Blurring our pseudo-element almost works, but its less blurry on the edges, diminishing the frosted glass illusion\r\n> \r\n> 伪元素模糊的方法基本上成功了，但模糊效果在边缘处会逐渐消退，尽重削弱了毛玻璃的视觉效果。\r\n\r\n***\r\n\r\n> ##### 图 4.22\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.22.png)\r\n\r\n> Adding a `red` background helps make sense of what’s happening\r\n> \r\n> 添加一个 `red` 背景有助于解释事情的真相。\r\n\r\nTo circumvent this issue, we will make the pseudo-element **at least** `20px` (as much as our blur radius) **larger than the dimensions of its container**, by applying a margin of `-20px` or less to be on the safe side, as different browsers might use different blurring algorithms. As **Figure XX.XX** demonstrates, this fixes the issue with the faded blurring at the edges, but now there is also **some blurring outside** our container, which makes it look like a smudge instead of frosted glass. Thankfully, this is also easy to fix: we will just apply `overflow: hidden;` to `main`, in order to clip that extraneous blurring. The final code looks as follows, and its result can be seen in **Figure XX.XX**:\r\n\r\n为了补偿这种情况，我们需要让伪元素**相比其宿主元素的尺寸再向外扩大**至少 `20px`（即它的模糊半径），我们可以通过 `-20px` 的外边距来达到目的，由于不同浏览器的模糊算法可能存在差异，用一个更大的绝对值（比如 `-30px`）会更保险一些。如 **图 4.19** 所示，这个方法可以修复边缘模糊消退的问题，但现在的情况是有**一圈模糊效果超出**了容器，这让它看起来不像毛玻璃，而更像是玻璃脏了。不过幸运的是，这个问题也很容易修复：我们只要对 `main` 元素应用 `overflow: hidden;`，就可以把多余的模糊区域裁切掉了。最终代码如下所示，而最终效果可以在 **图 4.23** 中看到：\r\n\r\n> ##### 图 4.19\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.19.png)\r\n\r\n> We fixed the faded blurring at the edges, but now there is some blurring outside our element too\r\n> \r\n> 我们修正了边缘处的模糊消退情况，但现在又出现了模糊效果超出元素范围的情况。\r\n\r\n```css\r\nbody, main::before {\r\n\tbackground: url(\"tiger.jpg\") 0 / cover fixed;\r\n}\r\n\r\nmain {\r\n\tposition: relative;\r\n\tbackground: hsla(0,0%,100%,.3);\r\n\toverflow: hidden;\r\n}\r\n\r\nmain::before {\r\n\tcontent: '';\r\n\tposition: absolute;\r\n\ttop: 0; right: 0; bottom: 0; left: 0;\r\n\tfilter: blur(20px);\r\n\tmargin: -30px;\r\n}\r\n```\r\n\r\n> ##### 图 4.23\r\n\r\n> ![FIGURE](https://raw.githubusercontent.com/cssmagic/CSS-Secrets/master/figures/chapter-4/4.23.png)\r\n\r\n> Our final result\r\n> \r\n> 我们最终得到的效果。\r\n\r\nNote how much more readable our page has now become, and how much more elegant it looks. It’s debatable whether the fallback for this effect constitutes graceful degradation. If filters are not supported, we will get the result we saw in the beginning (**Figure XX.XX**). We can make our fallback a bit more readable by increasing the opacity of the background color.\r\n\r\n请注意现在页面文本的可读性相比以前要好多了，而整个设计也优雅多了。现在唯一有争议的问题就是这个效果的回退机制是否算得上平稳退化。如果浏览器不支持滤镜，我们将会得到最开始在 **图 4.14** 中所看到的结果。我们只能适当增加背景色的不透明度，以便让回退样式下的可读性得到少许提升。\r\n\r\n> {试一试} [play.csssecrets.io/frosted-glass](http://play.csssecrets.io/frosted-glass)\r\n\r\n***\r\n\r\n> #### Related specs\r\n\r\n> * [Filter Effects](http://w3.org/TR/filter-effects)\r\n\r\n> #### 相关规范\r\n\r\n> * [滤镜效果](http://w3.org/TR/filter-effects)"}}