How to use mix-blend-mode to change text color on an animated background

184 Views Asked by At

I have a codepen with 4 boxes,

each box has a text on top of a moving background svg. I am using mix-blend-mode to invert the colors of the text when the background changes. For example, if the background is red, the text should be yellow, if the background is yellow, the text should be red.

My problem:

  1. It seems like the technique is not working with chrome
  2. It seems like the technique is not working with hex colors. Am i missing a point, or is this a bug?

Working codepen: https://codepen.io/nicopoggenburg/pen/xxmaeGw

Left side chrome, right side firefox

Mac Firefox: No, Mac Chrome: No

.box-1 {
  --light: #FCFAF0;
  --dark: #082605;
}

Mac Firefox: Yes, Mac Chrome: No

.box-2 {
  --light: yellow;
  --dark: red;
}

Mac Firefox: No, Mac Chrome: No

.box-3 {
  --light: #66CDAA;
  --dark: #FFA500;
}

Mac Firefox: Yes, Mac Chrome: No

.box-4 {
  --light: green;
  --dark: purple;
}

HTML:

<div class="box box-1">
  <div class="svgs">
    <div class="svg-container">
      <svg class="svg svg-1" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="#082605" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
    <div class="svg-container">
      <svg class="svg svg-2" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="#082605" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
  </div>
  <h1 class="text" data-text="Do reinvent the wheel">Do reinvent<br>the wheel</h1>
</div>

<div class="box box-2">
  <div class="svgs">
    <div class="svg-container">
      <svg class="svg svg-1" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="red" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
    <div class="svg-container">
      <svg class="svg svg-2" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="red" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
  </div>
  <h1 class="text" data-text="Do reinvent the wheel">Do reinvent<br>the wheel</h1>
</div>

<div class="box box-3">
  <div class="svgs">
    <div class="svg-container">
      <svg class="svg svg-1" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="#FFA500" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
    <div class="svg-container">
      <svg class="svg svg-2" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="#FFA500" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
  </div>
  <h1 class="text" data-text="Do reinvent the wheel">Do reinvent<br>the wheel</h1>
</div>

<div class="box box-4">
  <div class="svgs">
    <div class="svg-container">
      <svg class="svg svg-1" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="purple" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
    <div class="svg-container">
      <svg class="svg svg-2" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="purple" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
  </div>
  <h1 class="text" data-text="Do reinvent the wheel">Do reinvent<br>the wheel</h1>
</div>

CSS:

@keyframes moveWave {
  to {
    transform: translateX(-50%);
  }
}


.box-1 {
  --light: #FCFAF0;
  --dark: #082605;
}
.box-2 {
  --light: yellow;
  --dark: red;
}
.box-3 {
  --light: #66CDAA;
  --dark: #FFA500;
}
.box-4 {
  --light: green;
  --dark: purple;
}

.box {
  position: relative;
  overflow: hidden;
  background: var(--light);
  color: var(--light);
  padding: 20px 0;
  isolation: isolate;
}
.svgs {
  display: flex;
  width: 200%;
  animation: moveWave 5s linear infinite;
  display: flex;
  align-items: center;
}
.svg-container {
  width: 100%;
}
.svg {
  width: 100%;
}
.text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  font-size: 90px;
  text-transform: uppercase;
  margin: 0;
  mix-blend-mode: difference;
  font-weight: 800;
  width: fit-content;
  color: var(--dark);
}

.text:after {
  content: attr(data-text);
  mix-blend-mode: difference;
  position: absolute;
  left: 0;
  top: 0;
  color: var(--light);
}
1

There are 1 best solutions below

1
imhvost On

It is necessary to once again display the text with the second color (for example, using .text:after) and apply mix-blend-mode: difference;:

@keyframes moveWave {
  to {
    transform: translateX(-50%);
  }
}

:root {
  --light: yellow;
  --dark: red;
}
.box {
  position: relative;
  overflow: hidden;
  background: var(--light);
  color: var(--light);
  padding: 20px 0;
}
.svgs {
  display: flex;
  width: 200%;
  animation: moveWave 5s linear infinite;
  display: flex;
  align-items: center;
}
.svg-container {
  width: 100%;
}
.svg {
  width: 100%;
}
.text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  font-size: 90px;
  text-transform: uppercase;
  margin: 0;
  mix-blend-mode: difference;
  font-weight: 800;
  width: fit-content;
  color: var(--dark);
}

.text:after {
  content: attr(data-text);
  mix-blend-mode: difference;
  position: absolute;
  left: 0;
  top: 0;
  color: var(--light);
}
<div class="box">
  <div class="svgs">
    <div class="svg-container">
      <svg class="svg svg-1" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="red" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
    <div class="svg-container">
      <svg class="svg svg-2" viewBox="0 0 1024 244" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M1029 59.77c-258.25 0-258.25 124.62-516.5 124.62S254.25 59.77-4 59.77" stroke="red" stroke-width="118.634" stroke-miterlimit="10"/>
      </svg>
    </div>
  </div>
  <h1 class="text" data-text="Do reinvent the wheel">Do reinvent<br>the wheel</h1>
</div>