繁体   English   中英

CSS 过滤器:反转不适用于背景色

[英]CSS filter:invert not working with background-color

我将以下 CSS 应用于<html>标签: filter: invert(1);

所有元素都被反转,甚至元素的background-color ,(Chrome v80)

一旦我在 Safari iOS 13 / Safari MacOS 上尝试相同的操作,除 <html> 的background-color外,每个元素都会反转

我正在运行的所有浏览器都支持 CSS 过滤器属性:

https://caniuse.com/#feat=mdn-css_properties_filter

有人可以解释这种行为吗?

 html { filter: invert(1); /* this background-color does not change on ios+other browsers */ background: #fff; padding: 50px; } body { background-color: #0000ff; display: flex; align-items: center; justify-content: center; height: 100vh; }.text { text-align: center; color: red; }
 <div class="text"> If it works: color should not be red, background should not be blue </div>

TL;DR :不要过多地使用html元素。

The easy workaround is to block body 's background propagation to the document's canvas, but make it take the same size as the html by removing its margin, and applying all the styles you had on html on the body, and the ones you had on body到包装器<div>

 html { /* block body's background propagation */ background: #FFF; } /* move all one layer down */ body { filter: invert(1); background: #fff; padding: 50px; /* make it cover the full canvas */ margin: 0; }.wrapper { background-color: #0000ff; display: flex; align-items: center; justify-content: center; height: 100vh; }.text { text-align: center; color: red; }
 <div class="wrapper"> <div class="text"> If it works: color should not be red, background should not be blue and border should not be white </div> </div>


更深入的观察:

这里有一些概念在起作用,它们的交互并不是那么容易掌握(至少对我来说......)。

  • “渲染层”:绘制页面时,通常会有几层渲染,可能嵌套在其中应用过滤器或不透明度等效果。 规范仅定义“堆叠上下文”,对于我们这里的情况,它们是相同的。
  • “文档画布” :每个文档都有一个背景 canvas,它不存在于 DOM 中,它是最深的“渲染层”。
  • “背景传播” :一些特殊元素在其 CSS background属性方面具有特殊行为。 值得注意的是, htmlbody可能会为“文档的画布”提供自己的背景。 基本工作流程是

    • 如果html的背景不是nonetransparent ,则将其用于“文档画布”。
    • 否则,如果body的背景不是none且不是transparent ,则将其用于“文档的画布”。
    • 否则做任何你想做的事情(通常浏览器呈现白色纯色)。
  • 当所有内部内容已经被渲染时, filteropacity等“后处理”效果应该应用于整个“渲染层”。

  • 在元素上设置此类“后处理”效果应该隔离该元素并从中创建一个新的“渲染层”。

现在,还不清楚“文档的画布”应该如何受到这些“后处理”效果的影响,而且我在规范中找不到任何明确的答案。

可以肯定的是,我们有 [Compat] 问题...

不仅并非所有浏览器都遵循相同的规则,而且当页面呈现为独立的 window 或 iframe 时,某些浏览器的行为也会有所不同。

由于测试结果在窗口渲染和框架渲染之间确实有所不同,并且 StackSnippet 只允许框架渲染,所以我不得不在这个 plnkr中外包测试用例。

html {
  background: red;
  height: 50vh;
  border: 10px solid green;
}

.opacity {
  opacity: 0.5;
}

.filter {
  filter: invert(1);
}

body {
  background: yellow;
  margin: 10vh;
  border: 2px solid green;
}

这些针对主要浏览器的测试结果如下:

窗口化时:(屏幕截图顺序,从左到右:过滤器不透明度过滤器+不透明度)。

  • Firefox 不对文档的 canvas 应用过滤器或不透明度。 火狐截图
  • Edge 不会对文档的 canvas 应用滤镜或不透明度。 (与火狐相同)
  • Chrome < 81 不会对文档的 canvas 应用过滤器或不透明度。 (与火狐相同)
  • Chrome >= 81 对文档的 canvas 应用过滤器和不透明度。
    Chrome 屏幕截图
  • Safari 确实
    • 当没有设置不透明度时,统一应用过滤器。
    • 不要在文档的 canvas 上应用不透明度
    • 设置不透明度时为<html>创建一个新层,并在<html>的背景上应用不透明度和过滤器。
      然而,它现在使用<body>的背景颜色作为文档的 canvas... 但让它不受过滤器的影响。
    Safari 截图

加框时:(截图顺序,从左到右:滤镜不透明度滤镜+不透明度)。

  • Firefox 不对文档的 canvas 应用过滤器或不透明度。
    火狐截图
  • Edge 不会对文档的 canvas 应用滤镜或不透明度。 (与火狐相同)
  • Chrome(所有版本)不会对文档的 canvas 应用过滤器或不透明度。
    Chrome 屏幕截图
  • Safari 确实
    • 当没有设置不透明度时,统一应用过滤器。
    • 设置不透明度时,将文档的 canvas 设置为透明,并为<html>创建一个应用不透明度的新层。
    • 设置不透明度时为<html>创建一个新层,并在<html>的背景上应用不透明度和过滤器。
      但是,它现在将文档的 canvas 设置为透明。
    Safari 截图


所以再一次,我不知道这里的任何结果是否符合规范,我知道作为网络作者,我们应该尽可能避免弄乱它。


后记:

  • 这是引入新 Chrome 行为的Chromium 问题
  • 这是允许 web 作者将文档的 canvas 背景定义为对某些设备透明的提议

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM