Цвет штабелированных полупрозрачных коробок зависит от заказа?
почему окончательный цвет двух сложенных полупрозрачных коробок зависит от заказа?
Как я могу сделать так, что я получу тот же цвет в обоих случаях?
.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)) / factor
ColorF наш окончательный цвет. 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>