Home > OS >  Clippingmask from text and its parent div
Clippingmask from text and its parent div

Time:09-30

I've seen a few people ask this question, but it's always closed and redirected to a similar question (that is different).

The question is: How do you make a clipping mask from text and the closest parent div of the text element? Not to confuse with how do you make a clipping mask from text and the text background.

Any help is much appreciated. If you can make knockout text in a parent div that would bring amazing versatility!

Thanks!

CodePudding user response:

The background-clip: text property cuts everything except the text away from the background, leaving the text colored/filled with the background color/image. (If you set text color to transparent of course.)

You want the opposite of that. But since there is no true inverse of background-clip: text, you can use the trick they use here.

Method 1: CSS trick to make it look like cut-out text

What it does is making you think the text is transparent by filling/coloring it with the same background and putting some other content in between to make the distinction.

On your screen you would see for example:

  1. Red background. (Created with a ::after element.)
  2. A smaller black element (leaving the red background element visible around it). (Created with ::before element.)
  3. Red text on top. (The original element.)

Now it seems that the text is transparent, because it has the same fill as the red background element. So the trick is to have text and the background have the same fill and size and position the fill the same way.

Working example:

/*
  Contains only the text that is
  filled/colored with the background.
*/
.cut-out-text {
    position: relative;
    font-size: 100px;
    font-weight: bold;
    padding: 50px;
    background: linear-gradient(to right, red, blue);
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
}

/*
  Layer in between. (Black in this case.)
    This layer is sized just a bit smaller than the
    container to leave the `::after` visible around.
*/
.cut-out-text::before {
    content: '';
    display: inline-block;
    position: absolute;
    z-index: -1;
    top: 10px;
    right: 10px;
    bottom: 10px;
    left: 10px;
    background: #000;
}

/*
  Layer that repeats the original background
    and appears to be the real background,
  making it look like the text is cut out.
*/
.cut-out-text::after {
    content: '';
    display: inline-block;
    position: absolute;
    z-index: -2;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: inherit;
    background-image: inherit;
}
<div class="cut-out-text">Hello World</div>

Method 2: Using SVG

If the background isn't as straightforward as a color or linear gradient, you can use a SVG image to put over the background.

The contents of this SVG would, for example, be a full-sized <rect> with a mask or clipping path.

This mask or clipping path would contain a black-and-white contents of which parts of the rect should be shown.

In this mask you could put text to have that be cut out. See examples here.

Tip: If you don't want just a full-sized black <rect> with the text cut out as overlapping content, you can also use a <foreignObject> with regular HTML inside (which can be styling using CSS classes, etc). (See this JSFiddle example.)

#some-header-background {
    width: 100%;
    height: 100px;
    background: linear-gradient(to right, red, blue);
}

#overlapping-content-with-text-cut-out {
    width: 100%;
    height: 100%;
}

text.cut-out-text {
    font: bold 60px sans-serif;
}
<div id="some-header-background">
  
  <svg id="overlapping-content-with-text-cut-out" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <mask id="cut-out-text">
        <rect x="0" y="0" width="100%" height="100%" fill="white" />
        <text class="cut-out-text"
          fill="black"
          x="0%" y="100%"
        >Hello World</text>
        <!--
           More about styling and position text in SVG:
           https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text
           https://developer.mozilla.org/en-US/docs/Web/SVG/Element/tspan
        -->
      </mask>
    </defs>

    <rect x="0" y="0" width="100%" height="100%" mask="url(#cut-out-text)" />
    <!-- OR use HTML for overlapping content: -->
    <!--
    <foreignObject x="0" y="0" width="100%" height="100%" mask="url(#cut-out-text)">
      <div class="overlapping-content">Overlapping</div>
    </foreignObject>
    -->
  </svg>
  
</div>

For other methods have a look at this question.

  • Related