【问题标题】:Gooey css effects with contrast parent带有对比父级的粘糊糊的 CSS 效果
【发布时间】:2017-03-17 00:40:11
【问题描述】:

我正在尝试仅使用 CSS(没有 svg) 创建粘糊糊的效果。 一切正常,但我的父容器有一个 contrast filter,我不能在我的子元素上使用颜色(对比度过滤器会改变颜色)。

是否有人知道一种基本方法可以仅使用 CSS 或反转对比度过滤器以在子元素上获得正确的颜色?

我的代码:

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blob {
  background:black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  -webkit-transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  box-shadow: 0 0 30px 10px black;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

当我为子元素着色时:

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blob {
  background: rgb(255, 113, 93);
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  -webkit-transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  box-shadow: 0 0 30px 10px rgb(255, 113, 93);
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}

.original-color {
  height: 100px;
  background: rgb(255, 113, 93);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="original-color"></div>

My fiddle

【问题讨论】:

  • 如果能帮到你:codepen.io/mirajm212/pen/Iivdj
  • 嗨@RedBreast,不幸的是它不是。在您的示例中,颜色会发生变化,因为父级上的对比度过滤器。我正在为这种行为寻找解决方案,并使子元素具有正确的颜色。将您的红色更改为绿色,您就会发现问题
  • 对不起,我帮不上忙,但这真的很酷:P

标签: css css-filters


【解决方案1】:

我已经采取了你的效果。在容器上,我设置了一个覆盖它的伪元素,用你想要的任何颜色。

通过混合混合模式,我可以在容器为黑色的地方设置此颜色,保持剩余的白色:

(顺便说一句,效果很好!)

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blobs:after {
  content: "";
  position: absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background-color: coral;  
  mix-blend-mode: lighten;
}

.blob {
  background:black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
  box-shadow: 0 0 30px 10px black;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

添加了另一种方式来获取您的请求。这更难设置,但可以在 Edge 上工作,其中过滤器可用但混合模式不可用。

此 sn-p 涉及使用 2 个您之前的设置,并为每个设置使用不同的原色。 (您已经可以使用原始设置实现原色)。

要获得特定颜色,您可以为这 2 个设置设置不同的 alpha,然后您可以通过某种方式获得您想要的任何颜色(尽管过程并不容易)

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
  opacity: 0.99;
}


.blob {
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
}

.blobs:hover .blob:first-child,  
.blobs:hover ~ .blobs .blob:first-child {
  transform:translateX(-70px);
}
.blobs:hover .blob:last-child, 
.blobs:hover ~ .blobs .blob:last-child {
  transform:translateX(70px);
}
.blobs:nth-child(1)  {
  opacity: 0.57;
}
.blobs:nth-child(1) .blob {
  background: red;
  box-shadow: 0 0 30px 10px red;
}
.blobs:nth-child(2)  {
  pointer-events: none;
  opacity: 0.08;
}
.blobs:nth-child(2) .blob {
  background: yellow;
  box-shadow: 0 0 30px 10px yellow;
}
.test {
    width: 100px;
  height: 100px;
  position: absolute;
  left: 0px;
  background-color: rgb(255, 113, 93);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="test"></div>

再试一次,这次使用更复杂的过滤器。

颜色是通过色调旋转实现的

body {
  background: #fff;
}
.blobs {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #fff;
  width: 400px;
  height: 200px;
  margin: auto;
  -webkit-filter: contrast(20) hue-rotate(-25deg);
  filter: contrast(20) hue-rotate(-25deg);
}
.blob {
  background: red;
  width: 100px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-top: -50px;
  margin-left: -50px;
  border-radius: 100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
  box-shadow: 0 0 30px 10px red;
}
.blobs:hover .blob:first-child {
  transform: translateX(-70px);
}
.blobs:hover .blob:last-child {
  transform: translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

再试一次,这次是单个 div ....

.test {
  border: 1px solid black;
  width: 600px;
  height: 400px;
  background-color: white;
  background-image: radial-gradient(circle, red 100px, transparent 140px), radial-gradient(circle, red 100px, transparent 140px);
  background-position: -150px 0px, 150px 0px;
  background-repeat: no-repeat;
  -webkit-filter: contrast(20) hue-rotate(35deg);
  filter: contrast(20) hue-rotate(35deg);
  transition: background-position 2s;
  animation: crazy 13s infinite steps(12);
}
.test:hover {
  background-position: 0px 0px, 0px 0px;
}
@keyframes crazy {
  from {
    filter: contrast(20) hue-rotate(0deg);
  }
  to {
    filter: contrast(20) hue-rotate(360deg);
  }
}
&lt;div class="test"&gt;&lt;/div&gt;

试图获得一个可以跨浏览器工作的解决方案。 添加了 javascript 以检查混合模式是否可用。

只需单击按钮即可运行该功能。

function check () {
  if('CSS' in window && 'supports' in window.CSS) {
    var support = window.CSS.supports('mix-blend-mode','lighten');
    if ( ! support) {
      var element = document.getElementById('blobs');
      element.classList.add('compat');
    }
}
}
body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blobs:after {
  content: "";
  position: absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background-color: coral;  
  mix-blend-mode: lighten;
}

.blob {
  background:black;
  box-shadow: 0 0 30px 10px black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}

/* compatibility */

.blobs.compat {
  -webkit-filter:contrast(20)  hue-rotate(-25deg);
  filter:contrast(20)   hue-rotate(-25deg);
}
.blobs.compat:after {
  content: none;
}

.compat .blob {
  background: red;
  box-shadow: 0 0 30px 10px red;
}
<div class="blobs" id="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<button onclick="check()">Check</button>

【讨论】:

  • 真的很好!我认为这个属性不支持 IE,你有 IE 解决方案吗?谢谢!
  • 谢谢@vals,但它不像你的第一个sn-p那样工作。我需要一个完整的支持解决方案,但我不知道该怎么做。 :(
  • 嗨@vals,颜色看起来与您定义的不同,并且在悬停时有一个奇怪的阴影。 :(
  • 获得最终颜色的方法有点复杂,正如我在答案中指出的那样。由于您只能使用原色和互补色,因此您需要使用 2 个元素的 alpha 来调整最终颜色。我已经编辑了答案,以获得或多或少等于您问题中的颜色的颜色。但我没有看到影子。我已经放慢了过渡速度,但还是看不到影子……
  • 感谢您的宝贵时间。看看这张图片:i.imgsafe.org/b49f404766.png
【解决方案2】:

对于这个答案,我只需要更改过滤器属性

contrast(15) contrast(.5) sepia(1) brightness(1.85) hue-rotate(319deg) saturate(3.45)
  • 首先,我们将对比度设置为 15(如果您问我,20 会使边缘有点太硬)
  • 然后我们将其设置回 0.5(是的,您可以堆叠这些东西)

所以现在我们有了浅灰色背景和深灰色斑点

  • 应用棕褐色(赋予其颜色)
  • 添加 1.85 亮度(现在背景再次变为白色,并且我们有彩色斑点)
  • 色相旋转以获得正确的色相
  • 饱和使其饱和

列表中的最后三个属性对于获得正确的颜色至关重要。你的目标是 rgb(255, 113, 93)。应用这条线后,颜色为 rgb(255, 115, 94)

你可以在this Fiddle看到它的工作原理

作为旁注。您还可以堆叠变换,这意味着如果您想使 blob 居中,则不必使用负边距,而是使用 translate(-50%, -50%) 技巧。然后,当您将鼠标悬停在它们上时,您可以像这样简单地堆叠变换 translate(-50%, -50%) translateX(-70px)

【讨论】:

  • 悬停时将颜色更改为黑色。 :(
  • 我相信在 safari 中存在某种错误......你的小提琴在 PC 上工作正常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 2016-01-13
  • 2021-04-07
  • 2011-12-22
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多