How to Create Knockout or Cutout Text Effect with CSS

A knockout text is a text that appears cut out so that it is possible to see the background behind it. One can get a knockout text with several methods. Some modern CSS properties can be used now and even enhance the effect further, like transitions and animations. See them in action later in this article. Now let’s discuss five methods of making knockout text.

Use background-clip and text-fill-color

Use the CSS background-clip property with its "text" value to have the background painted within the foreground text. Next, specify the fill color of characters of the text by using the text-fill-color CSS property and set the "transparent" value in order to show the background behind the text.

Firefox, Chrome, and Safari support the unofficial -webkit-background-clip: text only with the -webkit- vendor prefix.
Note that the -webkit-text-fill-color property has not been standardized yet and it will not work for all the browsers. But the performance may change in the future. This property should be used only with the -webkit- prefix.

Example of creating a knockout text effect:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      h1 {
        display: inline-block;
        margin: 0;
        line-height: 1em;
        font-weight: bold;
        font-size: 200px;
        text-align: center;
        align-items: center;
        background-image: url("/uploads/media/default/0001/02/79cd6362a06feb80e0db3f5884df2ef279310ca7.jpeg");
        background-size: 650px 450px;
        background-repeat: no-repeat;
        background-position: center;
        background-clip: text;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
      }
    </style>
  </head>
  <body>
    <h1>NEW<br>YEAR</h1>
  </body>
</html>

Result

NEW
YEAR

Here see another example which includes some illustrations of this method.

