Capsule shape using border-radius without a set width or height?
Asked Answered
N

6

101

Is it possible to make a capsule shape using border-radius without a set width or height?

I want the left and right sides to be completely rounded while the capsule would remain straight along it's horizontal length. Setting the radius to 50% doesn't seem to give the desired affect.

Capsule Shape

Neom answered 13/9, 2013 at 20:45 Comment(4)
You could do the desired math using a server side language or javascript and generate it appropriately from there.Adactylous
This is an option. Just seems like overkill for something so presentational. I'm looking to use this for buttons so I might be able to make some headway using ems.Neom
This question explains how this works : #29966999Soluble
Does it have to use border-radius? You could also do this with 3 background properties (2 radial-gradients for the ends)Hypnotic
H
160

Applying a very large border radius seems to work on many browsers (IE9+, FF, Chrome) like this mod of David's fiddle http://jsfiddle.net/cthQW/1/

border-radius: 500px;
Hazing answered 13/9, 2013 at 21:0 Comment(5)
Could this be the answer? Corner curves must not overlap: When the sum of any two adjacent border radii exceeds the size of the border box, UAs must proportionally reduce the used values of all border radii until none of them overlap.Hazing
Absolutely! Nicely found, and a very impressive (and simple) solution; have a deserved upvote =)Presentable
It's nice to think it's perhaps not a hack after all, and that would explain why all the browsers I've observed so far behave the same.Hazing
Why does this work but a large percentage doesn't work?Intricate
@Intricate I assume that when using percentages the vertical radius is computed based on the elements height and the horizontal radius is calculated based on the elements width. Whereas a fixed unit does not vary in that way. Here's a border-radius fiddle that visualizes differences between fixed units and percentages.Hazing
P
28

Yes, this is possible (albeit I've only tested in Chromium 28/Ubuntu 12.10):

div {
    /* this is the only relevant part: */
    border-radius: 20%/50%;

    /* this is irrelevant, and just so the element can be visualised/displayed: */
    width: 50%;
    height: 5em;
    margin: 2em auto;
    background-color: #000;
}

JS Fiddle demo.

The important information is, obviously, the 20%/50% property-value; the 20% is the 'horizontal length' of the radius, whereas the 50% is the 'vertical length'; using two different measurements gives an elliptical curve to the border, instead of a single measurement, which yields the more circular radius. Obviously this requires a certain amount of adjustment to your own requirements

References:

Presentable answered 13/9, 2013 at 20:49 Comment(3)
Okay, I see your point; but that's always a problem of using border-radius (that the content isn't necessarily 'contained' within the border's curve. Using padding can help, though; Or a child element, with a margin.Presentable
this doesn't work if you don't want to round all the bordersScurrility
Yeah this isn't exactly what you wantBobbi
B
9

If you use percentages, it takes the element width to calculate the radius. To have the capsule-shaped element, you need to pass to the border-radius property units like rem or px (neither I know the reason for this, but it works). This is why it works when passing 500px. You can use the same value for line-height and border-radius properties if you want.

.capsule {
    line-height: 48px;
    border-radius: 48px;
}

Here you have an example in CodePen. Try to change the variable $label-height to see how the shape is maintained while the height of the button changes.

In this example, you don't need to set the width or height of the element. You just need to adjust the content's height and padding.

The padding property is useful to set a separation between the contents and the component border. See how it looks if I only set the left padding.

enter image description here

If you set the line-height property of the container, you will set automatically the container height, and center the content inside the container at the same time.

If you want to set the component's width to the component's content width, you can set the component's display property to inline-block, and use FlexBox to arrange them in a column, for example. And then, set the left and right margins to auto, to avoid the element to grow to its parent width.

enter image description here

And if you want to leave a space between the components, you can set the margin-top property between consecutive components.

.capsule + .capsule {
    margin-top: 15px;
}

Hope it helps :)

Beabeach answered 4/9, 2015 at 14:32 Comment(0)
F
2

This can be easily achieved using HTML Span. You have to just set the background-color and border-radius.

span {
  background-color: #30bb36;
  border-radius: 10px;  
  padding-left: 10px;
  padding-right: 10px;
}
<!DOCTYPE html>
<html>
  <body>
    <p>Set a <span>Background Color</span> for only a part of a text.</p>
    <span>One</span>
    <span>Two</span>
    <span>Three</span>
    <span>Four</span>
  </body>
</html>
Fellatio answered 9/12, 2019 at 9:48 Comment(1)
This does not work well for anything but the default font-size.Woodnote
M
0

To get capsule shape you can set the border radius to height of an element.

So if

height: 5rem;

than set

border-radius: 5rem;

If you use some padding or border set box-sizing: border-box; this includes the padding and border into an element's total height

Mikaelamikal answered 4/3 at 19:10 Comment(0)
C
-3

This is what I have found to work well:

border-radius: 50vh;

Browser support looks good for that now too.

To explain, the vh is a "Viewport Unit" that computes the height of the viewport in pixels. By saying 50vh to declare the border radius, it is 50% * (Viewport Height)px.

Chinfest answered 22/8, 2016 at 20:46 Comment(5)
Please add an explanation for your answer.Dung
This isn't right. It works because 50vh is half the height of the screen, and that is larger than the maximum radius so it truncated to the correct radius. If you do 1000vh it will behave the same.Numbskull
I explained the screen height in my answer. It usually works fine for me, but you may be correct in that the 1000vh is more likely to work for larger elements.Chinfest
I think @Timmmm's point is there's nothing magic about the 50 here. This works only as a consequence of Jeremy Cook's answer to use a big value; 40vh or 60vh or 1000vh would all work just as well for a typical (ie small-ish) element.Bedding
Correlation does not imply causation.” No magic about the 50.Greengrocer

© 2022 - 2024 — McMap. All rights reserved.