Reputation: 5631
I am new to using the css property clip-path
and have created a shape that almost fits the requirement I have.
I am looking to create the following shape however struggling to convert the squares I have to circles.
.ticket {
background-color: blue;
height: 100px;
width: 200px;
border-radius: 10px;
box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 15%);
clip-path: polygon(
0 0,
0% 42%,
5% 42%,
5% 58%,
0 58%,
0 100%,
100% 100%,
100% 58%,
95% 58%,
95% 42%,
100% 42%,
100% 0
);
}
<div class="ticket"></div>
Is this possible using this property? If not, how could I achieve this using a SVG instead? Is it also possible to add a drop shadow to this clipped mask? As you can see in the snippet the shadow doesn't really work.
Upvotes: 6
Views: 3053
Reputation: 272909
If it's only a solid coloration, background can do it:
.ticket {
background: radial-gradient(20px at 20px,#0000 97%,blue) -20px 50%;
height: 100px;
width: 200px;
border-radius: 10px;
filter: drop-shadow(0 0.5rem 0.2rem rgb(0 0 0 / 50%));
}
<div class="ticket"></div>
Upvotes: 8
Reputation: 51
Here is my solution for both contained and outlined coupons with mask-image
and radial-gradient
.
In order to draw an outlined coupon, I use two backgrounds and masks, each of which is only a half part to avoid overlapping of radial-gradient
.
.wrapper {
display: flex;
gap: 30px;
--coupon-side-radius: 6px;
--coupon-background-color: #c39f76;
--coupon-border-color: #c39f76;
--coupon-border-width: 1px;
}
.coupon {
width: 100px;
height: 100px;
border: var(--coupon-border-width, 1px) solid var(--coupon-border-color);
border-radius: 6px;
box-sizing: border-box;
background: radial-gradient(
circle at center left,
transparent 0px var(--coupon-side-radius),
var(--coupon-border-color) var(--coupon-side-radius)
calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px)),
var(--coupon-background-color) calc(var(--coupon-side-radius) + var(--coupon-border-width) + 0.5px)
)
border-box,
radial-gradient(
circle at center right,
transparent 0px var(--coupon-side-radius),
var(--coupon-border-color) var(--coupon-side-radius)
calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px)),
var(--coupon-background-color) calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px) + 0.5px)
)
border-box;
background-size: 50% 100%, 50% 100%;
background-position: 0% 100%, 100% 100%;
background-repeat: no-repeat, no-repeat;
-webkit-mask-image: radial-gradient(
circle at center left,
transparent 0,
transparent var(--coupon-side-radius),
#000 calc(var(--coupon-side-radius) + 0.5px)
),
radial-gradient(
circle at center right,
transparent 0,
transparent var(--coupon-side-radius),
#000 calc(var(--coupon-side-radius) + 0.5px)
);
-webkit-mask-size: 50% 100%, 50% 100%;
-webkit-mask-position: 0% 100%, 100% 100%;
-webkit-mask-repeat: no-repeat, no-repeat;
}
.coupon1 {
--coupon-side-radius: 6px;
--coupon-background-color: #c39f76;
--coupon-border-color: #c39f76;
--coupon-border-width: 1px;
}
.coupon2 {
--coupon-side-radius: 6px;
--coupon-border-color: red;
--coupon-border-width: 1px;
--coupon-background-color: #c39f76;
}
.coupon3 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 1px;
}
.coupon4 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 2px;
}
.coupon5 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 0.5px;
border: none !important;
position: relative;
}
.coupon5::before{
content: "";
position: absolute;
top: 0px;
left: 0px;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
border: 1px solid red;
border-radius: 16px;
opacity: 0.7;
}
.coupon-demo {
width: 100px;
height: 100px;
border: 2px solid red;
border-radius: 15px;
background: radial-gradient(
circle at center left,
transparent 0px 6px,
red 6px 8px,
#fff 9px
)
border-box,
radial-gradient(
circle at center right,
transparent 0px 6px,
red 6px 8px,
#c39f76 9px
)
border-box;
background-size: 51% 100%, 50% 100%;
background-position: 0% 100%, 100% 100%;
background-repeat: no-repeat, no-repeat;
-webkit-mask-image: radial-gradient(
circle at center left,
transparent 0,
transparent 6px,
red 7px
),
radial-gradient(
circle at center right,
transparent 0,
transparent 6px,
red 7px
);
-webkit-mask-size: 50% 100%, 50% 100%;
-webkit-mask-position: 0% 100%, 100% 100%;
-webkit-mask-repeat: no-repeat, no-repeat;
}
<div class="wrapper">
<div class="coupon coupon1">1. Contained</div>
<div class="coupon coupon2">2. Contained + Outlined</div>
<div class="coupon coupon3">3. Outlined</div>
<div class="coupon coupon4">4. Border 2px</div>
<div class="coupon coupon5">5. Border 0.5px </div>
<div class="coupon-demo">6. For debug purpose </div>
<div>
Upvotes: 2
Reputation: 36502
It is possible to 'cut holes' using the mask-image property and radial-gradients.
This snippet uses your code but replacing the clip-path with circle radial-gradient masks. Obviously you can change the percentages depending on hole-size required.
body {
background: cyan;
}
.ticket {
background-color: blue;
height: 100px;
width: 200px;
border-radius: 10px;
box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 15%);
--mask1: radial-gradient(circle at 0 50%, transparent 0, transparent 5%, black 5%, black 90%, transparent 90%, transparent);
--mask2: radial-gradient(circle at 100% 50%, transparent 0, transparent 5%, black 5%, black 90%, transparent 90%, transparent);
/* webkit needed for Chrome */
-webkit-mask-image: var(--mask1), var(--mask2);
mask-image: var(--mask1), var(--mask2);
}
<div class="ticket"></div>
(body has been given a background just to prove that holes have been cut rather than white circles drawn which is what would have happened with pseudo elements).
The box shadow is more problematic as it gets masked (or clipped as in the question's code). Box-shadow on element with -webkit-mask-image has ideas on putting a shadow on a containing element which has the mask image(s) as background images(s) but putting a shadow into the holes is still a problem. Perhaps just putting a slightly bigger container with gradient gray/transparent backgrounds would do enough, with the 'holes' varying transparent grays rather than just transparent. Seems hacky though.
Upvotes: 4