4

I'm looking for a way to change the background color of a certain element based on the background. What you can do in css with mix-blend-mode but I want to be able to set the color.

Preferable I can use the same trick with an SVG.

To show what I'm getting at here is a jsfiddle with mix-blend-mode: https://jsfiddle.net/5p69j4st/7/

.block {
  position: fixed;
  top: 10px;
  left: 10px;
  height: 25px;
  width: 25px;
  background-color: #fff;
  mix-blend-mode: difference;
}

.is-green {
  display: block;
  height: 300px;
  width: 100%;
  background-color: green;
}

.is-white {
  display: block;
  height: 300px;
  width: 100%;
  background-color: #fff;
}
<div class="block">
</div>
<div class="is-green">
</div>
<div class="is-white">
</div>
<div class="is-green">
</div>

So I want the fixed element with class block to be white when in the green.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Michiel
  • 1,061
  • 10
  • 17

1 Answers1

3

Here is a trick where you can put the coloration of the fixed element within the different block considering background-attachment:fixed

.block {
  position: fixed;
  top: 10px;
  left: 10px;
  height: 25px;
  width: 25px;
  border:1px solid;
  box-sizing:border-box;
}

.is-green {
  display: block;
  height: 300px;
  width: 100%;
  background:
    linear-gradient(#fff,#fff) 10px 10px/25px 25px fixed no-repeat,
    green;
}

.is-white {
  display: block;
  height: 300px;
  width: 100%;
  background:
    linear-gradient(#000,#000) 10px 10px/25px 25px fixed no-repeat,
    #fff;
}
body {
 padding-bottom:200px;
}
<div class="block">
</div>
<div class="is-green">
</div>
<div class="is-white">
</div>
<div class="is-green">
</div>

Of course, there 2 main drawbacks with this solutions: In case there is a content it will break the magic of the background trick and you are obliged to change the different values in different places.

To overcome this we can consider pseudo element and CSS variables:

:root {
  --t:10px;
  --l:10px;
  --h:25px;
  --w:25px;
}

.block {
  position: fixed;
  z-index:999;
  top: var(--t);
  left: var(--l);
  height: var(--h);
  width: var(--w);
  border:1px solid;
  box-sizing:border-box;
  color:red;
}

.is-green {
  display: block;
  height: 300px;
  width: 100%;
  position:relative;
  z-index:0;
  background:green;
}
.is-green::before {
  content:"";
  position:absolute;
  z-index:99;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:
    linear-gradient(#fff,#fff) var(--l) var(--t)/var(--w) var(--h) fixed no-repeat;
}

.is-white {
  display: block;
  position:relative;
  height: 300px;
  width: 100%;
  background: #fff;
  color:#000;
}
.is-white::before {
  content:"";
  position:absolute;
  z-index:99;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:
    linear-gradient(#000,#000) var(--l) var(--t)/var(--w) var(--h) fixed no-repeat;
}
body {
 padding-bottom:200px;
}
<div class="block">
Hi
</div>
<div class="is-green">
  lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum
</div>
<div class="is-white">
 lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum
</div>
<div class="is-green">
 lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum lorem pisum
</div>

Now you only need to change the color of gradient to whataver you want.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415