cssmix-blend-mode

CSS mix blend mode / only white or black


Hello I'm currently trying to find a solution to make a sticky text black if the background is white or black in any other case. During my research I found mix blend mode property but it seems very complex to make what I want.

.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 20px;
  color:white;
  font-size:60px;
  mix-blend-mode: difference;
}
.panel {
  height: 80vh;
  widht: 100%;
}

.bg-black {
  background: black;
}

.bg-red {
  background: red;
}

.bg-blue {
  background: blue;
}

.bg-green {
  background: green;
}
<div class="sticky">
  My text
</div>
<div>
  <section class="panel"></section>
  <section class="panel bg-black"></section>
  <section class="panel bg-red"></section>
  <section class="panel bg-blue"></section>
  <section class="panel bg-green"></section>
</div>

Does someone know a hack or a package that can help me?

Thanks a lot


Solution

  • I finally find something great ! It's not as beautiful as mix-blend-mode but it do the job.

    I'd prefer to stay 100% css because it require use of ScrollMagic

    const controller = new ScrollMagic.Controller();
    const sections = document.querySelectorAll('section');
    const menu = document.querySelector('.my-text');
    
    
    sections.forEach((section, index, arr) => {
      const trigger = '#' + section.id;
      const backgroundColor = window.getComputedStyle(section, null).getPropertyValue('background-color');
     
      const textColor = getContrastYIQ(backgroundColor);
    
      let previousBackgroundColor = backgroundColor;
      let previousTextColor = getContrastYIQ(previousBackgroundColor);
      
    
      if (index >= 1) {
        previousBackgroundColor = window.getComputedStyle(arr[index - 1], null).getPropertyValue('background-color');
        previousTextColor = getContrastYIQ(previousBackgroundColor);
      }
    
      new ScrollMagic.Scene({
          triggerElement: trigger,
          triggerHook: "onLeave",
          offset: -50,
          reverse: true
        })
        .on("enter", function() {
          menu.classList.remove(previousTextColor);
          menu.classList.add(textColor);
    
        })
        .on("leave", function() {
          menu.classList.remove(textColor);       menu.classList.add(previousTextColor);
    
        })
        .addTo(controller);
    })
    
    // Color contrast helper function
    // https://en.wikipedia.org/wiki/YIQ
    function getContrastYIQ(rgb) {
      rgb = rgb.substring(4, rgb.length - 1)
        .replace(/ /g, '')
        .split(',');
      const yiq = ((rgb[0] * 299) + (rgb[1] * 587) + (rgb[2] * 114)) / 1000;
      return (yiq >= 128) ? 'black' : 'white';
    }
    section {
      min-height: 80vh;
    }
    
    .my-text {
      position: sticky;
      top: 5vh;
      color: white;
    }
    
    .black {
        color: black;
        &:before {
          background: black;
          box-shadow: 0 0.4em 0 0 black, 0 0.80em 0 0 black;
        }
     }
    
    #s1 {
      background-color: black;
    }
    
    #s2 {
      background-color:  white;
    }
    
    #s3 {
      background-color: #111;
    }
    
    #s4 {
      background-color: #9f3;
    }
    
    #s5 {
      background-color: #145;
    }
    
    #s6 {
      background-color: #f5f; 
    }
    <script ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js"></script>
    <div class="my-text">
      MY TEXT</div>
    <section id="s1">
    </section>
    <section id="s2"></section>
    <section id="s3"></section>
    <section id="s4"></section>
    <section id="s5"></section>
    <section id="s6"></section>