積み重ねられた半透明の箱の色は注文によって異なりますか?


84

2つの積み重ねられた半透明のボックスの最終的な色が順序に依存するのはなぜですか?

どちらの場合も同じ色になるようにするにはどうすればよいですか?

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

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


7
質問の答えはわかりませんが、フォトショップでも同じことが起こり、コンピューターの色彩理論の一部として何年も受け入れてきました。これ以上の情報がないか見回します。
YAHsaves 2018年

11
その価値については、100%透明ではなく、正面から照らされているものについても、実際の生活で同じことが起こります。前面のオブジェクトからより多くの光が目に届くため、両方の透明度が50%であっても、その色は最終的な色に大きな影響を与えます。
jpa 2018年

4
@YAHsaves:0と100の平均は50です(ステップ1)。50と150の平均は100です(ステップ2)。これを次のように比較してください。150と0の平均は75です(ステップ1)。75と100の平均は87.5です(ステップ2)。問題は、3つの数値が正しく重み付けされていないことです。平均は、すべての数値に基づいて同時に計算する必要があります。ステップごとに平均を再帰的に計算することはできません。(平均計算は基本的に50%の透明度の計算であることに注意してください。計算は透明度レベルごとに異なりますが、原則は同じです)
2018年

2
学んだ教訓:「mix-blend-mode:multiply」を使用すると、スタックの順序に関係なく色が得られます。これが最初に探していたものです。@Moffensの回答は、同じ問題に直面している他のユーザーにとって最も役立つと思います。しかし、Temani Afifの説明は実際に私の質問に当てはまり、HTMLが逆に動作する理由(半透明のフォイルを介した物理的な光の伝播を模倣する)を説明しているため、緑色のチェックマークが彼に届きます。
rmv 2018年

回答:


101

どちらの場合も、色の組み合わせは、不透明度のどのように同じ原因ではないという理由だけで、トップ層はの色に影響下の層を。

最初のケースでは、最上層に50%の青と50%の透明が表示されます。透明な部分を通して、最下層に赤い色の50%が表示されます(したがって、合計で赤の25%しか表示されません)。第二のケース(のために同じ論理赤色の50%および青25% )。したがって、どちらの場合も同じ比率ではないため、異なる色が表示されます。

これを回避するには、両方の色で同じ比率にする必要があります。

これは、同じ色を取得する方法をわかりやすく説明するための例です。

最上層(内側のスパン)には0.25不透明度があり(つまり、最初の色の25%、透明度の75%)、最下層(外側のスパン)には0.333不透明度があります(つまり、 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)
}
<span class="a"><span class="b">          Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>

ちなみに、白い背景も色のレンダリングに影響を与えています。その比率は50%であり、論理的な結果は100%(25%+ 25%+ 50%)になります。

また0.5最初のレイヤーの不透明度が50%を超え、2番目のレイヤーの不透明度が50%未満のままであるため、トップレイヤーの不透明度が大きい場合、両方の色の比率を同じにすることができないことに気付くかもしれません。1:

一般的な些細なケースは、トップレイヤーがopacity:1100%の割合でトップカラーを作成している場合です。したがって、それは不透明な色です。


ここでは、より正確で精密な説明については、我々は両方の層の組み合わせ後に表示色を計算するために使用される式であるREFを

ColorF = (ColorT*opacityT + ColorB*OpacityB*(1 - OpacityT)) / factor

ColorFが最終的な色です。ColorT / ColorBは、それぞれトップカラーとボトムカラーです。 opacityT / opacityBは、それぞれ、各色に対して定義された上部と下部の不透明度です。

factorこの式で定義されますOpacityT + OpacityB*(1 - OpacityT)

2つのレイヤーを切り替えてfactorも変化しないことは明らかですが(一定のままです)、同じ乗数がないため、各色の比率が変化することがはっきりとわかります。

最初のケースでは、両方の不透明度がある0.5ため、次のようになります。

ColorF = (ColorT*0.5 + ColorB*0.5*(1 - 0.5)) / factor

上で説明したように、上の色は50%(0.5)の割合で、下の色は25%(0.5*(1-0.5))の割合であるため、レイヤーを切り替えるとこれらの比率も切り替わります。したがって、最終的な色が異なります。

