Цвет уложенных полупрозрачных коробок зависит от заказа?
Почему конечный цвет двух уложенных полупрозрачных ящиков зависит от порядка?
Как я могу сделать это так, чтобы в обоих случаях я получил один и тот же цвет?
.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>
Ответы
Ответ 1
Просто потому, что в обоих случаях комбинация цветов не одинакова из-за того, как непрозрачность верхнего слоя влияет на цвет нижнего слоя.
В первом случае вы видите 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)
}
<span class="a"><span class="b"> Color 1</span></span>
<span class="b"><span class="a">Different Color 2</span></span>
Ответ 2
Вы можете использовать свойство 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>
Ответ 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, который не является коммутативным. А поскольку он не является коммутативным, замена цветов переднего плана и фона приведет к разным результатам.
1 Режим наложения - это функция, которая принимает цвет переднего плана и фона, применяет некоторую формулу и возвращает полученный цвет.
Решение состоит в том, чтобы использовать режим смешивания, который является коммутативным: тот, который возвращает один и тот же цвет для одной и той же пары цветов в любом порядке (например, режим смешанного смешивания, который умножает оба цвета и возвращает полученный цвет, или режим затемнения, который возвращает темный цвет двух).
$(function() {
$("#mode").on("change", function() {
var mode = $(this).val();
$("#demo").find(".a, .b").css({
"mix-blend-mode": mode
});
});
});
#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);
}
<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>
Ответ 4
Для объяснения того, что происходит, см. Ответ Темани Аффи.
В качестве альтернативного решения можно взять один интервал, a
, например, расположить его и придать ему более низкий Z-индекс, если он внутри 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;}
<span class="a"><span class="b"> Color 1</span></span>
<span class="b"><span class="a">Same Color 2</span></span>