html - Firefox:如何在不破坏固定位置元素的情况下对整个页面进行灰度化?

标签 html css firefox centering css-filters

为什么CSS filters ,(那些似乎与大小/定位无关的)会破坏您为后代元素提供固定位置的能力吗?

除了回答这个问题之外,请提出一个解决方案来解决我在下面展示的问题。

下面的 CSS 和 HTML 只是在视口(viewport)中心生成一个红色小框:

#box
{
  background: red; color: white;
  display: inline-block;
  border: solid #333333 10px;
  padding: 5px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Before Filter Corrupts Fixed Positioning</title>
</head>
<body>
<div id ="box">Dead Center<div>
</body>
</html>

现在,假设我们有一个要求,整个页面必须以灰度显示。下面唯一有效的更改是添加了 CSS 灰度滤镜。但是,添加此过滤器后,该框将不再遵循我们规定的中心页面定位:

body { filter: grayscale(100%); }
#box
{
  background: red; color: white;
  display: inline-block;
  border: solid #333333 10px;
  padding: 5px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Filter Corrupts Fixed Positioning</title>
</head>
<body>
<div id ="box">Dead Center<div>
</body>
</html>

请注意,该框不再垂直居中。这是一个错误,还是只是设计愚蠢

更新1:

Temani Afif 在评论中建议在 html 元素(而不是 body 元素)上应用过滤器。虽然这确实解决了 Chrome 中的问题,但在 Firefox 78 中却没有:

html { filter: grayscale(100%); }
#box
{
  background: red; color: white;
  display: inline-block;
  border: solid #333333 10px;
  padding: 5px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Filter Corrupts Fixed Positioning</title>
</head>
<body>
<div id ="box">Dead Center<div>
</body>
</html>

更新2:

根据反馈,这里我尝试将过滤器应用到 :root ,而不是 html。虽然这确实解决了 Chrome 中的问题,但在 Firefox 78 中却没有:

:root { filter: grayscale(100%); }
#box
{
  background: red; color: white;
  display: inline-block;
  border: solid #333333 10px;
  padding: 5px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Filter Corrupts Fixed Positioning</title>
</head>
<body>
<div id ="box">Dead Center<div>
</body>
</html>

enter image description here

我提交了这个issue到火狐浏览器。

摘要:尽管规范允许您将过滤器应用到文档根目录,以避免封装固定/绝对后代,但我认为规范可以改进通过在与修改大小和位置无关的过滤器上完全避免这种行为。像灰度这样的过滤器对后代的大小或位置的影响应该为零,因此应用该过滤器的位置(根或非根)应该不重要。在像灰度这样的过滤器上,永远不应该有任何后代的包装。我正在向 W3C 解释 here .

更新 3: @NateG 建议将过滤器应用于 body > *。到目前为止,这似乎在 Chromium 和 Firefox 中都有效!见下文:

body > * { filter: grayscale(100%); }
#box
{
  background: red; color: white;
  display: inline-block;
  border: solid #333333 10px;
  padding: 5px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Filter Corrupts Fixed Positioning</title>
</head>
<body>
<div id ="box">Dead Center<div>
</body>
</html>

最佳答案

在应用某些样式时,您不应该弄乱 body/html,因为由于这些元素的性质,您将面临很多意想不到的结果。

相关问题表明您在 html 上使用过滤器时会遇到比预期更多的问题:CSS filter:invert not working with background-color

您还需要考虑某些属性的传播,例如 overflowbackground

这里有一个使用 position:sticky 模拟固定元素的想法,并考虑使用额外的包装器来避免任何类型的问题:

.html {
  min-height: 100vh;
  filter: grayscale(100%);
}

#box {
  background: red;
  color: white;
  border: solid #333333 10px;
  padding: 5px;
  position: sticky;
  top: 50vh;
  left: 50%;
  transform: translate(-50%, -50%);
  /* the combination of float and transparent shape outside will make the element
     * shrink to fit
     * will not affect the other elements
  */
  float: left;
  shape-outside: linear-gradient(transparent, transparent);
}


/* to simulate content */

.content {
  font-size: 40px;
}

body {
  margin: 0;
}
<div class="html">
  <div id="box">Dead Center
  </div>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus volutpat eu ante sed lacinia. In sit amet sapien euismod nibh malesuada convallis pulvinar non mauris. Ut id felis posuere, pharetra justo eget, viverra lacus. Vestibulum tellus libero,
    euismod ac tellus vitae, dapibus mollis tellus. Donec ornare consectetur dui. Vestibulum iaculis neque leo, nec bibendum nisl consectetur in. Curabitur at viverra augue, ac semper neque.
  </div>
</div>

关于html - Firefox:如何在不破坏固定位置元素的情况下对整个页面进行灰度化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62717289/

相关文章:

html - Bootstrap 4 : align content inside cards deck

html - 覆盖巨型下拉菜单的 slider

flash - Flash:同一页面上有许多相同的SWF

通过 VBA/Excel 提取 HTML

html - 画廊的水平滚动条

javascript - 如何滚动到先前隐藏但在标签单击时可见的 div

html - 为什么 col break 元素占用 flexbox 中的空间

javascript - anchor 标记上的 onclick 事件在 IE 中有效,但在 Firefox 和 Chrome 中无效

javascript - firefox 和 chrome 中 offsetwidth 的不同值

javascript - HTML5 视频加载数据事件在 IOS Safari 中不起作用