Возможны ли пользовательские цвета смешивания в CSS?

У меня есть два div с двумя разными прозрачными цветными фонами. Элементы перекрывают друг друга.

Я хотел бы настроить цвет в области перекрытия.

Например, я смешиваю красный и синий с непрозрачностью 0.5 и хотел бы, чтобы перекрытая область была черной. Является ли это возможным? Это решение упростит реализацию функциональных возможностей.

Для лучшего понимания, например:

.wrapper{
  width: 200px;
  height: 500px;
  background-color: #fff;
  position: relative;
}
.box{
  width: 100%;
  position: absolute;
}
.box-1{
  top: 0px;
  height: 250px;
  background-color: rgba(181, 226, 163, 0.5);  
}
.box-2{
  background-color: rgba(183, 222, 241, 0.5);
  top: 200px;
  height: 300px;
}
<div class="wrapper">
  <div class="box box-1">
  </div>
  <div class="box box-2">
  </div>
</div>

Ответы

Ответ 1

Здесь используется свойство mix-blend-mode CSS со значением умножить для достижения результатов. К сожалению, это не поддерживается в IE.

<!DOCTYPE html>
<html>

  <head>
    <style>
      div{
        width:100px;
        height:100px;
        opacity:1;
      }
      .red{
        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==);
      }
      .blue{
        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg==);
        mix-blend-mode: multiply
      }
    </style>
  </head>

  <body>
    
    <div class="red">
    </div>
    <div style="position:absolute;top:90px" class="blue">
    </div>
  </body>

</html>

Ответ 2

Вы можете добиться этого эффекта, предоставив .box-1 абсолютно позиционированный псевдо-элемент ::after (расположенный в bottom:0;) с высотой, вычисленной как 100% ее родителя .box-1 минус положение вертикального смещения .box-2.

Например. Если .box-2 имеет значение top: 200px, то высота псевдоэлемента ::after на .box-1 должна быть:

height: calc(100% - 200px); /* 200px is the top: value of .box-2 */

Рабочий пример.box-1 на 4 разных высотах - последний .box-1 изменяет размер):

.wrapper{
  display: inline-block;
  width: 200px;
  height: 500px;
  background-color: #fff;
  position: relative;
}

.box{
  width: 100%;
  position: absolute;
}

.box-1{
  top: 0px;
  background-color: rgb(128,191,128);
}

.box-2{
  top: 200px;
  height: 300px;
  background-color: rgb(128,128,255);
}

.wrapper .box-1 {
z-index: 6;
}

.wrapper .box-1::after {
content: '';
position: absolute;
left: 0;
bottom: 0px;
width: 100%;
height: calc(100% - 200px); /* 200px is the top: value of .box-2 */
background-color: rgba(0,0,0,1);
}

div:nth-of-type(1).wrapper .box-1 {
height: 250px;
}

div:nth-of-type(2).wrapper .box-1 {
height: 275px;
}

div:nth-of-type(3).wrapper .box-1 {
height: 300px;
}

div:nth-of-type(4).wrapper .box-1 {
height: 325px;
}


div:nth-of-type(4).wrapper .box-1 {
resize: vertical;
overflow: auto;
}
<div class="wrapper">
  <div class="box box-1">
  </div>
  <div class="box box-2">
  </div>
</div>

<div class="wrapper">
  <div class="box box-1">
  </div>
  <div class="box box-2">
  </div>
</div>

<div class="wrapper">
  <div class="box box-1">
  </div>
  <div class="box box-2">
  </div>
</div>

<div class="wrapper">
  <div class="box box-1">
  </div>
  <div class="box box-2">
  </div>
</div>

Ответ 3

Это, вероятно, намного больше, чем вы хотели бы сделать, но я думаю, что это единственный способ получить результат, который вы ищете.

Используя javascript, вы можете в основном определить, есть ли перекрытие, и если существует div, который представляет перекрываемую область и цвет, который является черным. Ниже приведен фрагмент кода, показывающий очень простой пример.

