How to apply inverse text mask with CSS
Asked Answered
N

4

13

I'll try to explain my question with images. Here we go.

1 - This image shows the text masking an image, so far so good, I can do with the following code:

enter image description here

font-size: 120px;
background: url(image-to-be-masked.jpg) repeat 0 0, white;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;

2 - This other image, the text creates the opposite effect, leaving transparent only the text area. This is what I want:

enter image description here

Has anyone tried it?

Naturally answered 19/3, 2013 at 18:17 Comment(4)
Are you going to have another image behind that? Why not just color the text in white?Heavyarmed
Yes, there will be another image behind.Naturally
So you might want to try -webkit-mask-image: url(the_bg_image.png);Heavyarmed
This is not the desired effect.Naturally
H
8

I don't think CSS can do that. But you can hack it together using three different nested elements:

  • The outermost element contains the background-image
  • The middle element contains the middle image
  • The inner element contains the text, and has the same background image as the outermost element, masked with background-clip:text; like on your first example.

This works, but is a little cumbersome, as you'll have to compensate the masks background-position to achieve the desired effect. Here is an example: http://jsfiddle.net/dzkTE/.

Heavyarmed answered 19/3, 2013 at 18:58 Comment(2)
Nice, this is a solution, but I don't know if it is the best. Thanks!Naturally
It's worth mentioning that the background image (or a gradient if its used) of the clipped text needs to have the exact same origin and sizing of the main image in reference to the window. This means it has to start outside of its own bounding box and sized greater than itself in order to get the backgrounds to line up correctlyAutomation
A
4

I've managed to achieve this with a couple of different methods. See my answer here: https://mcmap.net/q/906687/-making-font-color-same-as-that-of-background-image

See Below:

There are three ways to what you're looking for in HTML/CSS/JavaScript, some a little more hacky than others.

  1. Use <canvas> to draw your shape and type, and set ctx.globalCompositeOperation="xor";where ctx is your canvas context.

var c=document.getElementById('myCanvas');
var ctx=c.getContext('2d');
ctx.font = "bold 36px Proxima Nova";
ctx.fillStyle='blue';
ctx.fillText("MORE",100,87);
ctx.globalCompositeOperation='xor';
ctx.beginPath();
ctx.fillStyle='white';
ctx.arc(150,75,75,0,2*Math.PI);
ctx.fill();
body{
  background: -webkit-radial-gradient(top left,rgb(23, 39, 34) 4%,rgb(56, 99, 99) 37%,rgb(22, 27, 15) 73%,rgb(22, 27, 14) 93%,#232323 100%);
  width:100%;
  height:100%;
}

html{
  height:100%
}
<canvas id='myCanvas'></canvas>
  1. Use mix-blend-mode: screen and set the colour of the text to black.

.blend-mode {
  background:white;
  border-radius:100%;
  width:150px;
  height:150px;
  line-height:155px;
  float:left;
  margin:20px;
  font-family: "Proxima Nova", Hevetica, sans-serif;
  font-weight:bold;
  color:black;
  text-align:center;
  vertical-align:middle;
  font-size:36px;
  mix-blend-mode: screen;
}

body{
  background: -webkit-radial-gradient(top left,rgb(23, 39, 34) 4%,rgb(56, 99, 99) 37%,rgb(22, 27, 15) 73%,rgb(22, 27, 14) 93%,#232323 100%);
  width:100%;
  height:100%;
}

html{
  height:100%;
}
<div class="blend-mode">MORE</div>
  1. Use -webkit-text-fill-color:transparent and -webkit-background-clip:text to reveal a copy of the background behind it. This one requires some alignment of the background copy to match the 'original' background.

.wrap{
  margin:20px;
  float:left;
  position:relative;
}

.background {
  width: 150px;
  height: 150px;
  border-radius: 100%;
  background: white;
  position:absolute;
  top:0;
  left:0;
  z-index:4;
  
}

.text {
  position:absolute;
  top: 25px;
  left: 25px;
  z-index:5;
  background: -webkit-radial-gradient(top left, rgb(23, 39, 34) 4%, rgb(56, 99, 99) 37%, rgb(22, 27, 15) 73%, rgb(22, 27, 14) 93%, #232323 100%);
  font-family: Proxima Nova, Helvetica, sans-serif;
  font-weight:bold;
  line-height:100px;
  font-size: 36px;
  color: #666;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

body{
  background: -webkit-radial-gradient(top left,rgb(23, 39, 34) 4%,rgb(56, 99, 99) 37%,rgb(22, 27, 15) 73%,rgb(22, 27, 14) 93%,#232323 100%);
  width:100%;
  height:100%;
}

html{
  height:100%;
}
<div class="wrap">
  <div class="background"></div>
  <div class="text">MORE</div>
</div>

None of these are likely to work that well cross browser, and I haven't tested them!

Alienage answered 9/9, 2015 at 10:3 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Finnougrian
Sure, I've added the content from the other post in here. Just didn't want to cross post.Alienage
P
4

* { margin: 0; padding: 0 }

header {
    overflow: hidden;
    height: 100vh;
    background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/2017/17_04_art_bw_butterfly_bg.jpg) 50%/ cover
}

h2 {
    color: white;
    mix-blend-mode: difference;
    font: 900 35vmin/35vh cookie, cursive;
    text-align: center
}
<header>
    <h2 contentEditable role='textbox' aria-multiline='true'>And stay alive...</h2>
</header>
Protease answered 24/5, 2019 at 5:26 Comment(0)
I
-1

[sorry i misread this. I tried out opposite, think :P] I think you can do it by using background-clip.

background-clip:text;

check here (please try in chrome or add vendor prefixes). you can check demo page form chris.

Instance answered 19/3, 2013 at 18:32 Comment(2)
This is not the desired effect. Needs to be the oposite effect.Naturally
Look this new image(ricardomasao.com/temp/stackoverflow/stack03.jpg). This is the desired effectNaturally

© 2022 - 2024 — McMap. All rights reserved.