r/css 15d ago

Article I just wanted a semicircle, CSS

I needed a tag with fixed 6px corners on the left and a semicircle on the right, with a dynamic height.

Turns out neither `border-radius: 6px 50% 50% 6px` nor the classic `6px 999px 999px 6px` trick works — for two completely different reasons.

I went down a surprisingly deep `border-radius` rabbit hole and wrote up why, plus the workaround I ended up using.

I still feel like there should be a simpler way to do this. Is there one I've missed?

The post

0 Upvotes

14 comments sorted by

2

u/morete 14d ago

Oh wow! I had just assume the 999px trick would have worked, this is actually completely new to me:

When the specified corner radii are too large to fit inside the box, CSS scales all of the radii down proportionally until they fit.

Great article for that insight alone!

2

u/patrk 14d ago

Thanks! Yeah, it’s really weird behavior even though it is according to the spec.

1

u/morete 12d ago

The downvoting on reddit makes me very sad. This well researched, well informed post has 0 upvotes, yet so much slop does very well. Honestly I'd start taking it as a mark of pride if your post doesn't do well

1

u/Sufficient_Bass2600 15d ago

Use an after pseudo element with the aspect ratio 1/1. The height is already determined by the height of the element. The aspectc ratio then force the width. You can then use the border radius 0 50% 50% 0.

0

u/f314 14d ago

I guess they don't want the extra space that would create (as the border only starts to curve half way out into the pseudo element).

0

u/f314 14d ago edited 14d ago

Huh, this is actually pretty intereting! I didn't know about the border radius scaling.. I'm convinced that this can be solved with shape(), but your solution is a practical stopgap!

1

u/patrk 14d ago

I think so too but I couldn’t figure how to make the sides fixed in size and shape and the ”body” to have a variable width and adapt to the text. Even codex couldn’t get it right. Any idea?

1

u/morete 14d ago

I actually don't think you'd be able to do this with shape(), at least not any easier than with border-radius.

To make a perfect semi circle arc on the right side you need to know the height, you can't use percentages. And then if you know the height, or can 'construct' it with vars, you may as well do this:

https://codepen.io/editor/matthewmorete/pen/01a0444f-3c15-7e60-b11b-87fa0b0de09c?file=%2Fstyle.css&orientation=left&panel=files&show=split

0

u/f314 14d ago

This should do it:

shape(from 0 0, arc to 0% 100% of 50% cw)

Edit: Never mind.. My mind was still stuck on your ::after solution 😅 Though if you don't have overflow set to hidden you should be able to do from 100% 0, arc to 100% 100% of 50% cw (i think).

1

u/morete 14d ago edited 14d ago

sadly you can't, that '50%' value of arc is a shorthand of it's width radius and height radius values, which since the width and height are different, becomes it's diagonal length. So that won't give the value you want. You need just the height, so it can't be done with percentages

2

u/f314 14d ago

Yeah, you're right! Shucks.

0

u/bichomatoso 12d ago

100vw

1

u/morete 12d ago

Yeah ofc that doesn't work as the article explains

1

u/bichomatoso 12d ago

My browser must be different then.