堆叠的半透明盒子的颜色取决于订单?

rmv*_*rmv 78 html css background background-color overlapping

为什么两个堆叠的半透明盒子的最终颜色取决于订单?

我怎么能这样做才能在两种情况下得到相同的颜色?

.a {
  background-color: rgba(255, 0, 0, 0.5)
}

.b {
  background-color: rgba(0, 0, 255, 0.5)
}
Run Code Online (Sandbox Code Playgroud)
<span class="a"><span class="b">          Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 91

仅仅因为在两种情况下,由于顶层的不透明度如何影响底层的颜色,颜色的组合是不同的.

对于第一种情况,您会在顶层看到50%的蓝色和50%的透明.通过透明部分,您可以在底层看到50%的红色(因此我们只看到25%的红色).第二种情况的逻辑相同(50%的红色25%的蓝色); 因此你会看到不同的颜色,因为在这两种情况下我们没有相同的比例.

为避免这种情况,您需要为两种颜色选择相同的比例.

这是一个更好地说明和展示我们如何获得相同颜色的示例:

在顶层(内部跨度),我们有0.25不透明度(因此我们有25%的第一种颜色和75%的透明度)然后对于底层(外部跨度)我们有0.333不透明度(所以我们有1/3的75%= 25%的颜色,其余是透明的).我们在两个层中具有相同的比例(25%),因此即使我们颠倒了层的顺序,我们也会看到相同的颜色.

.a {
  background-color: rgba(255, 0, 0, 0.333)
}

.b {
  background-color: rgba(0, 0, 255, 0.333)
}

.a > .b {
  background-color: rgba(0, 0, 255, 0.25)
}
.b > .a {
  background-color: rgba(255, 0, 0, 0.25)
}
Run Code Online (Sandbox Code Playgroud)
<span class="a"><span class="b">          Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>
Run Code Online (Sandbox Code Playgroud)

另外,白色背景也会影响颜色的渲染.它的比例为50%,这将产生100%的合理结果(25%+ 25%+ 50%).

您可能也注意到,它不会有可能对我们的两种颜色相同的比例,如果顶层是具有透明度比我的大0.5,因为第一个将有超过50% ,它仍将低于50%,为第二一:

.a {
  background-color: rgba(255, 0, 0, 1) /*taking 40% even with opacity:1*/
}

.b {
  background-color: rgba(0, 0, 255, 1) /*taking 40% even with opacity:1*/
}

.a > .b {
  background-color: rgba(0, 0, 255, 0.6) /* taking 60%*/
}
.b > .a {
  background-color: rgba(255, 0, 0, 0.6) /* taking 60%*/
}
Run Code Online (Sandbox Code Playgroud)
<span class="a"><span class="b">          Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>
Run Code Online (Sandbox Code Playgroud)

常见的小问题是当顶层具有opacity:1使顶部颜色具有100%的比例时; 因此它是一种不透明的颜色.


对于这里的更准确和精确的解释是用于计算我们两个层的组合后看到的颜色式REF:

ColorF = (ColorT*opacityT + ColorB*OpacityB*(1 - OpacityT)) / factor
Run Code Online (Sandbox Code Playgroud)

ColorF是我们的最终颜色.ColorT/ColorB分别是顶部和底部颜色. opacityT/opacityB分别是为每种颜色定义的顶部和底部不透明度:

factor由如下公式定义OpacityT + OpacityB*(1 - OpacityT).

很明显,如果我们切换两个层factor不会改变(它将保持不变)但我们可以清楚地看到每种颜色的比例将会改变,因为我们没有相同的乘数.

对于我们最初的情况,两种不透明都是0.5如此,我们将:

ColorF = (ColorT*0.5 + ColorB*0.5*(1 - 0.5)) / factor
Run Code Online (Sandbox Code Playgroud)

如上所述,顶部颜色的比例为50%(0.5),底部颜色的比例为25%(0.5*(1-0.5)),因此切换层也会切换这些比例; 因此我们看到了不同的最终颜色.

现在,如果我们考虑第二个例子,我们将:

ColorF = (ColorT*0.25 + ColorB*0.333*(1 - 0.25)) / factor
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们0.25 = 0.333*(1 - 0.25)这样切换两层将没有任何影响; 因此颜色将保持不变.

我们还可以清楚地识别琐碎的案例:

  • 当顶层具有opacity:0公式时等于ColorF = ColorB
  • 当顶层具有opacity:1公式时等于ColorF = ColorT

  • @ChrisHappy我没有解决问题;)我正在解释..解释有时比解决方案更好 (22认同)
  • 如果你想添加TLDR,那就是它们是乘法而不是加法. (5认同)
  • @Caramiriel:"乘法"仍然无法解释为什么操作不可交换. (2认同)

