2

I'm looking to achieve these sides on an element with CSS:

screenshot

This is the closest I've got (border is required):

screenshot

div { 
  width: 120px;
  height: 100px;
  margin: 25px auto;
  border: 1px solid #000;
  border-top-left-radius: 200px 300%;
  border-bottom-left-radius: 200px 300%;
  border-top-right-radius: 200px 300%;
  border-bottom-right-radius: 200px 300%;
}
<div></div>

Any suggestions on how to sharpen the edges? Width needs to be variable.

0

3 Answers 3

6

If you know the size that you want the shape to be, you can use a wrapper div and overflow: hidden to solve this.

I use flexbox to center it, but you can use other ways to center it vertically.

.wrapper {
  display: flex;
  align-items: center;
  height: 100px;
  overflow: hidden;
}

.circle { 
  width: 120px;
  height: 120px;
  margin: 25px auto;
  background-color: black;
  border-radius: 100%;
}
<div class="wrapper">
   <div class="circle"></div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

3

You can do that with pseudo elements, like this, and it will scale to what ever size you set on the main element

Updated

typ2 has equal radius on the left/right curved border, if you want to fill these with a color, or image, or dynamically scalable height, an extra inner element is required.

.typ1 div {
  position: relative;
  display: inline-block;
  width: 120px;
  height: 100px;
  margin: 0 30px;
  overflow: hidden;
}

.typ1 div + div { 
  width: 200px;
  height: 100px;
}

.typ1 div::before,
.typ1 div::after { 
  left: 0;
  top: -10%;
  width: 100%;
  height: 120%;
  border-radius: 100%;
  border: 1px solid #000;
}
.typ1 div::after { 
  left: 22%;
  top: 0;
  width: 56%;
  height: 100%;
  border-radius: 0;
  border-width: 1px 0;
}

.typ2 div { 
  position: relative;
  display: inline-block;
  width: 74px;
  height: 100px;
  margin: 5px 52px;
  border: 1px solid #000;
  border-width: 1px 0;
}

.typ2 div + div { 
  width: 156px;
}

.typ2 div::before,
.typ2 div::after { 
  left: -24px;
  top: -25%;
  width: 188px;
  height: 150%;
  border-radius: 100%;
  border: 1px solid transparent;
  border-left: 1px solid #000;
}
.typ2 div::after { 
  left: auto;
  right: -24px;
  border-left: none;
  border-right: 1px solid #000;
}

/* general styling */
div::before, div::after { 
  content: '';
  position: absolute;
  box-sizing: border-box;
}
<div class="typ1">
  <div></div>
  <div></div>
</div>

<div class="typ2">
  <div></div>
  <div></div>
</div>

1 Comment

.typ2 is exactly what I'm after. Nice idea to use pseudo-elements like this, thank you.
1

You can do it with the :before and :after pseudo-elements:

.circle { 
  position: relative;
  width: 100px;
  height: 100px;
  margin: 25px auto;
  border-radius: 50%;
  background: #000;
}

.circle:before,
.circle:after {
  content: "";
  position: absolute;
  width: 100px;
  height: 25px;
  background: #fff;
}

.circle:before {
  top: -16px;
}

.circle:after {
  bottom: -16px;
}
<div class="circle"></div>

Adjust the values of the top and bottom properties as you wish.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.