UPDATE:

Я заметил в комментарии, что это нужно для работы с несколькими элементами, а не только с двумя элементами, поэтому я обновляю свой фрагмент для работы с несколькими элементами. Пока элемент является типом класса overlappable-box, тогда для элемента будет вычисляться перекрытие.

clearOverlaps не используется в фрагменте, но если ваша страница вообще динамична, вам нужно будет очистить любые расчетные перекрытия, которые вы можете сделать с этой функцией.

function clearOverlaps() {
  overlaps = document.getElementsByClassName("box-overlap");
  var i = 0;
  for (i = 0; i < overlaps.length; i++) {
    document.body.removeChild(overlaps[i]);
  }
}

function addOverlap(box1, box2) {
  var box1Top = box1.offsetTop;
  var box1Left = box1.offsetLeft;
  var box1Right = box1Left + box1.offsetWidth;
  var box1Bottom = box1Top + box1.offsetHeight;

  var box2Top = box2.offsetTop;
  var box2Left = box2.offsetLeft;
  var box2Right = box2Left + box2.offsetWidth;
  var box2Bottom = box2Top + box2.offsetHeight;

  var isOverlappedVertically = box1Bottom > box2Top && box1Top < box2Bottom;
  var isOverlappedHorizontally = box1Right > box2Left && box1Left < box2Right;

  if (isOverlappedVertically && isOverlappedHorizontally) {
    var overlapTop = Math.max(box1Top, box2Top);
    var overlapBottom = Math.min(box1Bottom, box2Bottom);
    var overlapLeft = Math.max(box1Left, box2Left);
    var overlapRight = Math.min(box1Right, box2Right);
    var overlap = document.createElement("div");
    overlap.className += "box-overlap";
    overlap.style.position = "absolute";
    overlap.style.left = overlapLeft + "px";
    overlap.style.width = (overlapRight - overlapLeft) + "px";
    overlap.style.top = overlapTop + "px";
    overlap.style.height = (overlapBottom - overlapTop) + "px";
    document.body.appendChild(overlap);
  }
}

var overlappableBoxes = document.getElementsByClassName("overlappable-box");
var i = 0;
var j = 0;
var box1;
var box2;
for (i = 0; i < overlappableBoxes.length; i++) {
  box1 = overlappableBoxes[i];
  for (j = i + 1; j < overlappableBoxes.length; j++) {
    box2 = overlappableBoxes[j];
    addOverlap(box1, box2);
  }
}
.overlappable-box {
  position: absolute;
}
.red-box {
  top: 0px;
  left: 40px;
  height: 50px;
  width: 50px;
  background-color: red;
  opacity: .5
}
.blue-box {
  background-color: blue;
  top: 20px;
  left: 25px;
  height: 50px;
  width: 50px;
  opacity: .5
}
.green-box {
  background-color: green;
  top: 60px;
  height: 50px;
  width: 50px;
  opacity: .5
}
.box-overlap {
  background-color: black;
  z-index: 99;
}
<div class="overlappable-box red-box"></div>
<div class="overlappable-box blue-box"></div>
<div class="overlappable-box green-box"></div>

Ответ 4

Конечно. Хотя вы можете сделать это, включив другой элемент который находится поверх перекрываемой области. Чтобы показать это, я меняю ширины и высоты div, чтобы вы могли видеть, где все границы.

Смотрите это:

div {position:absolute; border:1px solid black;}
#div1 { background:red; opacity:.5; top:0; height:110px; width:100px;}
#div2 { background:blue; opacity:.5; top:50px; height:100px;width:175px;}
#div3 { background:black; top:50px; height:50px; z-index:99; width:150px;}
<div id="div1">test</div>
<div id="div2">test</div>
<div id="div3">test</div>

Ответ 5

