Transparent text cut out of background

It's possible with css3 but it's not supported in all browsers

With background-clip: text; you can use a background for the text, but you will 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/1337/


Automatic Alignment

With a little javascript you can align the background automatically:

$(document).ready(function(){
  //Position of the header in the webpage
  var position = $("h1").position();
  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/1336/


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

  • Much better browser support: IE10+, chrome, Firefox, safari...
  • This doesn't impact SEO as spiders can crawl SVG content (google indexes SVG content since 2010)

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 aim on making the text selectable and searchable, you need to include it outside the <defs> tag. The following example shows a way to do that keeping the transparent text with the <use> tag:

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>

One way that works on most modern browsers is to use

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

for transparent text on a black background, or

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

for transparent text on a white background.

enter image description here

For this to work in chrome, you also need to set any background colour on the html element.

Put these styles on your text element and then put whatever background you want behind that. Multiply basically maps the 0-255 color code to 0-1 and then multiplies that by whatever is behind it, so black stays black and white multiplies by 1 and effectively becomes transparent. Screen is effectively the opposite for this case. http://codepen.io/nic_klaassen/full/adKqWX/


It is possible, but so far only with Webkit based browsers (Chrome, Safari, Rockmelt, anything based on the Chromium project.)

The trick is to have an element within the white one that has the same background as the body, then use -webkit- background-clip: text; on the inner element which basically means "don't extend the background beyond 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/


I just discovered a new way to do this while messing around, I'm not entirely sure how it works ( if someone else wants to explain please do ).

It seems to work very well, and requires no double backgrounds or JavaScript.

Here's the code: JSFIDDLE

body {
  padding: 0;
  margin: 0;
}

div {
  background: url(http://www.color-hex.com/palettes/26323.png) repeat;
  width: 100vw;
  height: 100vh;
}

body::before {
  content: '$ALPHABET';
  left: 0;
  top: 0;
  position: absolute;
  color: #222;
  background-color: #fff;
  padding: 1rem;
  font-family: Arial;
  z-index: 1;
  mix-blend-mode: screen;
  font-weight: 800;
  font-size: 3rem;
  letter-spacing: 1rem;
}
<div></div>