I need to achieve an effect like in this demo.
But the code I used there is too specific and not very clean. As you can see I have used quite a lot of elements and also some transforms with very specific angle calculations.
Is there a way for me to create this shape, keep it responsive but in a cleaner way? Please note that I don't want just half a circle, but a very specific angle that I could adapt. I mean the circle could be more or less inside the rectangle, so the angle of the arc would be more or less big.
CSS:
.rectangle {
background-color: white;
width:200px;
height:200px;
border:solid 1px navy;
}
.circle {
position: relative;
width: 70px; height: 70px;
border-radius: 50%;
background: white;
margin-top:calc(50% - 35px);
margin-left:calc(100% - 50px);
}
.arc {
overflow: hidden;
position: absolute;
top: -1px; right: 50%; bottom: 50%; left: -1px;
transform-origin: 100% 100%;
transform: rotate(115deg);
}
.arc:before {
box-sizing: border-box;
display: block;
border: solid 1px navy;
width: 200%; height: 200%;
border-radius: 50%;
content: '';
}
.arc2 {
overflow: hidden;
position: absolute;
top: -1px; right: 50%; bottom: 50%; left: -1px;
transform-origin: 100% 100%;
transform: rotate(155deg);
}
.arc2:before {
box-sizing: border-box;
display: block;
border: solid 1px navy;
width: 200%; height: 200%;
border-radius: 50%;
content: '';
}
HTML:
<div class='rectangle'>
<div class='circle'>
<div class='arc'></div>
<div class='arc2'></div>
</div>
</div>
Points to Note:
I would generally recommend using SVG for such shapes because it is easier to create and maintain arcs with it. Using SVG would also mean better control over the radius, the arc's start and end angles etc but I don't think we can make part of the shape be responsive (the rectangle) while keeping other part as static (the circle's height) and hence it might be safer to use CSS.
In CSS also, it is tough to achieve this with a single element because you've indicated that z-index
cannot be used. Other approaches (like making the element's width larger than height or using scale) would result in an elliptical arc and it would also require tweaking to positioning attributes when height or width changes.
Considering all those the below approach using a couple of elements and a pseudo-element could be the best bet. The .inner
element is placed on top of the right border of the .rectangle
and its width is just enough to get the circle to display. Inside the .inner
element, the pseudo element that creates the circle is placed with a negative left offset so that only a part of the circle is visible (due to overflow being hidden on .inner
). The output is responsive.
.rectangle {
position: relative;
background-color: white;
width: 200px;
height: 200px;
border: solid 1px navy;
}
.inner {
position: absolute;
left: 100%;
top: -1px;
height: calc(100% + 2px);
width: 30px;
overflow: hidden;
}
.inner:after {
position: absolute;
content: '';
width: 70px;
height: 70px;
border-radius: 50%;
background: white;
top: calc(50% - 35px);
left: -45px;
border: 1px solid navy;
}
/* Just for demo */
.rectangle {
transition: all 1s ease;
}
.rectangle:hover {
height: 400px;
}
<div class='rectangle'>
<div class="inner"></div>
</div>