htmlcssblendingmix-blend-mode

How to only blend background of <section> but not the content


My website is made up of several sections. I'm looking for a way to only blend the background of one of these sections, but not have it affect the section content.

.bg {
  background-color: darkslategray;
  height:80vh;
}

.section {
  background: linear-gradient(
    124deg,
    rgba(89, 73, 219, 1) 0%,
    rgba(215,234,255,1) 100%
   ); 
  mix-blend-mode: multiply;
}

.text-white {
  color: white;
  text-align: center;
}
<div class="bg">
    <section class="section">
           <div id="content">
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
           </div>
    </section>
</div>

As you can see, the text is clearly affected, I'd love for the text to remain white.

The problem is, if I move the background gradient and blend mode to one of the divs, it stops working. The way I set up my page it needs to happen on the section level, but I cannot figure out how to stop the content from also blending.

I tried isolation, which didn't work.


Solution

  • You could use a pseudo-element to create the desired background.
    This way, the mix-blend-mode only applies to the pseudo-element itself.

    The important part is the position: relative; on the #content element, which creates a new stacking context and thus puts the content "in front" of the pseudo-element and its background.

    .bg {
      background-color: darkslategray;
      height: 80vh;
    }
    
    .section {
      position: relative;
    }
    
    .section::before {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(
        124deg,
        rgba(89, 73, 219, 1) 0%,
        rgba(215,234,255,1) 100%
       );
      mix-blend-mode: multiply;
    }
    
    #content {
      position: relative; /* create new stacking context */
    }
    
    .text-white {
      color: white;
      text-align: center;
    }
    <div class="bg">
        <section class="section">
           <div id="content">
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
               <div class="text-white">TEST</div>
           </div>
        </section>
    </div>