(somewhat) Desired result
.parent {
width: 600px;
height: 300px;
--border-opacity: 0.5;
--border-color: rgba(229, 128, 255, var(--border-opacity));
--inner-opacity: 0.2;
--inner-bkg: rgba(255,255,255, var(--inner-opacity));
background: #000;
}
.box {
width:150px;
height:100px;
margin:10px;
border:10px solid var(--border-color);
background:
radial-gradient(farthest-side at bottom right,#0000 98%, var(--border-color)) top left / 30px 30px,
radial-gradient(farthest-side at top right,#0000 98%, var(--border-color)) bottom left / 20px 20px,
radial-gradient(farthest-side at bottom left ,#0000 98%, var(--border-color)) top right / 50px 50px,
radial-gradient(farthest-side at top left ,#0000 98%, var(--border-color)) bottom right/ 10px 10px,
var(--inner-bkg);
background-repeat:no-repeat;
background-origin:padding-box;
}
<div class="parent"><div class="box"/></div>
Context:
- The “box” div is repeated a number of times both vertically and horizontally, in a grid.
- The grid itself has rounded corners, but bigger than the individual box, hence the example I gave with a bigger radius for the top right corner.
- The grid sits on top of a video (for the purposes of this issue, consider the black background as the video)
Requirements
- At certain timestamps in the video, the entire grid has various degrees of opacity (root of the problem)
- Both the border, and the inner part of the box must have opacities that can be individually controlled.
- The inner shape acts as a mask (cuts out the inside of the box) so the video behind can be seen. I also have to add a background to the inner shape to which opacity can be applied.
- The “box” does
not
have fixed dimensions, so whatever solution may exist, needs to take into account responsiveness - CSS-only solution (no JS)
What I tried so far:
- Using a CSS
mask
with an inline SVGrect
- 2 problems with this approach
- cannot control the radius on just one corner (except by adding a clip-path to it), and even so, the clip path won’t align properly with the parent’s border radius in responsive scenarios.
- cannot/don’t know how to make the
rect
responsive (it would always need to be i.e.height: calc(100% - var(---border-width * 2))
… same for width.
- 2 problems with this approach
- find a way to have a border with radius only on the inside (no luck)
The provided code snippet is the closest I’ve got to achieving what I need, but there are a few problems.
- there’s a weird line on the right side (probably because both the border and the radial gradients have opacity and they intersect slightly) – breaker
- seems so overly-complicated
- the radius of the inner element is always fixed (as if the box itself were square), which is honestly something I can live with, though in a responsive environment, the expected result would be slightly different.
- changing the
--inner-opacity
variable affects the border’s and the radial-gradient’s opacity as well – breaker
You can rely on a simple border-radius
and consider an overflowing coloration to simulate your border.
.box {
border-radius: 10px 20px 30px 40px; /* your radius */
background: #add8e691; /* background color*/
outline: 999px solid rgb(255 0 0/.8); /* border color (don't touch the 999px) */
margin: 20px; /* border thickness */
clip-path: inset(0) margin-box;
height: 100px;
width: 300px;
}
body {
background: repeating-linear-gradient(45deg,#fff 0 10px,#eee 0 20px);
}
<div class="box"></div>
2