Mof*_*fen 37

添加css属性, mix-blend-mode : multiply

.a {
  background-color: rgba(255, 0, 0, 0.5);
  mix-blend-mode: multiply;
}

.b {
  background-color: rgba(0, 0, 255, 0.5);
  mix-blend-mode: multiply;
}

.c {
  position: relative;
  left: 0px;
  width: 50px;
  height: 50px;
}

.d {
  position: relative;
  left: 25px;
  top: -50px;
  width: 50px;
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<span class="a"><span class="b">          Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>

<div class="c a"></div>
<div class="d b"></div>

<div class="c b"></div>
<div class="d a"></div>
Run Code Online (Sandbox Code Playgroud)

  • 几乎任何来自[此列表](http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html)的颜色混合模式都是"可交换的"特技. (5认同)
  • @rmv为什么你会期待覆盖/正常以外的任何东西?如果你在红色框前面放置一个不透明的蓝色框,预期的颜色是多少?它将是蓝色而不是红色或蓝色和红色的功能. (3认同)

Sal*_*n A 20

您按以下顺序混合三种颜色:

  • rgba(0, 0, 255, 0.5) over (rgba(255, 0, 0, 0.5) over rgba(255, 255, 255, 1))
  • rgba(255, 0, 0, 0.5) over (rgba(0, 0, 255, 0.5) over rgba(255, 255, 255, 1))

你会得到不同的结果.这是因为使用不可交换的普通混合模式1将前景色与背景色混合.由于它不是可交换的,因此交换前景色和背景色会产生不同的结果.

1混合模式是一种接受前景色和背景色的功能,应用一些公式并返回结果颜色.

解决方案是使用可交换的混合模式:以任何顺序为同一对颜色返回相同颜色的模式(例如,乘法混合模式,它将两种颜色相乘并返回结果颜色;或者变暗混合模式,返回两种颜色较深的颜色).

$(function() {
  $("#mode").on("change", function() {
    var mode = $(this).val();
    $("#demo").find(".a, .b").css({
      "mix-blend-mode": mode
    });
  });
});
Run Code Online (Sandbox Code Playgroud)
#demo > div {
  width: 12em;
  height: 5em;
  margin: 1em 0;
}

#demo > div > div {
  width: 12em;
  height: 4em;
  position: relative;
  top: .5em;
  left: 4em;
}

.a {
  background-color: rgba(255, 0, 0, 0.5);
}

.b {
  background-color: rgba(0, 0, 255, 0.5);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<select id="mode">
  <optgroup label="commutative">
    <option>multiply</option>
    <option>screen</option>
    <option>darken</option>
    <option>lighten</option>
    <option>difference</option>
    <option>exclusion</option>
  </optgroup>
  <optgroup label="non-commutative">
    <option selected>normal</option>
    <option>overlay</option>
    <option>color-dodge</option>
    <option>color-burn</option>
    <option>hard-light</option>
    <option>soft-light</option>
    <option>hue</option>
    <option>saturation</option>
    <option>color</option>
    <option>luminosity</option>
  </optgroup>
</select>

<div id="demo">
  <div class="a">
    <div class="b"></div>
  </div>
  <div class="b">
    <div class="a"></div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


为了完整性,这里是计算合成颜色的公式:

?s x (1 - ?b) x Cs + ?s x ?b x B(Cb, Cs) + (1 - ?s) x ?b x Cb
Run Code Online (Sandbox Code Playgroud)

有:

Cs:前景色的颜色值
αs:前景色的alpha值
Cb:背景色的颜色值
αb:背景颜色的alpha值B:混合函数


Mr *_*ter 8

有关发生的事情的解释,请参阅Temani Afif的回答.
作为替代解决方案,您可以采用一个跨度,a例如,定位它,如果它在里面,则给它一个较低的z-index b.然后堆叠将始终相同:在第一行的b顶部绘制,a在第二行的a下面绘制b.

.a {
  background-color: rgba(255, 0, 0, 0.5);
}

.b {
  background-color: rgba(0, 0, 255, 0.5);
}

.b .a {position:relative; z-index:-1;}
Run Code Online (Sandbox Code Playgroud)
<span class="a"><span class="b">     Color 1</span></span>
<span class="b"><span class="a">Same Color 2</span></span>
Run Code Online (Sandbox Code Playgroud)