-Webkit-mask cuts out border. Is there anyway to force border to div's shape once it is masked?

84 views Asked by At

So I'm trying to create a responsive frame with inverted corners for my website. I achieved to create the shape of it but once I try to add border to it, -webkit-mask cuts it out. Is there any way to achieve this easily?

.box {
  width: 98%;
  height: 800px;
  -webkit-mask: radial-gradient(40px at 40px 40px,#0000 98%,#000) -40px -40px;
  background-color: black;
  margin: auto;
  border-width: 10px;
  border-style: solid;
  border-color: red;
}
<div class="box">
</div>

Thank you

Create a border frame with inverted corners and transparent background.

3

There are 3 answers

0
Brett Donald On

Just reverse your thinking. Rather than adding border after the mask is applied, put some red circles in the corners before applying the mask. Create a background with a similar repeating radial gradient to what you’re using for the mask.

black box with red border and red circles in corners

Note that by default, the origin of a mask is border-box and the origin of a background is padding-box. In this case we want these origins to coincide, so we explicitly set the background origin to border-box.

.box {
  width: 80%;
  height: 200px;
  mask: radial-gradient(40px at 40px 40px,#0000 98%,red) -40px -40px;
  background-color: black;
  margin: auto;
  border-width: 10px;
  border-style: solid;
  border-color: red;
  background: radial-gradient(50px at 50px 50px,red 98%,#000) -50px -50px border-box;
}
<div class="box"></div>

0
G-Cyrillus On

You may also put a second div inside the first and apply the same mask. Both can have a different background color and a padding on the parent will visually fake the border: example below:

.box, .box > div {
box-sizing:border-box;
  -webkit-mask: radial-gradient(40px at 40px 40px,#0000 98%,#000) -40px -40px;
  }
.box {
  width: 98%;
  height: 800px;
  margin: auto;
  padding: 10px;
  background: red;
}
.box>div {
  background-color: black;
  width:100%;
  height:100%;
}
<div class="box">
<div></div>
</div>

From your try, here is your snippet updated with the mix-blend-mode method, to blend the black part into the main background.

.box {
  width:98%;
  height: 800px;
  margin: auto;
  padding: 2px;
  background: red;
mix-blend-mode:screen;
}
.box>div {
  background:black;
  width:100%;
  height:100%;
}
.box, .box > div {
box-sizing:border-box;
  -webkit-mask: radial-gradient(40px at 40px 40px,#0000 98%,#000) -40px -40px;
  }
.home {
  background-image: url('https://www.barhemblematico.es/public/playground_assets/shooting%20bar%20h%20emblematico%20%5B13%5D-1500w.jpg');
}
<body class="home">
<div class="box">
<div></div>
</div>
</body>

0
Temani Afif On

You don't need mask for this. Play with gradients and background:

.box {
  --b: 10px; /* border*/
  --r: 50px; /* radius */
  --c1: red; /* border color */
  --c2: #000; /* background color */

  width: 98%;
  height: 400px;
  background: 
    linear-gradient(90deg,var(--c1) calc(2*var(--b)),#0000 0)
     calc(-1*var(--b)) 50%/100% calc(100% - 2*var(--r) + var(--b)) repeat-x,
    linear-gradient(var(--c1) calc(2*var(--b)),#0000 0)
     50% calc(-1*var(--b))/calc(100% - 2*var(--r) + var(--b)) repeat-y,
    radial-gradient(var(--r) at var(--r) var(--r),
      #0000 calc(100% - var(--b)),var(--c1) calc(98% - var(--b)) 100%,var(--c2) 101%) 
     calc(-1*var(--r)) calc(-1*var(--r));
}
<div class="box"></div>

And in case you need use mask, here is another idea:

.box {
  --b: 10px; /* border*/
  --r: 50px; /* radius */
  --c1: red; /* border color */
  --c2: #000; /* background color */

  width: 98%;
  height: 400px;
  background: 
    conic-gradient(from 90deg at var(--b) var(--b),#0000 25%,var(--c1) 0)
     0 0/calc(100% - var(--b)) calc(100% - var(--b)),
    radial-gradient(var(--r) at var(--r) var(--r),var(--c1) 98%,var(--c2)) 
     calc(-1*var(--r)) calc(-1*var(--r));
  --_r: calc(var(--r) -  var(--b));
  -webkit-mask: 
    radial-gradient(var(--_r) at var(--_r) var(--_r),#0000 98%,#000) 
     calc(-1*var(--_r)) calc(-1*var(--_r));
}
<div class="box"></div>

And if you want a transparent background and any kind of border, then use my online generator to get such shape https://css-generators.com/custom-corners/ Custom corner CSS only

.box { 
  position: relative;
  height: 300px;
  --mask:
    radial-gradient(48px at 48px 48px,#0000 calc(98% - 10px),#000 calc(100% - 10px) 98%,#0000) -48px -48px,
    linear-gradient(90deg,#000 20px,#0000 0) -10px 50% /100% calc(100% - 96px + 10px) repeat-x,
    linear-gradient(      #000 20px,#0000 0) 50% -10px/calc(100% - 96px + 10px) 100% repeat-y;
}
.box:before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(red,blue);
  -webkit-mask: var(--mask);
          mask: var(--mask);
}
<div class="box"></div>

I am applying the shape to a pseudo-element so you can put content inside it. If you don't need content, apply the CSS to the element