How to create a gullwing shape with CSS

时间:2016-02-12 20:58:42

标签: html css css-shapes

I am trying to create a div with a background image (background-size:cover) with this shape cut out in the center top of the div.

enter image description here

The div above the div I want to cut this shape out of has background-image:cover on it as well. I'm trying to do this with a CSS shape, moving the lower div up using a negative margin top, so the background image on the div above shows through the cut out shape.

Note: The shape has to look identical or almost identical to the image, as it is part of a site designed by someone else, and they are very specific with their designs.

Anyone out there know how to create this shape?

EDIT: @SZenC offered a really cool solution that I implemented, except it leaves me with colored shapes overlayed on top of background images. See image:

enter image description here

I need the light blue pattern to show through where the gray is, and the purple texture to show through where the white is. I'm not sure at this point if this is possible, at least with CSS.

2 个答案:

答案 0 :(得分:4)

The best solution using CSS would be to use some nested elements. You could create a div (static func merge<T1: NSObject, T2: NSObject>(itemChanging:T1, itemToMerge:T2) { let mirrorSelf = Mirror(reflecting: itemChanging) let mirrorItemToMerge = Mirror(reflecting: itemToMerge) for mirrorSelfItem in mirrorSelf.children { // Loop through items in mirrorItemToMerge. for mirrorImageItem in mirrorItemToMerge.children { // If you have a parameter who's name is a match, map the value // OR You could add any custom mapping logic you need for your specific use case if mirrorSelfItem.label == mirrorImageItem.label { // To set values, use self.setValue(valueToSet, forKey: propertyName) self.setValue(mirrorImageItem.value as? AnyObject, forKey: mirrorImageItem.label!) } } } } ) with two other divs inside it (.pointy & .curve-left).

The inner divs should be sided so that they each have half of the curve. So if your curve drops 10px and goes 20px horizontal, it's height should be 10px and the width 20px. Then give it a border radius in the top-left or top-right corner of 100%. Now the curve will go trough the entire div. You could then give it a gray background-color and the parent div white in the background. Then some simple CSS-tricks to center the .curve-right-div and do the backgrounds, and voila, there is your curvy triangle-y thingy.

So example below.

.pointy
#c1 {
  position: relative;
  width: 200px;
  height: 190px;
  overflow: hidden;
}
#c2 {
  position: relative;
  top: 0px;
  width: 200px;
  height: 200px;
  background-color: gray;
}
.pointy {
  position: absolute;
  top: 0px;
  left: 50%;
  margin-left: -20px;
  width: 40px;
  height: 10px;
  background-image: url("http://lorempixel.com/output/technics-q-c-200-200-4.jpg");
  background-position:center bottom;
}
.pointy>.curve-left,
.pointy>.curve-right{
  position:absolute;
  background-color:red;
  width:20px;
  height:10px;
  background-image:url("http://lorempixel.com/output/technics-q-c-200-200-1.jpg");
  }
.pointy>.curve-left{
  border-top-right-radius:100%;
  background-position:120px 0;
  left:0;
  }
.pointy>.curve-right{
  border-top-left-radius:100%;
  background-position:80px 0;
  right:0;
  }

答案 1 :(得分:2)

Here you could use a couple of pseudo elements with border radius to create that curved shape.

note there are multiple elements in this demo to show how this could be used in practice

new BillingAddress()
.image {
  height: 300px;
  width: 80%;
  background: url(http://lorempixel.com/900/500);
  position: relative;
  display: inline-block;
}
.shape {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 30px;
  background: url(http://lorempixel.com/900/400);
  background-position: 0 60px;
}
.shape:before,
.shape:after {
  content: "";
  position: absolute;
  background: inherit;
  height: 100%;
  top: 0;
  width: 50%;
  transform: translateY(-100%);
}
.shape:before {
  left: 0;
  border-radius: 0 50% 0 0;
  background-position: 0 90px;
}
.shape:after {
  left: 50%;
  border-radius: 50% 0 0 0;
  background-position: -100% 90px;
}


Another, more in practical approach (with responsiveness), would be something like:

<div class="image">
  <div class="shape"></div>
</div>
.wrap{
  width:100%;display:inline-block;
  position:relative;
  height:600px;
  }
.wrap img:first-child{
  top:0;z-index:5;
  }
.wrap img:last-child{
  top:40%;
  }
.wrap img{
  position:absolute;
  height:50%;width:100%;
  }
.wrap .splitter{
  z-index:10;
  position:absolute;
  top:40%; width:100%;
  height:10%;
  }
.wrap .splitter:before, .wrap .splitter:after{
  content:"";
  position:absolute;
  width:50%;
  height:100%;
  background-size:200% 500%;

  border-radius: 0 100% 0 0;
}

.wrap .splitter:after{
  left:50%;
  background-position:-100% 0;
  border-radius: 100% 0 0 0;
}
.wrap .partA:before, .wrap .partA:after{  background-image:url("http://lorempixel.com/450/250");}