Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thicker text after applying mix-blend-mode: difference

What I want to do, is to create interface that will change color, depending on the color of the background, to make text always readable. So far everything works fine. I've recorded my browser to show a working example:

enter image description here

From my research, I've discovered that the best method to achieve this, was to use mix-blend-mode: difference;. The only problem is that for some unknown reasons text is getting bold.

Originally I wanted to provide demo but mix-blend-mode is not working in the code snippet. I am not really sure why, I've seen other people using it in demos but for me, it is highlighted with red color.

Anyway, here is a picture (parts of a screenshot from a browser):

enter image description here

As you can see, after applying mix-blend-mode: difference; text is clearly thicker. Maybe it is not that big of a deal but when I apply this to smaller texts it looks really bad.

I know it is stupid but when I was trying to recreate the same effect in photoshop, everything was fine, which means that reversing colors with difference blending mode works correctly.

My question is: Can a man get the same result without inscriptions getting thicker (?) or maybe it is meant to work like that and there is nothing I can do?

I do not want to change the font style to light to force different look.

EDIT: Ok, so here is a quick example - I do not know why but this time it worked. Last time mix-blend-mode: difference; didn't work at all in demo, that's why I used images to describe my problem.

Anyway, text on the left and right side is without mix-blend-mode: difference;, to be able to see the difference. What's strange is that white version without mix-blend-mode: difference; seems to look alright - I just discovered it by adding version on a black bg.

* {
  margin: 0;
  padding: 0;
}
.white {
  background-color: #fff;
  width: 50%;
  position: absolute;
  left: 0;
  height: 100%;
}
.black {
  background-color: #000;
  width: 50%;
  position: absolute;
  right: 0;
  height: 100%;
}
.normalb {
  position: absolute;
  top: 50%;
  left: 5%;
  color: #000;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  transform: translateY(-50%);
  z-index: 10;
}
.normalw {
  position: absolute;
  top: 50%;
  right: 5%;
  color: #fff;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  transform: translateY(-50%);
  z-index: 10;
}
.difference {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  color: #fff;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  mix-blend-mode: difference;
  z-index: 10;
}
<div class="white"></div>
<div class="black"></div>
<div class="normalb">example</div>
<div class="normalw">example</div>
<div class="difference">example</div>

Here is a quick comparison on a screenshot to get a closer look:

enter image description here

Hmmm... It looks like after applying mix-blend-mode: difference; to a white text, it is being rendered like white on black but on a white background, which is weird because font remains the same, so by reversing the colors it should look like normal black on white version but it doesn't. I am confused.

like image 845
Tanuki Avatar asked Aug 25 '17 14:08

Tanuki


3 Answers

I have observed that often when applying effect properties or transforms to text: you end up with inconsistent weights appearing across browser and Chrome notoriously appearing "chubby".

I've been able to resolve this issue by applying the following properties to the affected elements.

div{ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

like image 120
EoghanTadhg Avatar answered Oct 10 '22 14:10

EoghanTadhg


I think this issue it's not related to the blending mode, but to the way fonts are rendered on the screen.

When the computer or the browser render them, they "paint" the letters' edges in a certain way to improve their legibility. They render them differently on white or on black, because the specific needs to facilitate this legibility are different. Anti-aliasing also affects because it also plays with the letterforms edges.

That's why they look different even without using the blending effect.

Unfortunately I had no idea of it and my whole design was based on this ;)

More info in here: https://www.zachleat.com/web/font-smooth/

like image 1
kram08980 Avatar answered Oct 10 '22 13:10

kram08980


It still happens to me, i found a workaround by clipping the text affected by mix-blend mode (beware of browser compatibility)

background: white;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;

Here is your snippet with clipping:

* {
  margin: 0;
  padding: 0;
}
.white {
  background-color: #fff;
  width: 50%;
  position: absolute;
  left: 0;
  height: 100%;
}
.black {
  background-color: #000;
  width: 50%;
  position: absolute;
  right: 0;
  height: 100%;
}
.normalb {
  position: absolute;
  top: 50%;
  left: 5%;
  color: #000;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  transform: translateY(-50%);
  z-index: 10;
}
.normalw {
  position: absolute;
  top: 50%;
  right: 5%;
  color: #fff;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  transform: translateY(-50%);
  z-index: 10;
}
.difference {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  color: #fff;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 42px;
  mix-blend-mode: difference;
  z-index: 10;
  background: white;
   -webkit-background-clip: text;
   -webkit-text-fill-color: transparent;
}
<div class="white"></div>
<div class="black"></div>
<div class="normalb">example</div>
<div class="normalw">example</div>
<div class="difference">example</div>
like image 1
alyustik Avatar answered Oct 10 '22 13:10

alyustik