Double curved shape

匿名 (未验证) 提交于 2019-12-03 02:12:02

问题:

I am currently attempting to generate a 'wavy ghostly bottom' shape. This shape contains two double curves:

Although the bottom part of this image I think portrays it in better imagery.


My Code

My Current Attempt to generate this shape was using pseudo elements and overflow: hidden, although this does not allow for a gradient background (would require a plain background):

Attempt 1 - Using Pseudo Elements with overflow hidden

.bottom {   height: 300px;   width: 300px;   background: lightgray;   position: relative;   overflow: hidden;   margin-top:-150px;   -webkit-transform:rotate(45deg);   transform:rotate(45deg); } .bottom:before, .bottom:after{   position: absolute;   content: "";   background: white;  } .bottom:before {     height: 150%;   width: 150%;    top: 50%;   border-radius:50%;   left: -45%; }  .bottom:after {     height: 200%;   width: 100%;    bottom: -40%;   border-radius:50%;   left: 90%; }
<div class="bottom"></div>

Attempt 2 - Using Pseudo Elements with 's' shape

.bottom {   background: lightgray;   width: 300px;   height: 300px;   position: relative;   overflow:hidden;   color:white;   border-radius:0 100% 0 100%; } .bottom:before{   content:"S";   position:absolute;   height:100%;   width:100%;   top:-100%;   left:-75%;   font-size:60em;   font-family: 'arial';   }  .bottom:after{   content:"S";   position:absolute;   height:100%;   width:100%;   top:-150%;   left:-75%;   font-size:60em;   font-family: 'arial';   }
<div class="bottom"></div>

Attempt 3 - extra elements and box shadows

I also have recently tried using box shadows and extra elements (which i would be ok with), but even then, I can't create it properly:

.bottom {     height:300px;     width:300px;     position:relative;     overflow:hidden; } .bottom-left {     position:absolute;     top:50%;     left:-50%;     height:100%;     width:100%;     border-radius:50%;     box-shadow: inset -35px 35px 0px -24px rgba(50, 50, 50, 1);     z-index:8;     background:white; } .top {     position:absolute;     height:100%;     top:-35%;     left:0;     width:50%;     border-radius:50%;     z-index:8;     background:gray;     box-shadow:inset 35px -35px 0px -24px rgba(50, 50, 50, 1); } .top-right {     position:absolute;     top:-80%;     left:45%;     height:120%;     width:100%;     border-radius:50%;     box-shadow:inset 35px -35px 0px -24px rgba(50, 50, 50, 1);     border:20px solid gray; } .bigone {     position:absolute;     top:0;     left:-20%;     height:105%;     width:100%;     border-radius:50%;     box-shadow:inset -35px -35px 0px -24px rgba(50, 50, 50, 1);     -webkit-transform:rotate(-30deg);     transform:rotate(-30deg);     -webkit-transform-origin:center center;     transform-origin:center center;     background:gray; }
<div class="bottom">     <div class="bottom-left"></div>     <div class="top"></div>     <div class="top-right"></div>     <div class="bigone"></div> </div>

None of these approaches seem to allow the generation of this double curved shape easily, and would require a 'block coloured background'

Note: I would be reluctant to resort to SVG since I have 90% of the 'overall shape' completed using just pure css, so It would be good/nice to complete this without an svg element


The internal shape would be a block color, but the border isn't compulsory/critical in my design.

this is where I would like to add it to


Update

回答1:

Considering :

  • the amount of code needed
  • the hassle of aligning double curves

CSS doesn't seem to be the way to go here and SVG way more appropriate. To illustrate, see these two snippets :

SVG

DEMO

/*** FOR THE DEMO **/ svg{     display:block;     width:70%;     margin:0 auto;     opacity:0.8; } body{     background: url('http://lorempixel.com/output/people-q-g-640-480-7.jpg');     background-size:cover; }
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 80">     <path stroke-width="1" stroke="#000" fill="grey" d="M95 5 Q70 20 70 38 T50 65 Q55 50 30 40 T5 5z"/> </svg>

CSS

DEMO (consider I only made one double curve on the right side of the shape)

.ghost {   position: relative;   width: 400px;   height: 300px;   margin: 0 auto;   overflow: hidden; } .ghost:before, .ghost:after {   content: '';   position: absolute; } .ghost:before {   bottom: 0;   right: 50%;   width: 70%;   height: 30%;   transform-origin: 100% 100%;   transform: skewY(30deg) rotate(20deg);   box-shadow: -100px -100px 0px 99px #656565;   border-top-right-radius: 30% 100%; } .ghost:after {   top: 0;   right: 0;   transform-origin: 100% 0;   transform: skewX(-10deg) rotate(-20deg);   box-shadow: none;   height: 107px;   width: 173px;   border-top-left-radius: 90% 100%;   box-shadow: -30px -30px 0px 29px #656565, 60px -110px 0px 109px #656565; }
<div class="ghost"> </div>

Note that I didn't list out the advantages of using an svg in this case (responsiveness, quality of output, curve control, border, border color/opacity, fill colour/opacity, transparency, maintainability, amount of time to build the shape...)



回答2:

You should use boxshadows and overflows to make that shape.

body {background:url('http://whofortedblog.com/wp-content/uploads/2013/01/33c9f33218a6cab6054375fb76129a80.jpeg'); background-size: cover;} div {   height: 100px;   width: 200px;   overflow: hidden;   position: relative;   -webkit-transform: scale(1,1.1);   -moz-transform: scale(1,1.1);   -ms-transform: scale(1,1.1);   -o-transform: scale(1,1.1);   transform: scale(1,1.1); } div:before {   height: 80px;   width: 100px;   border-radius: 50% / 50%;   box-shadow: 40px -11px 0 -20px white, 42px -22px 0 -10px white, 50px -28px 0 -8px white, 36px -95px 0 20px white;   content: "";   position: absolute;   -webkit-transform: scale(0.9,1.1);   -moz-transform: scale(0.9,1.1);   -ms-transform: scale(0.9,1.1);   -o-transform: scale(0.9,1.1);   transform: scale(0.9,1.1);   top: 50%;   left: -10px; } div:after {   height: 70px;   width: 120px;   border-radius: 50%;   -webkit-transform: rotate(-35deg);   -moz-transform: rotate(-35deg);   -ms-transform: rotate(-35deg);   -o-transform: rotate(-35deg);   transform: rotate(-35deg);   box-shadow: ;   content: "";   position: absolute;   top: -1%;   box-shadow: -1px -28px 0 5px white;   right: -35px; }
<div></div>

You can certainly improve this version using good position values! In any case, you should almost never use this solution. the best option in my opinion would be a png image or SVG.

Working:

div {   height: 100px;   width: 200px;   overflow: hidden;   position: relative;   border: 1px solid black; } div:before {   height: 80px;   width: 100px;   border-radius: 50% / 50%;   background-color: red;   box-shadow: 40px -9px 0 -20px blue, 42px -20px 0 -10px pink, 50px -25px 0 -8px plum, 37px -95px 0 20px green;   content: "";   position: absolute;   top: 50%;   left: -10px; } div:after {   height: 70px;   width: 120px;   border-radius: 50%;   background-color: rgba(255, 215, 0, 0.6);   -webkot-transform: rotate(-35deg);   -moz-transform: rotate(-35deg);   -o-transform: rotate(-35deg);   -ms-transform: rotate(-35deg);   transform: rotate(-35deg);   box-shadow: ;   content: "";   position: absolute;   top: -1%;   box-shadow: -4px -27px 0 5px rgba(0, 255, 215, 0.6);   right: -44px; }
<div></div>


文章来源: Double curved shape
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!