htmlcssnavbarisolationmix-blend-mode

Make the mix-blend-mode on a sticky navbar ignore certain elements while scrolling down


<div class="navbar">
  <p>TEXT IN THE NAVBAR</p>
</div>

<div class="below-navbar"></div>

<div class="black-container">
  <p>An image I do not want to blend into the navbar:</p>
  <img src="https://media.4-paws.org/a/5/3/7/a537f08d227326121b80790ba54036498668c9c8/VIER%20PFOTEN_2016-07-08_011-4993x3455-1920x1329.jpg" alt="" class="img">
  <p>Some text I do not want to blend into the navbar</p>
</div>

<div class="white-container">
  <p>Some text I do not want to blend into the navbar</p>
</div>

<div class="black-container">
  <p>Some text I do not want to blend into the navbar</p>
</div>

<div class="white-container"></div>

<div class="black-container"></div>
.navbar {
  background-color: white;
  color: black;
  font-size: 24px;
  font-weight: bold;
  position: sticky;
  top: 0;
  height: 50px;
  z-index: 10;  
  display: flex; 
  align-items: center;
  justify-content: center;

  mix-blend-mode: difference;
}

.below-navbar {
  position: absolute;
  top: 0;
  height: 200px;
  width: 100vw;
  background-color: white;
  z-index: -1;
}

.img {
  width: 250px;
  height: 250px;
  object-fit: cover;
}

.black-container {
  height: 100vh;
  background-color: black;
  color: white;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.white-container {
  height: 100vh;
  background-color: white;
  color: black;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

Solution

  • You will need a custom solution to create this effect. For example, I added a ::before element to each container with the same sticky value and height of the header, so every time the header goes over a container, there is a sliver of just the background color in between.

    it's not the most straightforward and has some constraints but it will work.

    (open in full page to make it work with the img as well)

    :root {
      --navbar-height: 50px;
    }
    
    .navbar {
      background-color: white;
      color: black;
      font-size: 24px;
      font-weight: bold;
      position: sticky;
      top: 0;
      height: var(--navbar-height);
      z-index: 10;
      display: flex;
      align-items: center;
      justify-content: center;
      mix-blend-mode: difference;
    }
    
    .below-navbar {
      position: absolute;
      top: 0;
      height: 200px;
      width: 100vw;
      background-color: white;
      z-index: -1;
    }
    
    .img {
      width: 250px;
      height: 250px;
      object-fit: cover;
    }
    
    .black-container,
    .white-container {
      height: 100vh;
      background-color: var(--bg-color);
      color: var(--text-color);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    .black-container {
      --bg-color: black;
      --text-color: white;
    }
    
    .white-container {
      --bg-color: white;
      --text-color: black;
    }
    
    .black-container:before,
    .white-container:before {
      content: '';
      display: block;
      position: sticky;
      top: 0;
      height: var(--navbar-height);
      width: 100%;
      background: var(--bg-color);
      z-index: 5;
    }
    <div class="navbar">
      <p>TEXT IN THE NAVBAR</p>
    </div>
    
    <div class="below-navbar"></div>
    
    <div class="black-container">
      <p>An image I do not want to blend into the navbar:</p>
      <img src="https://media.4-paws.org/a/5/3/7/a537f08d227326121b80790ba54036498668c9c8/VIER%20PFOTEN_2016-07-08_011-4993x3455-1920x1329.jpg" alt="" class="img">
      <p>Some text I do not want to blend into the navbar</p>
    </div>
    
    <div class="white-container">
      <p>Some text I do not want to blend into the navbar</p>
    </div>
    
    <div class="black-container">
      <p>Some text I do not want to blend into the navbar</p>
    </div>
    
    <div class="white-container"></div>
    
    <div class="black-container"></div>