CSS 去饱和背景图像仅与 Div 中的其他图像保持饱和

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27572728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:51:06  来源:igfitidea点击:

CSS to Desaturate Background Image Only WIth Other Images in Div Stay Saturated

css

提问by mk97

I am trying to desaturate the background image of a div while leaving the images within that same div saturated. I've found one example close to what I'm trying to do (except w/ blur) but have tried multiple variations of it w/ no success.

我试图降低 div 的背景图像的饱和度,同时使同一 div 中的图像饱和。我找到了一个接近我想要做的例子(除了模糊),但尝试了它的多种变体,但没有成功。

In the code below, the .desaturate class correctly applies the filter attributes and turns bg image into b&w. The other image w/in this section tag are inheriting the desaturate as would be expected, but when I try to "re-saturate" through the img.saturate class it is not being applied. I've whittled down my code to as short/basic as it can get to explain what I am trying to do. Any ideas or solution how this can be done is appreciated.

在下面的代码中,.desaturate 类正确地应用了过滤器属性并将 bg 图像转换为黑白图像。本节标签中的另一个图像正如预期的那样继承了去饱和,但是当我尝试通过 img.saturate 类“重新饱和”时,它没有被应用。我已经将我的代码缩减到尽可能短/基本,以解释我正在尝试做什么。任何想法或解决方案如何做到这一点表示赞赏。

<html>
  <style>
    .desaturate {
      width: 100%;
      height: 100%;
      background-position: center center;
      background-repeat: no-repeat;
      background-size: cover;
       /*grayscale for background image*/
      -webkit-filter: grayscale(1); 
      -webkit-filter: grayscale(100%); 
      -moz-filter: grayscale(100%);
      filter: gray; 
      filter: grayscale(100%);
      filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
    }

  img.saturate {
    filter: none !important;
    width: 300px;
    height: 200px;
    -webkit-filter: grayscale(0%) !important;
    -moz-filter:    grayscale(0%) !important;
    -ms-filter:     grayscale(0%) !important;
    -o-filter:      grayscale(0%) !important;
  }
  </style>
  <body>
    <section class="desaturate" style="background-image: url('bg-img-1.jpg');">
      <div class="row">
        <div class="col-md-12">
          <img src="img-2.jpg" class="img-responsive saturate" alt="" />      
        </div>
      </div>
    </section>
  </body> 
</html>

采纳答案by Godwin

Saturation works in the same way as opacity does, you can't apply the effect to a parent and then undo it in a child. Your best option would probably be to make the grayscaled image a child of your section but not a parent of the image:

饱和度的工作方式与不透明度相同,您不能将效果应用于父级,然后在子级中撤消它。您最好的选择可能是使灰度图像成为您部分的子项,而不是图像的父项:

<section>
  <figure class="desaturate" style="background-image: url('bg-img-1.jpg');"></figure>
  <div class="row">
    <div class="col-md-12">
      <img src="img-2.jpg" class="img-responsive saturate" alt="" />      
    </div>
  </div>
</section>

Your other option would be to inherit the background in a ::beforeor ::afterpseudo element and apply the filter there:

您的另一个选择是继承 a::before::after伪元素中的背景并在那里应用过滤器:

.desaturate {
  width: 100%;
  height: 100%;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  position: relative;
}

.desaturate:before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: inherit;
   /*grayscale for background image*/
  -webkit-filter: grayscale(1); 
  -webkit-filter: grayscale(100%); 
  -moz-filter: grayscale(100%);
  filter: gray; 
  filter: grayscale(100%);
  filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
}

You can see a demo here: http://codepen.io/Godwin/pen/ogLPvR.

您可以在此处查看演示:http: //codepen.io/Godwin/pen/ogLPvR

Edit: Just for sake of interest, there is another way of doing this but it doesn't have high browser support yet:

编辑:只是为了兴趣,还有另一种方法可以做到这一点,但它还没有高浏览器支持:

.desaturate {
    width: 100%;
    height: 100%;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    /*grayscale for background image*/
    background-color: #FFF;
    background-blend-mode: luminosity, normal;
}

Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/background-blend-mode

参考:https: //developer.mozilla.org/en-US/docs/Web/CSS/background-blend-mode

Example: http://codepen.io/Godwin/pen/raLZVr

示例:http: //codepen.io/Godwin/pen/raLZVr

Support: http://caniuse.com/#feat=css-backgroundblendmode

支持:http: //caniuse.com/#feat=css-backgroundblendmode

回答by MarsAndBack

Make your background image a child

让你的背景图片成为一个孩子

With your background image as a child, then you can apply a filteron the element.

使用您的背景图像作为孩子,然后您可以filter在元素上应用 a 。

filter: grayscale(60%);
-webkit-filter: grayscale(60%);
-moz-filter: grayscale(60%);
-ms-filter: grayscale(60%);
-o-filter: grayscale(60%);

Alternatively, maintain your HTML structure, but only target the background-image...

或者,保持您的 HTML 结构,但只针对背景图像...

Concerning background image's, filters aren't available, however you can get the same saturation effect using this trick with background-blend-mode.

关于背景图像,过滤器不可用,但是您可以使用此技巧与background-blend-mode.

Usually background-blend-modeis on-or-off (ie you cannot define percentage), however with the below trick you can actually get variable saturation:

通常background-blend-mode是开或关(即您无法定义百分比),但是使用以下技巧您实际上可以获得可变饱和度:

background: linear-gradient(rgba(0,0,0,0.6),rgba(0,0,0,0.6)), url(image.jpg);
background-blend-mode: saturation;

This will give you a 60% desaturation only on the background image, using background-blend-mode. The key is using linear-gradient, with opacity set on the colors. I can't seem to replicate the same effect notusing a gradient (ie a solid color with opacity).

这将仅在背景图像上为您提供 60% 的去饱和度,使用background-blend-mode. 关键是使用线性渐变,在颜色上设置不透明度。如果使用渐变(即不透明的纯色),我似乎无法复制相同的效果。

Browser support:

浏览器支持:

Both filterand background-blend-modehave weaker support in IE/Edge, so perhaps use separate CSS rules for those browsers (as described in tons of other posts).

双方filterbackground-blend-mode在IE /边缘弱的支持,因此,或许使用不同的CSS规则,这些浏览器(如吨其他职位的描述)。

回答by Josh Burgess

Here's your fix:

这是你的修复:

Example Fiddle

示例小提琴

So, basically, your CSS is messed up pretty bad. The dangling !importantmodifiers after your semi-colons and the haphazardly included semi-colons after that aren't helping.

所以,基本上,你的 CSS 一团糟。!important分号之后的悬空修饰符和之后随意包含的分号都无济于事。

CSS Changes

CSS 更改

.desaturate {
  width: 100%;
  height: 100%;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;

}

.desaturate img {
  /*grayscale for background image*/
  -webkit-filter: grayscale(1); 
  -webkit-filter: grayscale(100%); 
  -moz-filter: grayscale(100%);
  filter: gray; 
  filter: grayscale(100%);
  filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
}



.desaturate img.saturate {
  filter: none !important;
  width: 300px;
  height: 200px;
  -webkit-filter: grayscale(0%);
  -moz-filter:    grayscale(0%);
  -ms-filter:     grayscale(0%);
  -o-filter:      grayscale(0%);
}

You can't apply the filter to the whole divand then override it on a child element (in this case your img. So we apply the filter to the imgfirst, and then override it with your saturateclass.

您不能将过滤器应用于整体div,然后在子元素上覆盖它(在这种情况下是您的img. 所以我们将过滤器应用于第img一个,然后用您的saturate类覆盖它。

Voila.

瞧。