Transparent text cut from background

Is there a way to make transparent text cut from a background effect like the one shown in the following image using CSS?
It would be sad to lose all precious SEO due to images replacing text.

Transparent text cut out of background

At first I thought about shadows, but I canโ€™t understand anything ...

The image is the background of the site, the absolute positioned <img>

+72
css fonts css3 css-shapes svg
Dec 18 '12 at 12:24
source share
10 answers

This is possible with css3, but not supported in all browsers

With background clip: text; you can use the background for the text, but you have to align it with the background of the page

 body { background: url(http://www.color-hex.com/palettes/26323.png) repeat; margin:10px; } h1 { background-color:#fff; overflow:hidden; display:inline-block; padding:10px; font-weight:bold; font-family:arial; color:transparent; font-size:200px; }span { background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat; -webkit-text-fill-color: transparent; -webkit-background-clip: text; display:block; } 
 <h1><span>ABCDEFGHIKJ</span></h1> 

http://jsfiddle.net/JGPuZ/1/

Auto leveling

with a little javascript you can align the background automatically:

 $(document).ready(function(){ var position = $("h1").position(); //Position of the header in the webpage var padding = 10; //Padding set to the header var left = position.left + padding; var top = position.top + padding; $("h1").find("span").css("background-position","-"+left+"px -"+top+"px"); }); 
 body { background: url(http://www.color-hex.com/palettes/26323.png) repeat; margin:10px; } h1 { background-color:#fff; overflow:hidden; display:inline-block; padding:10px; font-weight:bold; font-family:arial; color:transparent; font-size:200px; }span { background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat; -webkit-text-fill-color: transparent; -webkit-background-clip: text; display:block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h1><span>ABCDEFGHIKJ</span></h1> 
http://jsfiddle.net/JGPuZ/2/
+38
Dec 18 '12 at 12:49
source share

While this is possible with CSS, a better approach would be to use inline SVG with SVG masking . This approach has some advantages over CSS:

CodePen Demo: SVG Text Mask

transparent text clipping background

 body,html{height:100%;margin:0;padding:0;} body{ background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg'); background-size:cover; background-attachment:fixed; } svg{width:100%;} 
 <svg viewbox="0 0 100 60"> <defs> <mask id="mask" x="0" y="0" width="100" height="50"> <rect x="0" y="0" width="100" height="40" fill="#fff"/> <text text-anchor="middle" x="50" y="18" dy="1">SVG</text> <text text-anchor="middle" x="50" y="30" dy="1">Text mask</text> </mask> </defs> <rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/> </svg> 

If you want to make text available and searchable, you need to include it outside the <defs> . The following example shows a way to do this while maintaining transparent text with a <use> :

 body,html{height:100%;margin:0;padding:0;} body{ background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg'); background-size:cover; background-attachment:fixed; } svg{width:100%;} 
 <svg viewbox="0 0 100 60"> <defs> <g id="text"> <text text-anchor="middle" x="50" y="18" dy="1">SVG</text> <text text-anchor="middle" x="50" y="30" dy="1">Text mask</text> </g> <mask id="mask" x="0" y="0" width="100" height="50"> <rect x="0" y="0" width="100" height="40" fill="#fff"/> <use xlink:href="#text" /> </mask> </defs> <rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/> <use xlink:href="#text" mask="url(#mask)" /> </svg> 
+39
Apr 20 '15 at 12:18
source share

One of the ways that works in most modern browsers (except the edge), albeit with a black background, is to use

 background: black; color: white; mix-blend-mode: multiply; 

in your text element, and then put any background there. Multiplication basically maps the color code 0-255 to 0-1, and then multiplies it by what is behind it, so black stays black and white, multiplies by 1 and effectively becomes transparent. http://codepen.io/nic_klaassen/full/adKqWX/

+12
Jan 30 '16 at
source share

Perhaps, but so far only with Webkit-based browsers (Chrome, Safari, Rockmelt, everything based on the Chromium project.)

The trick is to have an element in white that has the same background as the body, and then use -webkit- background-clip: text; for the inner element, which basically means "do not expand the background outside the text" and use transparent text.

 section { background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg); width: 100%; height: 300px; } div { background: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 0); width: 60%; heighT: 80%; margin: 0 auto; font-size: 60px; text-align: center; } p { background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg); -webkit-background-clip: text; }โ€‹ 

http://jsfiddle.net/BWRsA/

+3
Dec 18 '12 at 12:37
source share

I think you could achieve something like using background-clip , but I have not tested this yet.

See this example:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(Webkit only, I still don't know how to change the black background to white)

+2
Dec 18 '12 at 12:37
source share

You can use the myadzel Patternizer jQuery plugin to achieve this effect in browsers. There is currently no cross-browser way to do this with CSS only.

You use Patternizer by adding class="background-clip" to the HTML elements where you want the text to be drawn as an image template and specify the image in the additional attribute data-pattern="โ€ฆ" . See Source Demo . Patternizer will create an SVG image with the text filled in the image and place it on a transparently displayed HTML element.

If, as in the image of the example question, the text fill pattern should be part of the background image that goes beyond the "patterned" element, I see two options (untested, my favorite first):

  • Use masking instead of background image in SVG. As in the answer of the web tick , to which with the help of Patternizer automatic generation of SVG and an invisible HTML element will be added on top, which allows you to select and copy text.
  • Or use automatic image alignment template. Can be done with JavaScript code similar to the one specified in the Gijs answer .
+1
Oct 17 '15 at 15:05
source share

You can use the inverted / negative / reverse font and apply it using the CSS rule font-face="โ€ฆ" . You may need to play with the letter spacing to avoid small white spaces between the letters.

If you donโ€™t need a specific font, itโ€™s easy. Download your favorite, for example, from the collection of inverted fonts .

If you need a specific font (say, "Open Sans"), it's hard. You must convert the existing font to an inverted version. This can be done manually using Font Creator, FontForge, etc., But, of course, we want an automatic solution. I could not find instructions for this yet, but some tips:

+1
Oct 17 '15 at 15:23
source share

Demo screenshot

I needed to make a text that looked the same as in the original post, but I couldnโ€™t just fake it by lining up the backgrounds, because there is animation around the element. Nobody seems to have suggested this, so here is what I did: (I tried to do as easily as possible.)

 var el = document.body; //Parent Element. Text is centered inside. var mainText = "THIS IS THE FIRST LINE"; //Header Text. var subText = "THIS TEXT HAS A KNOCKOUT EFFECT"; //Knockout Text. var fontF = "Roboto, Arial"; //Font to use. var mSize = 42; //Text size. //Centered text display: var tBox = centeredDiv(el), txtMain = mkDiv(tBox, mainText), txtSub = mkDiv(tBox), ts = tBox.style, stLen = textWidth(subText, fontF, mSize)+5; ts.color = "#fff"; ts.font = mSize+"pt "+fontF; ts.fontWeight = 100; txtSub.style.fontWeight = 400; //Generate subtext SVG for knockout effect: txtSub.innerHTML = "<svg xmlns='http://www.w3.org/2000/svg' width='"+stLen+"px' height='"+(mSize+11)+"px' viewBox='0 0 "+stLen+" "+(mSize+11)+"'>"+ "<rect x='0' y='0' width='100%' height='100%' fill='#fff' rx='4px' ry='4px' mask='url(#txtSubMask)'></rect>"+ "<mask id='txtSubMask'>"+ "<rect x='0' y='0' width='100%' height='100%' fill='#fff'></rect>"+ "<text x='"+(stLen/2)+"' y='"+(mSize+6)+"' font='"+mSize+"pt "+fontF+"' text-anchor='middle' fill='#000'>"+subText+"</text>"+ "</mask>"+ "</svg>"; //Relevant Helper Functions: function centeredDiv(parent) { //Container: var d = document.createElement('div'), s = d.style; s.display = "table"; s.position = "relative"; s.zIndex = 999; s.top = s.left = 0; s.width = s.height = "100%"; //Content Box: var k = document.createElement('div'), j = k.style; j.display = "table-cell"; j.verticalAlign = "middle"; j.textAlign = "center"; d.appendChild(k); parent.appendChild(d); return k; } function mkDiv(parent, tCont) { var d = document.createElement('div'); if(tCont) d.textContent = tCont; parent.appendChild(d); return d; } function textWidth(text, font, size) { var canvas = window.textWidthCanvas || (window.textWidthCanvas = document.createElement("canvas")), context = canvas.getContext("2d"); context.font = size+(typeof size=="string"?" ":"pt ")+font; return context.measureText(text).width; } 

Just drop it in the window.onload window, set the body background to your image and see how the magic happens!

+1
Nov 23 '16 at 8:34
source share

Impossible with CSS I'm afraid right now.

Itโ€™s best to just use an image (possibly PNG) and place a nice alt / title text on it.

Alternatively, you can use SPAN or DIV and have an image as a background for your text, which you want to use for SEO purposes inside it, but with text indent from the screen.

0
Dec 18 '12 at 12:27
source share

just put this css

  .banner-sale-1 .title-box .title-overlay { font-weight: 900; overflow: hidden; margin: 0; padding-right: 10%; padding-left: 10%; text-transform: uppercase; color: #080404; background-color: rgba(255, 255, 255, .85); /* that css is the main think (mix-blend-mode: lighten;)*/ mix-blend-mode: lighten; } 
0
Sep 22 '17 at 6:29
source share



All Articles