0

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

AngYC
  • 3,051
  • 6
  • 20

2 Answers2

2

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>
AngYC
  • 3,051
  • 6
  • 20
  • There is a way i can do this holes without remove the entire div, just move this "holes" to the borders and keeping all content inside my div without remove?? – Ricardo Pagano Apr 28 '23 at 18:43
  • Hi @RicardoPagano, I have just modified my answer to include an example on what you can achieve on a ticket-like shape in pure CSS – AngYC Apr 28 '23 at 19:02
0

Use the mask-composite property to create more complex masks:

<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;
        /* Fof all */
        --mask-image: radial-gradient(20px, #000 98%, #0000), radial-gradient(20px, #000 98%, #0000), radial-gradient(20px, #000 98%, #0000), linear-gradient(#000 0 0);
        --mask-size: 40px 40px, 40px 40px, 40px 40px, 100% 100%;
        --mask-position: left -20px top 110px, center -20px, right -20px top 110px, left top;
        --mask-repeat: no-repeat;
        /* For Chrome */
        -webkit-mask-image: var(--mask-image);
        -webkit-mask-size: var(--mask-size);
        -webkit-mask-repeat: var(--mask-repeat);
        -webkit-mask-position: var(--mask-position);
        -webkit-mask-composite: xor, xor, xor, source-in;
        /* For Firefox */
        mask-image: var(--mask-image);
        mask-size: var(--mask-size);
        mask-repeat: var(--mask-repeat);
        mask-position: var(--mask-position);
        mask-composite: exclude, exclude, exclude, add;
      }

      #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>
UModeL
  • 1,217
  • 1
  • 10
  • 15
  • 1
    Wow. i didn't know about mask-composite, i will try to take a look, but it's working too! thank you!!! – Ricardo Pagano May 02 '23 at 18:18
  • @RicardoPagano, pay special attention to the fact that for different browsers, the values for this property are also different. For example, in Chrome, this property has more options, but they are missing in Firefox. – UModeL May 02 '23 at 18:33