Example of creating different knockout text effects:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      *,
      :before,
      :after {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
      }
      html,
      body {
        min-height: 100%;
      }
      body {
        font-family: 'Oswald', sans-serif;
      }
      .wrapper {
        text-align: center;
      }
      /* Clip text element */
      .clip-text {
        font-size: 6em;
        font-weight: bold;
        line-height: 1;
        position: relative;
        display: inline-block;
        margin: 0.25em;
        padding: 0.5em 0.75em;
        text-align: center;
        /* Color fallback */
        color: #fff;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
      }
      .clip-text:before,
      .clip-text:after {
        position: absolute;
        content: '';
      }
      /* Background */
      .clip-text:before {
        z-index: -2;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-image: inherit;
      }
      /* Text Background */
      .clip-text:after {
        position: absolute;
        z-index: -1;
        top: 0.125em;
        right: 0.125em;
        bottom: 0.125em;
        left: 0.125em;
        background-color: #fc0;
      }
      /* Change the background position to display letter when the black zone isn't here */
      .clip-text--no-textzone:before {
        background-position: -0.65em 0;
      }
      .clip-text--no-textzone:after {
        content: none;
      }
      .clip-text-one {
        background-image: url("/uploads/media/default/0001/02/8ca4045044162379597641472fa0bb5489ba418f.jpeg");
      }
      .clip-text-two {
        background-image: url("/uploads/media/default/0001/03/6514e37cd15dbe1bca3e3b961baa3a19e2283dc3.jpeg");
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <div class="clip-text clip-text-one">JOIN US</div>
      <div class="clip-text clip-text-two clip-text--no-textzone">JOIN US</div>
    </div>
  </body>
</html>
It is recommended to use the color CSS property instead of the text-fill-color property because the color property has better browser support.

It is also possible to fix the position of the background behind the cutout text. For that purpose, the background-attachment CSS property is used with its "fixed" value. Have a look at the example below to see how to do it.

Example of creating a knockout text effect with a fixed background:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      html,
      body {
        background: #666666;
      }
      p {
        margin: 0;
      }
      #text {
        background: linear-gradient(to bottom, #eee, rgba(220, 110, 8, 0.3), #1c87c9);
        background-attachment: fixed;
        -webkit-text-fill-color: transparent;
        -webkit-background-clip: text;
        font-size: 150px;
        font-weight: bold;
        text-align: center;
      }
    </style>
  </head>
  <body>
    <p id="text">FIXED</p>
    <p id="text">FIXED</p>
    <p id="text">FIXED</p>
    <p id="text">FIXED</p>
    <p id="text">FIXED</p>
    <p id="text">FIXED</p>
  </body>
</html>

Use mix-blend-mode

Four blend modes of the mix-blend-mode property make text cutouts easily: "multiply", "screen", "darken" and "lighten". Applying these to the top element of an image and text creates the design of the knockout.

Although in most cases, in these blend modes, either black or white is used to distinguish between the text and the background clearly, I prefer using a darker or lighter color instead of making the background image slightly visible, like this:

Example of creating a cutout text effect with the mix-blend-mode property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .back {
        background: url("/uploads/media/default/0001/02/79cd6362a06feb80e0db3f5884df2ef279310ca7.jpeg") center;
        background-size: contain;
        margin: auto;
        width: 500px;
      }
      .text {
        color: #fff;
        border: 4px solid;
        background: rgb(0, 26, 0);
        mix-blend-mode: multiply;
        font: bolder 20vw sans-serif;
        text-align: center;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div class="back">
      <p class="text">NEW
        <br>YEAR</p>
    </div>
  </body>
</html>

The "multiply" blend mode keeps darker colors dark, and the lighter colors let through whatever’s behind them: a black portion on the top layer will be completely opaque and white will be completely transparent.

The blend mode "screen" reverses the roles: darker colors produce translucency while lighter shades stay light and block what lies behind.

The "darken" and "lighten" blend modes are alike to "multiply" and "screen", correspondingly, except that the details of the back image pieces that may be seen are missed. The modes choose the darker, or the lighter shade of the two layers displayed instead of mixing the shades.

Here see an example where the four modes are illustrated which will help you to know the difference between them.

Example of creating various cutout text effects with the mix-blend-mode property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .backdrop {
        background: url("/uploads/media/default/0001/01/4982c4f43023330a662b9baed5a407e391ae6161.jpeg") center;
        background-size: contain;
        margin: auto;
        margin-top: 30px;
        width: 600px;
      }
      .text {
        font: bolder 16vw "Alfa Slab One";
        text-align: center;
        margin: 0;
        border: 6px solid;
      }
      .multiply {
        color: white;
        mix-blend-mode: multiply;
        background-color: rgba(59, 2, 6, 1);
      }
      .screen {
        color: black;
        mix-blend-mode: screen;
        background-color: rgba(244, 220, 211, 1);
      }
      .darken {
        color: white;
        mix-blend-mode: darken;
        background-color: rgba(59, 2, 6, 1);
      }
      .lighten {
        color: black;
        mix-blend-mode: lighten;
        background-color: rgba(245, 220, 211, 1);
      }
    </style>
  </head>
  <body>
    <p>Multiply</p>
    <div class="backdrop">
      <p class="text multiply">NATURE</p>
    </div>
    <p>Screen</p>
    <div class="backdrop">
      <p class="text screen">NATURE</p>
    </div>
    <p>Darken</p>
    <div class="backdrop">
      <p class="text darken">NATURE</p>
    </div>
    <p>Lighten</p>
    <div class="backdrop">
      <p class="text lighten">NATURE</p>
    </div>
  </body>
</html>

You can also add a shadow blur effect to your knockout text using the text-shadow CSS property.

Example of creating a knockout text with a shadow blur effect:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .backdrop {
        background: url("/uploads/media/default/0001/01/4982c4f43023330a662b9baed5a407e391ae6161.jpeg") center;
        background-size: contain;
        margin: auto;
        margin-top: 30px;
        width: 600px;
      }
      .text {
        font: bolder 16vw "Helvetica";
        text-align: center;
        margin: 0;
        border: 6px solid;
        text-shadow: 0 0 9px white;
      }
      .darken {
        color: white;
        mix-blend-mode: darken;
        background-color: rgba(59, 2, 6, 1);
      }
    </style>
  </head>
  <body>
    <div class="backdrop">
      <p class="text darken">NATURE</p>
    </div>
  </body>
</html>

Let’s go further with the shadow idea and create an amazing animation with the knockout text. Here the animation property and @keyframes rule are added to make the animation effect.

Example of creating an animation with a knockout text:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .backdrop {
        background: url("/uploads/media/default/0001/01/4982c4f43023330a662b9baed5a407e391ae6161.jpeg") center;
        background-size: contain;
        margin: auto;
        margin-top: 50px;
        width: 600px;
      }
      .text {
        font: bolder 16vw "Alfa Slab One";
        text-align: center;
        margin: 0;
        border: 6px solid;
        animation: glow 3s infinite;
      }
      @keyframes glow {
        0% {
          text-shadow: 0 0 10px white;
        }
        15% {
          text-shadow: 2px 2px 10px rgba(255, 255, 255, 1), -2px -2px 10px rgba(255, 255, 255, 1);
        }
        30% {
          text-shadow: 2px 2px 4px rgba(255, 255, 255, .7), -2px -2px 4px rgba(255, 255, 255, .7);
        }
        50% {
          text-shadow: 20px 20px 50px rgba(255, 255, 255, .5), -20px -20px 50px rgba(255, 255, 255, .5);
        }
      }
      .darken {
        color: white;
        mix-blend-mode: darken;
        background-color: rgba(59, 2, 6, 1);
      }
    </style>
  </head>
  <body>
    <div class="backdrop">
      <p class="text darken">NATURE</p>
    </div>
  </body>
</html>

Use SVG

Below is an example that defines the bottom layer revealed by the knockout text, the middle layer we're cutting out of, and the top layer containing the SVG text that will behave as a mask to cut the second layer out.

The coordinates <text> in this example are entirely arbitrary and can be adjusted to match the exact size and positioning of the added text.

Notice that the second layer filling is black and the top layer filling is white. It's how masks work: white contrasts perfectly with black and hides the black parts.

The rest is the styling of the CSS. For instance, to get more of a dramatic effect, we may add a background gradient to the bottom layer and style up to the font size.

Example of creating a knockout text with SVG:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .knockout {
        background-image: linear-gradient(to left, red, blue);
        font-family: 'Bowlby One SC', cursive, serif;
        height: 100vh;
        text-transform: uppercase;
        width: 100%;
      }
      text:nth-child(2) {
        font-size: 5em;
      }
      text:nth-child(3) {
        font-size: 5.1em;
      }
      text:nth-child(4) {
        font-size: 12em;
      }
    </style>
  </head>
  <body>
    <div class="knockout">
      <svg class="knockout-text-container" width="100%" height="100%">
        <rect class="knockout-text-bg" width="100%" height="100%" fill="#000" x="0" y="0" fill-opacity="1" mask="url(#knockout-text)" />
        <mask id="knockout-text">
          <rect width="100%" height="100%" fill="#fff" x="0" y="0" />
          <text x="50%" y="100" fill="#000" text-anchor="middle">Knock</text>
          <text x="50%" y="175" fill="#000" text-anchor="middle">Out</text>
          <text x="50%" y="365" fill="#000" text-anchor="middle">Text</text>
        </mask>
      </svg>
    </div>
  </body>
</html>

See another example with SVG.

Example of creating a knockout text with SVG:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
        text-transform: uppercase;
        font-weight: bold;
      }
      .cake {
        background: url("/uploads/media/default/0001/03/97433bc96f2a9917e0ed141a28b6903d32f0211e.jpeg");
        background-size: cover;
        padding: 20% 0;
      }
      svg {
        display: block;
      }
    </style>
  </head>
  <body>
    <div class="cake">
      <svg viewBox="0 0 200 25">
        <rect fill="#000" x="0" y="0" width="200" height="100" fill-opacity=".9" mask="url(#text)" />
        <mask id="text">
          <rect fill="#fff" x="0" y="0" width="200" height="100"></rect>
          <text y="20" fill="#000" text-anchor="middle" x="100" font-size="25">
            Buy Cakes
          </text>
        </mask>
      </svg>
    </div>
  </body>
</html>
Do you find this helpful?

Related articles