How to Apply Mix-Blend-Mode While Keeping Text Opaque

How to apply mix-blend-mode while keeping text opaque?

You may use pseudo element and apply mix-blend-mode: multiply on it like this :

.bg {  background-image: url('https://images.unsplash.com/photo-1501706362039-c06b2d715385?auto=format&fit=crop&w=1070&q=60&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D');  background-repeat: no-repeat;  background-position: center center;  padding: 100px 50px;}
.text { position: relative;}
.text:before { content: ""; position: absolute; top: 0; right: 0; left: 0; bottom: 0; background: #ed1c24; mix-blend-mode: multiply; z-index: 0;}
.text p { font-family: "Helvetica"; font-weight: bold; font-size: 32px; color: #fff; margin: 0; padding: 40px; z-index: 2; position: relative;}
<div class="bg">  <div class="text">    <p>      These artistic movements were a refelection of the million of people who lived and worked here. To them, "I ❤ NY" could be read as a rallying cry.    </p>  </div></div>

Is it possible to use mix-blend-mode to blur a background while ignoring an opaque layer?

The semi transparent overlay will always add shade to entire card. We can have same image in the overlay and fade it there.

html,
body {
min-height: 100vh;
display: flex;
flex-direction: column;
webkit-font-smoothing: antialiased;
moz-osx-font-smoothing: grayscale;
font-family: 'Squada One', sans-serif !important;
}

body::before {
content: '';
background: black background-attachment: fixed;
background-repeat: no-repeat;
background-size: cover;
overflow: hidden;
position: fixed;
z-index: -1;
filter: blur(2.5px);
width: 100vw;
height: 100vh;
transform: scale(1.1);
}

.parenttile {
margin: 0 auto;
text-align: center;
display: flex;
align-items: center !important;
}

.link_wrapper2 {
width: auto;
padding: 0px;
}

.boxborder {
border-color: blue;
border-width: 0.3em;
border-style: solid;
border-radius: 15px !important;
}

.front {
position: relative;
z-index: 2 !important;
}

.blend {
text-shadow: 0 2px 2px #fdee00;
-webkit-filter: invert(100%);
filter: invert(100%);
mix-blend-mode: lighten;
}

.img1 {
background-image: url("https://images.unsplash.com/photo-1641225635705-139a1a5e3938?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=261&q=80");
}

.img2 {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_02.jpg");
}

.img3 {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_01.jpg");
}

.test-box {
background-size: 101% 101%;
background-repeat: no-repeat;
height: 150px;
border-radius: 15px !important;
position: relative;
}

.test-box::before {
content: ' ';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 15px !important;
background-size: 100% 100%;
background-repeat: no-repeat;
background-color: #faa4;
/*blending #faa4 with background image to make it look fade out*/
background-blend-mode: lighten;
}

/*add image to the pseudo element and then fade it*/

.img1.test-box:before {
background-image: url("https://images.unsplash.com/photo-1641225635705-139a1a5e3938?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=261&q=80");
}

.img2.test-box:before {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_02.jpg");
}

.img3.test-box:before {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_cat_bg_01.jpg");
}

header.blending {
color: white;
text-shadow: 0 3px 1px orange;
mix-blend-mode: difference;
font-size: 5rem;
font-weight: bolder;
filter: saturate(4);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="columns is-centered desktop front">
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img1 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img2 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
<div class="column is-4">
<div class="tile is-ancestor parenttile ml-3 mr-3">
<div class="tile is-12 is-parent">
<div class="tile is-child box test-box img3 boxborder has-text-white has-text-centered" style="overflow:hidden;">
<a href="#">
<header class="blending">Contra..</header>
</a>
</div>
</div>
</div>
</div>
</div>

Using mix-blend-mode to knock out a shape from it's parent, while keeping sibling text normal

You can do this with radial-gradient and masking. No mix-blend-mode and extra element needed.

.bg {
background: #666;
height: 100vh;
padding: 50px;
}

.flag {
background-color: white;
/* mix-blend-mode: screen; */
height: auto;
padding: 20px;
width: 400px;
overflow: hidden;
position: relative;
--mask: radial-gradient(circle at calc(100% + 60px) 50%, transparent 0 87.5px, red 88.5px 100%) 0 0/100% 100% no-repeat;
-webkit-mask: var(--mask);
mask: var(--mask);
}

.flag p {
font-family: 'Helvetica Neue LT Std 47 Light Condensed', Helvetica, Arial, Lucida, sans-serif;
color: #58595B!important;
font-size: 16px;
}

.green {
color: #B3BE35;
}
<div class="bg">
<div class="flag">
<p>
In this example <strong class="green">the text needs to be normal</strong> and the mix-blend-mode should only apply to the circle cutting out the right side of the "flag".
</p>
</div>
</div

Mix blend mode background with child content unaffected

As I already explained in this previous answer, isolation will not work this way and you cannot isolate the content after applying mix-blend-mode

On idea of fix is to consider background-blend-mode with multiple background. This will only affect the background and not the content and you will have a reduced code.

.bkg-image {  background:     linear-gradient(#323ff0,#323ff0) center/100% calc(100% - 100px) no-repeat,    url(https://poppyvine.com/wp-content/uploads/2019/04/beach-bw.jpg) center/cover;  text-align: center;  background-blend-mode: multiply;  padding: 100px 0px;}
.bkg-image .content { color: #fff;}
<div class="bkg-image">    <div class="content">      <h1>Margins to show bkg img<br>&<br>Content unaffected by blend mode</h1>    </div></div>

Mix blend mood with black text

You need to make a container for the whole page then set its background color in CSS to something, like white. Here's an example

.nav {  width: 95vw;  display: flex;  justify-content: space-between;  font-size: 3vw;  mix-blend-mode: difference;  position: fixed;  top: 0;}.nav__item {  color: #fff;  text-decoration: none;  text-transform: uppercase;}
.container {background-color: white;height: 100%;width: 100%;}
<div class="container"><nav class="nav">  <a href="" class="nav__item">home</a>  <a href="" class="nav__item">articles</a>  <a href="" class="nav__item">info</a></nav>
<section class="hero"> <img src="https://images.unsplash.com/photo-1589362086172-2c29bea70386?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80" alt="Sample Image"></section>
Run code snippet </div>

CSS mix blend mode / only white or black

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>

Exclude text from blending CSS-blending

Use a pseduo-element and apply the blend-mode to that instead of the parent div.

div.header {  width: 100%;  height: 300px;  background-image: url(http://www.eikongraphia.com/wordpress/wp-content/BIG_Zira_Island_Copyright_BIG_1_Small.jpg);}div.info-bol {  width: 200px;  height: 200px;  border-radius: 50%;  text-align: center;  position: relative;}div.info-bol::before {  content: '';  position: absolute;  top: 0;  left: 0;  right: 0;  bottom: 0;  border-radius: 50%;  background-color: red;  mix-blend-mode: multiply;}div.info-bol span {  position: relative;  top: 22%;  font-size: 30px;  font-weight: bold;  color: white;}
<div class="header">  <div class="info-bol">    <span>samenwerken<br>is meer dan<br>samen<br>werken</span>  </div></div>


Related Topics



Leave a reply



Submit