Я думаю, вам нужно установить непрозрачность двух ящиков, чтобы их цвета смешивались, вместо того, чтобы устанавливать непрозрачность цвета. Прозрачность rgba только облегчает или затемняет цвет, применяемый к div. По умолчанию разделители имеют непрозрачность, равную 1, поэтому, если оба поля перекрываются, тогда будет отображаться только верхняя коробка, а нижнее поле будет скрыто. Чтобы достичь желаемого, добавьте opacity:0.5 в классы .box-1 и .box-2 для применения к divs.

Ответ 6

Что-то вроде этого?

Но уверен, что это будет очень полезно, если высота динамическая

.wrapper {
  width: 200px;
  height: 500px;
  background-color: #fff;
  position: relative;
}
.box {
  width: 100%;
  position: absolute;
}
.box-1 {
  top: 0px;
  height: 250px;
  background-color: rgba(181, 226, 163, 0.5);
}
.box-2 {
  background-color: rgba(183, 222, 241, 0.5);
  top: 200px;
  height: 300px;
}
.box-2:before {
  background-color: black;
  height: 50px;
  display: block;
  content: ' ';
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <div class="wrapper">
    <div class="box box-1">
    </div>
    <div class="box box-2">
    </div>
  </div>
</body>

</html>

Ответ 7

Вы можете использовать градиенты CSS:

.box-2 {
    background-color: blue;
    top: 200px;
    height: 300px;
    background: rgb(0,0,0);
    background: -moz-linear-gradient(top, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 12%, rgba(0,0,0,1) 25%, rgba(0,0,0,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(25,33,255,1) 51%, rgba(25,33,255,1) 65%, rgba(25,33,255,1) 78%, rgba(25,33,255,1) 78%, rgba(25,33,255,1) 100%);
    background: -webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,1) 12%,rgba(0,0,0,1) 25%,rgba(0,0,0,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(25,33,255,1) 51%,rgba(25,33,255,1) 65%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 100%);
    background: linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(0,0,0,1) 12%,rgba(0,0,0,1) 25%,rgba(0,0,0,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(25,33,255,1) 51%,rgba(25,33,255,1) 65%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#1921ff',GradientType=0 );
    opacity: 0.5;
    background: rgb(0,0,0);
    background: -moz-linear-gradient(top, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 12%, rgba(0,25,255,1) 25%, rgba(0,25,255,1) 39%, rgba(0,25,255,1) 49%, rgba(0,25,255,1) 50%, rgba(0,25,255,1) 53%, rgba(0,25,255,1) 53%, rgba(25,33,255,1) 54%, rgba(0,25,255,1) 60%, rgba(25,33,255,1) 65%, rgba(25,33,255,1) 78%, rgba(25,33,255,1) 78%, rgba(25,33,255,1) 100%);
    background: -webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,1) 12%,rgba(0,25,255,1) 25%,rgba(0,25,255,1) 39%,rgba(0,25,255,1) 49%,rgba(0,25,255,1) 50%,rgba(0,25,255,1) 53%,rgba(0,25,255,1) 53%,rgba(25,33,255,1) 54%,rgba(0,25,255,1) 60%,rgba(25,33,255,1) 65%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 100%);
    background: linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(0,0,0,1) 12%,rgba(0,25,255,1) 25%,rgba(0,25,255,1) 39%,rgba(0,25,255,1) 49%,rgba(0,25,255,1) 50%,rgba(0,25,255,1) 53%,rgba(0,25,255,1) 53%,rgba(25,33,255,1) 54%,rgba(0,25,255,1) 60%,rgba(25,33,255,1) 65%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 78%,rgba(25,33,255,1) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#1921ff',GradientType=0 );
    opacity: .8; 
}

Ответ 8

попробуйте использовать этот сайт, чтобы сделать свои цвета, тогда он даст вам тег, который вам нужен.

http://www.w3schools.com/colors/colors_picker.asp