There's lots of techniques that cover the simplicity of the question, here are my requirements:
- I'd like an
<hr />
element to be visible, with a portion of it cut out (e.g.; fully transparent) - The width of the
<hr />
is unknown - The cutout region has fixed dimensions and must be centered on top of the
<hr />
- Use 1x
<hr />
element - Supported in IE11 and Safari 11, as well as modern browsers
Due to the browser support, I think I am left with using clipPath within an SVG and setting that as the clipping region via CSS on the <hr />
element.
The following demo is not tested in IE/Safari yet and it highlights my attempts to firstly draw an SVG shape with a portion cut out. That part is nearly fine apart from my requirements #2 and #3 because I don't yet have a fluid filling path with a fixed and centred second path inside it.
Requirement #1 currently fails completely, when I convert the path
inside the SVG into a clipPath
and then assign that to the hr />
element.
Codepen demo: https://codepen.io/davewallace/pen/WNNRMoR
Markup:
<p>1. Aspect ratio in action, box is correctly centered, but I need the black region to stretch all the way to the far left and right edges, leaving the inner cut-out box in the middle.</p>
<div>
<hr />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</svg>
</div>
<p>2. So I tried removing the aspect ratio. That sort of helped, but I need the inner cut-out box to be a fixed width and centered.</p>
<div>
<hr />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10" preserveAspectRatio="none">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</svg>
</div>
<p>3. Regardless of the stretching accuracy of the two techniques above, I expected the supplied paths, converted into a clipPath, to hide the centre part of the HR element, leaving only its left/right sides visible.</p>
<div>
<hr class="clipped" />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10">
<defs>
<clipPath id="square">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</clipPath>
</defs>
</svg>
</div>
CSS (mostly to illustrate):
div {
position: relative;
border: 1px solid red;
margin: 50px;
padding: 20px;
background: #999;
}
hr {
height: 5px;
background: lime;
&.clipped {
clip-path: url(#square);
}
}
svg {
position: absolute;
left: 0;
top: 20%;
border: 1px dotted red;
}
Research so far:
- https://css-tricks.com/clipping-masking-css/
- https://css-tricks.com/cutting-inner-part-element-using-clip-path/
- How can I cut one shape inside another?
Alternative approaches so far:
- Use flexbox and have 1
<hr />
, a gap, and then another element like a<div />
finishing off the second half of the effect. So it's not 'cutting a hole' in the<hr />
but stopping and starting it visually. This approach, in my context, would need some magic numbers and isn't so clean. Pretty sure it's still accessible in that I am still using 1x<hr />
element mostly as it is intended to be used. - Nothing else so far, but this is to achieve a "fancy horizontal rule" effect, where someone can drop their image/SVG asset into the middle of the horizontal rule without worrying about the horizontal line going under the asset. I also don't know what the page background colour is, no assumptions can be made about that.
Thank you!
. I'd settle for 'always square' in the middle part for now though :) – danjah Oct 22 '19 at 21:03