8

I'm trying to create an arch using just CSS. I've looked into various "inset border-radius" questions, but all of them show how to inset corners, not the middle section of an object.

I'm looking for a way to inverse the middle of an object to create an arch like a bridge.

Included is an example image to show the sort of thing I'm trying to achieve. enter image description here

Edit:

An important part of this arch is that it will be placed over other objects. Simply whiting it out isn't a solution, rather just a temporary hack. See image below for more on that.

enter image description here

Community
  • 1
  • 1
alex
  • 1,042
  • 4
  • 18
  • 33
  • For sure it is possible if you just want the image above. However without seeing your code it's hard to say what we can/cannot use creating it – Huangism Aug 25 '14 at 13:36
  • Hi @Huangism. I don't have any code yet, apart from a square div with a background colour that I need to turn into a arch! Regardless, I have created a JSfiddle for you to look at. http://jsfiddle.net/Lw53uxf5/ – alex Aug 25 '14 at 13:45
  • 1
    Yes, it is definitely possible, like [this](http://jsfiddle.net/5cm6ufvt/) using a pseudo-element and assigning a border-radius to it. – Harry Aug 25 '14 at 13:47
  • 1
    Simply adding a white background doesn't help. Please see this JSFiddle where the white is covering up the content below, as well as my updated image on the original question. http://jsfiddle.net/m9rnjqxr/ – alex Aug 25 '14 at 14:02
  • Hmm, got you. In that case Robin's answer is your best bet. It would have been better had you added the two extra images in the original question. But thats fine :) – Harry Aug 25 '14 at 14:20
  • 1
    Yeah, I realise my mistake in that. It's often only once other people start questioning me that my true needs come through! Next time I'll include everything from the start. And thanks for your help regardless :) – alex Aug 25 '14 at 14:25
  • You will find many techniques to make this shape in this post :http://stackoverflow.com/a/24786489/1811992 this post http://stackoverflow.com/a/24756255/1811992 and this post http://stackoverflow.com/a/24991844/1811992 – web-tiki Aug 25 '14 at 18:07

5 Answers5

10

You could accomplish with radial gradients. I’ve put an example up on JSFiddle: http://jsfiddle.net/17ohey9h/

The basic idea is to have a big overlay (generated content clipped to the container with overflow: hidden) and then to give it a background of a radial gradient with a hard stop for the transition. We can do this by setting two stops at the same position, but with opposite translucencies:

radial-gradient(ellipse at center, rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%)

You can obviously play around with the colours and positionings, the general idea holds. I’ve also only provided the W3C syntax for this. You’ll need to add in the older versions dependent on how far back your required browser support goes.

Robin Whittleton
  • 6,159
  • 4
  • 40
  • 67
  • Nice! And good use of the kitty placeholder. I'll try this out and see how it goes! Ps have a point. – alex Aug 25 '14 at 14:13
  • No probs. It’s a fairly flexible technique. I’m using a square container for the gradient, but if you wanted a different arc you could try adjusting the height for different ellipses. – Robin Whittleton Aug 25 '14 at 14:14
  • I'm so glad you mentioned that. I mean, I was going to try it anyway, but the fact you pointed it out anyway shows your true understanding of this solution :) – alex Aug 25 '14 at 14:18
  • 1
    @pappy I was working on a similar approach. As Robin has pointed radial gradient, a duplicate answer from me would be pointless. However you might want to take a look at this demo http://jsfiddle.net/hashem/jkfrkoez/ which may meet your needs. – Hashem Qolami Aug 25 '14 at 14:48
3

Given the images you've posted, you might consider another approach to this, such as this: http://codepen.io/pageaffairs/pen/lpLHg

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>

div {background: red; padding-top: 100px; width: 400px; text-align: center; overflow: hidden;}
img {border-radius: 200px/30px ; display: block; margin: 0 0 -30px -10px;}

</style>
</head>
<body>

<div>
    <img src="http://placeimg.com/420/420/any">
</div>

</body>
</html>
ralph.m
  • 13,468
  • 3
  • 23
  • 30
  • the margin tricks can be eliminated if we do div { width: 420px; } and img { border-top-left-radius: 50% 100px; border-top-right-radius: 50% 100px; } – BigDru Jun 14 '18 at 13:45
2

Another way to solve it, using box-shadow

.overlay::after {
    content: "";
    position: absolute;
    width: 100%;
    height: 50%;
    top: 30px;
    border-radius: 50%;
    box-shadow: 0px -100px 0px 72px red;
 }

fiddle

Reusing Robin fiddle :-)

vals
  • 61,425
  • 11
  • 89
  • 138
1

Html :

<div class="wrapper">
   <div class="rectangle"></div>
   <div class="egg"></div>
</div>

CSS :

.wrapper {
  width:200px;
  height:100px;
  overflow:hidden;
  position:relative;
}
.rectangle{
  width:200px;
  height:100px;
  background-color:red;
}
.egg {
  width:200px;
  height:100px;
  border-radius:50%;
  background-color:#fff;
  position:absolute;
  top:56px;
}

and the fiddle : http://jsfiddle.net/h1gjefk7/

AlexHolly
  • 11
  • 1
  • 1
    Nice try, but not what I'm looking for. By placing a white "egg" over the rectangle, it only created the illusion of what I need, rather than the functionality. I'm planning on having this Arch on top of various pages and images, so it really does need to be cut out. See included image for more. http://i.imgur.com/BdE9UPf.jpg – alex Aug 25 '14 at 13:52
1

You could do it like this: http://codepen.io/pageaffairs/pen/wpaFm

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>

div { 
    width: 230px;
    height: 120px;
    background: red;
    position: relative;
    overflow: hidden;
}
div:after {
    content:"";
    width: 260px;
    height: 50px;
    background: #fff;
    border-radius: 100% 100% 0 0;
    position: absolute;
    bottom:0;
    left: -15px;
}

</style>
</head>
<body>

<div></div>

</body>
</html>
ralph.m
  • 13,468
  • 3
  • 23
  • 30
  • 1
    Good attempt, but it doesn't help my objects below. Take a look at this JSFiddle and notice how the white from the .arch:after simple covers up the green .otherObjects making the whole exercise rather pointless! http://jsfiddle.net/m9rnjqxr/ – alex Aug 25 '14 at 14:00
  • That's easy to deal with, though. E.g. `.otherObjects {position: relative; z-index: 100;}` – ralph.m Aug 25 '14 at 14:12
  • No, that's not easy to deal with. http://jsfiddle.net/4vcj0z0r/ If you toggle the z-index of .otherObjects you will see with switches between in front of the whiteout arch and behind it. At no point does it sit inbetween .arch and .arch:after. This is because z-indexes are inherited from parents. There isn't a way to split them up using CSS. Inspect the element on this JSFiddle and you'll see the issue. http://jsfiddle.net/4vcj0z0r/ – alex Aug 25 '14 at 14:17