border curved css - circle with curved end

You can do this using SVG as background:

.bottom-bar {
  background: #29a7e8;
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 50px;
  text-align: center;
}

.circle {
  display: inline-block;
  position: relative;
  top: -28px;
  border-radius: 100%;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='10 10 45 15'  width='64' height='64' fill='%2329a7e8'><path d='M12 24 L52 24 L52 16 C40 16 42 10 32 10 C20 10 22 16 12 16 Z' /></svg>") 0 0/100% 100% no-repeat;
  width: 60px;
  height: 60px;
  margin: 0 1rem;
}
<div class="bottom-bar">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>


<svg xmlns='http://www.w3.org/2000/svg'
  viewBox='10 10 45 15'
  width='64' height='64'
  fill='#29a7e8'>
  <path d='M12 24 L52 24 L52 16 C40 16 42 10 32 10 C20 10 22 16 12 16 Z' />
</svg>

For a CSS only solution you can consider a combination of radial-gradient to create the curve:

.bottom-bar {
  background: #29a7e8;
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 50px;
  text-align: center;
}

.circle {
  display: inline-block;
  position: relative;
  top: -30px;
  background:
  radial-gradient(circle at top right,transparent 50%,#29a7e8 51%)100% 21px/12px 10px no-repeat,
  radial-gradient(circle at top left,transparent 50%,#29a7e8 51%)0 21px/12px 10px no-repeat,
  radial-gradient(circle at center,#29a7e8 55%, transparent 56%);
  width: 60px;
  height: 60px;
  margin: 0 1rem;
}
<div class="bottom-bar">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>


In general, there are for ways to create that kind of shapes, from simple to more complex:

  • Adding 2 pseudoelements with radial-gradient.

    Simplest and well-supported solution. Probably the one I would use.

  • Adding 2 pseudoelements with mask-image (same as above, but with worse support).

    Quite similar, code-wise, to the previews one, but with really bad support (needs browser prefixes for those that support it).

    If you want to check how similar they are, take a look at this other similar question: CSS "inverse border-radius" outside element's bounding box to create a mobile phone notch design

  • Adding 2 pseudoelements with a border-radius, box-shadow and background: transparent.

    Needs a bit more code, but it looks a bit smoother, at least on Chrome Version 78.0.3904.108, although the difference is minimal. In any case, the shapes you can do can't be as complex as with the previous alternatives, especially if you want to work with ellipses rather than circles, as it is your case.

  • Using an SVG.

    I think the SVG solution is not worth it here, but it would be a good alternative for more complex shapes or animated/transitioning shapes. In any case, Temani Afif already added a solution using SVG.

Something to keep in mind is that, as that looks like a navigation bar, the hoverable/clickable area of each button should match as good as possible what users actually see, which is not the case for Temani Afif's solutions.

This is what it would look like using radial-gradient:

body {
  margin: 0;
  font-family: monospace;
  background: #DDD;
}

.bar {
  background: white;
  position: fixed;
  bottom: 0;
  width: 100%;
  height: 60px;
  text-align: center;
}

.circle {
  position: relative;
  top: -10px;
  border-radius: 100%;
  background: white;
  width: 60px;
  height: 60px;
  margin: 0 16px;
  cursor: pointer;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font-size: 24px;
  font-weight: bold;
  color: black;
  transition: box-shadow ease-in 150ms;
  background: white;
  border: 0;
  outline: none;
}

.circle:hover {
  box-shadow: 0 16px 16px 0 rgba(0, 0, 0, .125);
}

.circle:active {
  box-shadow: 0 8px 8px 0 rgba(0, 0, 0, .125);
}

.circle::before,
.circle::after {
  content: "";
  position: absolute;
  top: 4px;
  width: 32px;
  height: 6px;
  background: white;
  z-index: 1;
}

.circle::before {
  left: -18px;
  background: radial-gradient(ellipse at 0% -25%, transparent 0, transparent 70%, white 70%, white 100%);
}

.circle::after {
  right: -18px;
  background: radial-gradient(ellipse at 100% -25%, transparent 0, transparent 70%, white 70%, white 100%);
}
<nav class="bar">
  <button class="circle"></button>
  <button class="circle"></button>
  <button class="circle"></button>
</nav>

If you want to see a similar question and all the alternatives in action, check this out: CSS "inverse border-radius" outside element's bounding box to create a mobile phone notch design

Tags:

Html

Css

Svg

Border