Цвет штабелированных полупрозрачных коробок зависит от заказа?
почему окончательный цвет двух сложенных полупрозрачных коробок зависит от заказа?
Как я могу сделать так, что я получу тот же цвет в обоих случаях?
.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>4 ответа:
просто потому, что в обоих случаях сочетание цветов не то же самое, так как непрозрачность самой top слой влияет на цвет дно слой.
в первом случае, вы видите 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>в качестве примечания, белый фон также влияет на рендеринг цветов. Его доля составляет 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%*/ }<span class="a"><span class="b"> Color 1</span></span> <span class="b"><span class="a">Different Color 2</span></span>общий тривиальный случай, когда верхний слой имеет
opacity:1которые делают верхний цвет с пропорцией 100%; таким образом это непрозрачного цвета.
для более точного и точного объяснения вот формула, используемая для расчета цвета, который мы видим после комбинации обоих слоев ref:
ColorF = (ColorT*opacityT + ColorB*OpacityB*(1 - OpacityT)) / factorColorF наш окончательный цвет. ColorT/ColorB соответственно верхние и нижние цвета. opacityT/opacityB соответственно верхняя часть и дно помутнения, определенные для каждого цвета:
The
factorопределяется по формулеOpacityT + OpacityB*(1 - OpacityT).ясно, что если мы переключим два слоя
factorне изменится (он останется постоянным), но мы ясно видим, что пропорция для каждого цвета изменится, так как у нас нет одного и того же множителя.для нашего начального случая, оба помутнения
0.5так что у нас будет:ColorF = (ColorT*0.5 + ColorB*0.5*(1 - 0.5)) / factorкак объяснено выше, верхний цвет имеет доля 50% (
0.5) и нижний имеет долю 25% (0.5*(1-0.5)) таким образом, переключение слоев также переключит эти пропорции; таким образом, мы видим другое финал цвета.теперь, если мы рассмотрим второй пример мы имеем:
ColorF = (ColorT*0.25 + ColorB*0.333*(1 - 0.25)) / factorв этом случае мы имеем
0.25 = 0.333*(1 - 0.25)таким образом, переключение двух слоев не будет иметь никакого эффекта; таким образом, цвет останется прежним.мы также можем четко определить тривиально случаи:
- когда верхний слой имеет
opacity:0формула равнаColorF = ColorB- когда верхний слой имеет
opacity:1формула равнаColorF = ColorT
добавить свойство 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>
вы смешиваете три цвета в следующем порядке:
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>
для полноты, вот формула для расчета составных цвет:
αs x (1 - αb) x Cs + αs x αb x B(Cb, Cs) + (1 - αs) x αb x CbС:
Cs: цветовое значение цвета переднего плана
как: альфа-значение цвета
Cb: значение цвета фона
ab: Альфа-значение цвета фона B: функция смешивания
для объяснения того, что происходит, см. ответ Темани Афифа.
В качестве альтернативного решения, вы можете взять один пролет,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>