htmlcssradial-gradientscss-mask

How to use radial-gradient inside an -webkit-mask to make 3 transparent holes but keeping image


I'm working on a project where I need to make a div that must have 3 random holes on the borders, making them transparent.

The issue I'm facing is, to 2 holes i'm using -webkit-mask with radial-gradient to create 2 transparent holes of 20px. My problem is when i'm trying to create a third hole, does anyone have any idea how to do this?

<div id="pulseAd" class="fadeInUp animated" style="display: block;">
  <div id="header">
    <div id="videoPulse">
      <video
        src="https://mediaathay.org.uk/2/13/62/82/@/Simo-10S-Web-Device-2022-06-29--2--1.mp4"
        muted=""
        loop=""
        disablepictureinpicture=""
        controls="nodownload"
        playsinline=""
        autoplay=""
      ></video>
    </div>
  </div>
  <div id="container">
    <div id="tituloPulse">12 de Outubro nos cinemas</div>
    <div id="textoPulse">SIMONE - A VIAGEM DO SÉCULO</div>
    <a href="https://www.google.com" target="_blank">
      <div id="ctaPulse">Veja o trailer</div>
    </a>
  </div>

  <a id="closePulse"></a>

  <style id="pulseStyleWBD" type="text/css">
    @import url('https://opec.itdg.com.br/opec/teste/css/animate.css');

    #pulseAd {
      display: none;
    }

    @media (min-width: 1025px) {
      #closePulse {
        position: absolute;
        top: 0px;
        right: 0px;
        width: 30px;
        height: 30px;
        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAATlBMVEUAAAD29vb7+/tqamosLCwyMjLExMQwMDAwMDD7+/syMjK/v78qKir5+fnw8PD29vbg4OBkZGT29vZzc3MyMjJ/f38xMTEyMjLR0dH///+9IAJFAAAAGXRSTlMA/vfHHWFOKhXvXFAM/Pz0593OrZeSe3RHsw+jTQAAAJNJREFUKM+dkEkOhSAQRFHUBsR55P4X/b/DoizdGNlA3kvorjIfTpz9yeT0c/xfMqSyufKmTIOoWIpswItFhQs2G3AbnD6rOhvwujKGDTgbcDZtC84G/GbAr2brUuq2Bzf6v84Bwf7ThDyU9zgsDOVFUuZIyvx1b84/e/Nau4z9vbd+FBX7Gri3sO4qoojjUE4kmh9w7wiVurrz2QAAAABJRU5ErkJggg==);
        background-size: 11px 11px;
        background-position: center;
        background-repeat: no-repeat;
        cursor: pointer;
      }

      #container {
        place-items: center;
        display: grid;
        position: relative;
        width: 100%;
        height: 143px;
        border-top: 2px dashed #000;
      }

      #tituloPulse {
        font-size: 10px;
        font-weight: 600;
        letter-spacing: 0.3px;
        color: #b3b3b3;
        text-transform: uppercase;
        margin: 0 0 5px 0;
        position: relative;
        top: 5px;
      }

      #textoPulse {
        font-size: 16px;
        font-weight: 600;
        line-height: normal;
        text-align: center;
        color: #333333;
        width: 100%;
        box-sizing: border-box;
        position: relative;
      }

      #ctaPulse {
        position: relative;
        width: 188px;
        height: 34px;
        line-height: 34px;
        text-align: center;
        margin: 0 auto;
        background-color: #fecc00;
        text-transform: uppercase;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.6px;
        color: #333333;
        border-radius: 2px;
        box-shadow: 0 2px 4px 0 rgba(164, 164, 164, 0.5);
      }

      #videoPulse {
        width: 100%;
        height: 127px;
      }

      #videoPulse video {
        width: 100%;
        border-top-left-radius: 8px;
        border-top-right-radius: 8px;
      }

      #pulseAd {
        position: fixed;
        bottom: 0px;
        left: 20px;
        width: 220px;
        background: #fff;
        height: 270px;
        z-index: 10;
        border-top-left-radius: 10px;
        border-top-right-radius: 10px;
        animation-duration: 2s;
        text-align: center;
        -webkit-mask: radial-gradient(20px, #0000 98%, #000) 110px -10px;
      }

      #pulseAd iframe {
        width: 220px;
        height: 270px;
        border-radius: 8px;
      }

      #ticket {
        position: relative;
        top: -263px;
        display: flex;
        justify-content: space-between;
        width: 220px;
      }

      #ticket1 {
        top: 117px;
        left: -8px;
        width: 20px !important;
        height: 20px !important;
      }

      #ticket2 {
        top: -14px;
        left: 98px;
      }

      #ticket3 {
        top: 117px;
        left: 207px;
        width: 20px !important;
        height: 20px !important;
      }

      div#ticket > div {
        width: 30px;
        height: 30px;
        position: absolute;
        border-radius: 50%;
        background: #f2f2f2;
      }
    }
  </style>
</div>

I attached an image with mockup who is the model i needed to copy. What i want is this, make 3 holes in a div

enter image description here


Solution

  • You can combine multiple radial-gradient to create more "holes" or effects, refer to this solution that I posted 2 days ago to create multiple "holes".

    The next challenge will be the shadow, but will prefer using filter: drop-shadow with a wrapper component instead. box-shadow will not work with -webkit-mask / mask.


    Here's an example of building the ticket-like element in pure CSS:

    .wrapper {
      filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
      width: 200px;
      height: 300px;
    }
    
    .ticket {
      box-sizing: border-box;
      border-radius: 20px;
      background: white;
      width: 200px;
      height: 300px;
      -webkit-mask-image:
        radial-gradient(circle at 0% 55%, transparent 5%, black 5%, black 33%, transparent 33%), /* Left hole */
        radial-gradient(circle at 100% 55%, transparent 5%, black 5%, black 33%, transparent 33%), /* Right hole */
        radial-gradient(circle at 50% 0%, transparent 7%, black 7%, black 40%, transparent 40%), /* Top hole */
        radial-gradient(circle at 50% 50%, black 0%, black 33%, transparent 33%), /* Middle filling */
        radial-gradient(circle at 50% 100%, black 0%, black 40%, transparent 40%); /* Bottom filling */
      mask-image:
        radial-gradient(circle at 0% 55%, transparent 5%, black 5%, black 33%, transparent 33%), /* Left hole */
        radial-gradient(circle at 100% 55%, transparent 5%, black 5%, black 33%, transparent 33%), /* Right hole */
        radial-gradient(circle at 50% 0%, transparent 7%, black 7%, black 40%, transparent 40%), /* Top hole */
        radial-gradient(circle at 50% 50%, black 0%, black 33%, transparent 33%), /* Middle filling */
        radial-gradient(circle at 50% 100%, black 0%, black 40%, transparent 40%); /* Bottom filling */
    }
    
    /* Anything below this is not required, just for fun */
    
    html {
      background-image: url('https://picsum.photos/1280/720');
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
      min-height: 100%;
      padding: 16px;
    }
    
    .ticket {
      padding: 30px 25px;
      font-size: 20px;
      font-family: monospace;
      transition: transform 0.2s;
    }
    
    .ticket:hover {
      transform: scale(1.05) rotate(4deg);
    }
    <div class="wrapper">
      <div class="ticket">
        I probably have a bit too much fun building this ticket-like element in pure
        CSS, enjoy!<br /><br /><a
          href="https://stackoverflow.com/users/8888888/angyc"
          target="_blank"
          >@AngYC</a
        >
      </div>
    </div>