ここで、2番目の例を検討すると、次のようになります。

ColorF = (ColorT*0.25 + ColorB*0.333*(1 - 0.25)) / factor

この場合0.25 = 0.333*(1 - 0.25)、2つのレイヤーを切り替えても効果はありません。したがって、色は同じままになります。

また、些細なケースを明確に特定することもできます。

  • 最上層がopacity:0式を持っているときは等しいColorF = ColorB
  • 最上層がopacity:1式を持っているときは等しいColorF = ColorT

23
@ChrisHappyは問題を解決していません;)説明しています..説明は修正よりも優れている場合があります
Temani Afif 2018年

divを互いに外し、position:absoluteをスタックに配置しても、問題は引き続き発生します。
YAHsaves 2018年

1
@YAHsavesこの問題は、複数の背景を使用したり、2つの色を互いに重ね合わせる(絶対位置を使用するかどうかに関係なく)場合でも発生します;)
TemaniAfif18年

5
TLDRを追加する場合は、加算ではなく乗法になります。
カラミリエル2018年

2
@Caramiriel:「乗法」は、操作が可換でない理由をまだ説明していません。
Eric Duminil 2018年

41

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;
}
<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>


6
このリストの「可換」であるほぼすべてのカラーブレンディングモードでうまくいきます。
サルマンA

興味深いことに、これはChromeでは機能しますが、Edgeでは機能しません(最新のWindows 10アップデートの時点)。
Hong Ooi

3
@rmvなぜオーバーレイ/通常以外のものを期待するのですか?赤いボックスの前に不透明な青いボックスを配置した場合、予想される色は何ですか?赤または青と赤の機能ではなく、青になります。
サルマンA

1
@Moffenパーフェクト答えていますが、説明のために追加してください可能性があり、なぜこの作品を、なぜ元のコードではありませんでしたか?
ベルギ2018年

1
@rmv:「通常の」ミキシングモードが最もよく模倣するのは、実際にはペイントミキシングです。たとえば、白い絵の具を取り、その半分を赤い絵の具に置き換えてから、結果のピンクの絵の具の半分を青い絵の具に置き換えると、青みがかった紫(25%白、25%赤、50%)になります。青い)。同じ白い絵の具から始めて、最初に半分を青に置き換え、次に結果の半分を赤に置き換えると、代わりに紫(25%白、25%青、50%赤)になります。
IlmariKaronen18年

22

次の順序で3つの色を混合しています。

  • 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,23。また、可換ではないため、前景色と背景色を入れ替えると、異なる結果が生成されます。

1ブレンディングモードは、前景色と背景色を受け入れ、数式を適用して、結果の色を返す関数です。

2背景と前景色の2色が与えられた場合、通常のブレンドモードは単に前景色を返します。

3オペランドの順序を変更しても結果が変わらない場合、演算は可換です。たとえば、加算は可換(1 + 2 = 2 + 1)であり、減算は可換ではありません(1-2≠2-1)。

解決策は、可換なブレンドモードを使用することです。つまり、同じ色のペアに対して任意の順序で同じ色を返すモード(たとえば、両方の色を乗算して結果の色を返す乗算ブレンドモード、または戻るブレンドモードを暗くするモード)を使用します。 2つの暗い色)。


完全を期すために、合成色を計算する式は次のとおりです。

αs x (1 - αb) x Cs + αs x αb x B(Cb, Cs) + (1 - αs) x αb x Cb

と:

Cs:前景色の色値
αs:前景色のアルファ値
Cb:背景色の
色値αb:背景色のアルファ値
B:ブレンディング関数


8

何が起こるかの説明については、TemaniAfifの回答を参照してください。
別の解決策として、aたとえば、1つのスパンを使用して配置し、内部にある場合は低いzインデックスを指定することができbます。その場合、スタッキングは常に同じになります。最初の行でb上に描画され、2番目のa行でabに描画されます。

.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;}
<span class="a"><span class="b">     Color 1</span></span>
<span class="b"><span class="a">Same Color 2</span></span>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.