css - 带 CSS 的 Sigmoid 曲线形状

标签 css svg css-shapes rounded-corners

我想创建一个 sigmoid curve类似形状的全屏布局,一侧显示装饰性图案背景,另一侧显示纯色背景,用于将文本放置在其顶部。

目标是有一个全屏页面,左上 Angular 有一个类似 sigmoid 的图案,页面的其余部分只是有白色背景。

JSFiddle:Unfinished sigmoid curve

#container {
  padding-top: 10%;
  padding-bottom: 10%;
  background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#parallelogram {
  margin-left: 35%;
  width: 100%;
  height: 900px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
  background: white;
  -moz-border-radius: 100px;
  -webkit-border-radius: 100px;
  border-radius: 100px;
  -moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  -webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
  <div id="parallelogram">
  </div>
</div>


我不知道如何在左下 Angular 附近创建(或模拟)倒圆 Angular 。

或者也许有一个概念上不同(更好)的解决方案可用?

更新:我想出了如何创建 shape I need完全用CSS。

#container {
  padding-top: 100px;
  background: red;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#parallelogram {
  margin-left: 400px;
  width: 100%;
  height: 900px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
  background: white;
  -moz-border-top-left-radius: 100px;
  -webkit-top-left-border-radius: 100px;
  border-top-left-radius: 100px;
}
#bottom {
  height: 200px;
  width: 100%;
  background: white;
}
#bottom-corner {
  height: 100px;
  width: 300px;
  margin-left: -34px;
  background: red;
  -moz-border-bottom-right-radius: 100px;
  -webkit-bottom-right-border-radius: 100px;
  border-bottom-right-radius: 100px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
}
<div id="container">
  <div id="parallelogram">
  </div>

  <div id="bottom">
    <div id="bottom-corner">
    </div>
  </div>
</div>


然而,这仍然不是最终的解决方案,因为形状不允许我使用我想到的那种背景效果。这是我尝试时发生的情况:fiddle .

#container {
  padding-top: 100px;
  background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) bottom left / 26px 32px repeat;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#parallelogram {
  margin-left: 400px;
  width: 100%;
  height: 900px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
  background: white;
  -moz-border-top-left-radius: 100px;
  -webkit-top-left-border-radius: 100px;
  border-top-left-radius: 100px;
  -moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  -webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom {
  height: 200px;
  width: 100%;
  background: white;
  -moz-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  -webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-corner {
  height: 100px;
  width: 300px;
  margin-left: -34px;
  background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
  -moz-border-bottom-right-radius: 100px;
  -webkit-bottom-right-border-radius: 100px;
  border-bottom-right-radius: 100px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
  -moz-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
  -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .4);
  box-shadow: 0 0 15px rgba(0, 0, 0, .4);
}
<div id="container">
  <div id="parallelogram">
  </div>

  <div id="bottom">
    <div id="bottom-corner">
    </div>
  </div>
</div>


后期更新:经过一些反复试验,我最终得到了 ridiculously crude hack solution达到了我需要的视觉效果:

#container {
  padding-top: 100px;
  background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#parallelogram {
  margin-left: 385px;
  width: 100%;
  height: 900px;
  -webkit-transform: skew(-15deg);
  -moz-transform: skew(-15deg);
  -o-transform: skew(-15deg);
  transform: skew(-15deg);
  background: white;
  -moz-border-top-left-radius: 100px;
  -webkit-top-left-border-radius: 100px;
  border-top-left-radius: 100px;
  -moz-box-shadow: inset 0 15px rgba(0, 0, 0, .4);
  -webkit-box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
  box-shadow: inset 0 0 15px rgba(0, 0, 0, .4);
}
#bottom-rounded-corner {
  height: 122px;
  position: relative;
  width: 200%;
  z-index: 1000;
  margin-top: -80px;
  margin-left: -185px;
  background: url(http://famok.com/wp-content/uploads/2016/11/CornerAndMask.png) top left no-repeat;
}
#bottom-white {
  height: 100px;
  width: 100%;
  background: white;
}
<div id="container">
  <div id="parallelogram">
  </div>
  <div id="bottom-rounded-corner">

  </div>
  <div id="bottom-white">
  </div>
</div>


尽我所能实现下面 Harry 建议的概念上更好的替代方案,但我无法使用它来创建我想要的效果。如果有人可以提供帮助,我仍然会很感激,无论是通过展示如何做到这一点,还是通过对我的解决方案提出优化建议。

提前谢谢你!

最佳答案

对复杂形状使用 SVG 而不是 CSS:

正如我在评论中提到的,请不要使用 CSS 来创建如此复杂的形状。 SVG 是处理此类复杂内容的推荐工具。 SVG 易于创建、维护,并且默认情况下它们也是响应式的(可缩放的),因此它有很多优点。

创建 sigmoid 形状:

使用 SVG 本身创建 sigmoid 曲线形状非常简单,只需要一个路径元素:

  • M0,750将假想的笔靠近 SVG 元素的左下 Angular (坐标设置为略低于 SVG 的高度,以便在底部有一个间隙,可以看到阴影)。
  • L250,750产生水平 L 从点 (0,768) 到 (250,768)
  • C650,730 500,154 1024,154创建实际曲线。这里前两个坐标是曲线的控制点 ((650,730), (500,154)),第三个坐标是终点 (1024,154)。可以通过修改控制点来调整曲线的曲率。
  • L1024,0 0,0 0,750是为了完成形状。形状需要完整才能填充工作。


  • body {
      margin: 0;
    }
    svg {
      width: 100%;
      height: 100vh;
    }
    <svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
    
      <!-- For the shadow -->
      <defs>
        <filter id="dropShadow">
          <feGaussianBlur in="SourceAlpha" stdDeviation="6" />
          <feOffset dx="3" dy="3" result="offsetBlur" />
          <feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
          <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
          <feMerge>
            <feMergeNode />
            <feMergeNode in="SourceGraphic" />
          </feMerge>
        </filter>
      </defs>
      <!-- End of shadow -->
    
      <!-- For filling the top-left with pattern -->
      <pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
        <polygon points='0,0 0,25 25,25 25,0' fill='yellowgreen' />
        <circle cx='12.5' cy='12.5' r='4' fill='rebeccapurple' />
      </pattern>
      <!-- End of pattern -->
    
      <!-- Actual sigmoid curve -->
      <path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
    
    </svg>



    将图案应用于形状:

    在上面的演示中,我使用 polygon 创建了一个圆点图案。和 circle元素,但在 SVG 本身中创建它不是强制性的,我们也可以使用 image元素并用图像图案填充形状。

    如果您想将背景图片(图案)更改为您选择的另一张图片,只需在 xlink:href 中指定您图片的 URL。 image 的属性像下面的代码片段一样标记。根据您的需求和形象,您可能需要更改 heightwidthpatternimage .
    <pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
      <image xlink:href='https://yourwebsite.com/yourpath' x='0' y='0' width='15' height='15' />
    </pattern>
    

    body {
      margin: 0;
    }
    svg {
      width: 100%;
      height: 100vh;
    }
    <svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
      <defs>
        <filter id="dropShadow">
          <feGaussianBlur in="SourceAlpha" stdDeviation="6" />
          <feOffset dx="3" dy="3" result="offsetBlur" />
          <feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
          <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
          <feMerge>
            <feMergeNode />
            <feMergeNode in="SourceGraphic" />
          </feMerge>
        </filter>
        <pattern id='dots' patternUnits='userSpaceOnUse' width='36.6' height='46'>
          <image xlink:href='http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg' x='0' y='0' width='36.6' height='46' />
        </pattern>
      </defs>
      <path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
    </svg>


    注意:上面演示中使用的图像不是我自己的。它是从互联网上截取的。

    影子:

    阴影效果是使用 SVG 创建的 filter元素以及 feGaussianBlur , feOffsetfeMerge元素。 feGaussianBlur 元素通过指定的标准偏差值和 feOffset 模糊源图形(我们的 sigmoid)将结果图像偏移 dx , dy值。原始图像和模糊图像使用 feMerge 合并. feFlood feComposite 以防万一你想给阴影一个不同的颜色。可以使用 flood-color 指定颜色和 flood-opacity属性。 (更改 SVG 阴影颜色的方法来自 Joe W.的 this answer。)

    添加文本:

    现在这是整个事情中真正棘手的一点。如果您只需要将文本放置在页面的纯色区域,则需要谨慎使用定位属性。如果文本很小或只有一行文本,那么我们可以使用 SVG text元素本身就像我之前链接的演示中一样。如果不是,那么您必须确保文本的容器框不会重叠到 sigmoid 形状的区域上。

    body {
      margin: 0;
    }
    div.container {
      position: relative;
      width: 100%;
      height: 100vh;
    }
    svg {
      position: absolute;
      top: 0px;
      left: 0px;
      height: 100%;
      width: 100%;
    }
    .container div {
      position: absolute;
      top: 50%;
      right: 0px;
      height: 30vh;
      width: 33.33%;
      font-size: 20px;
    }
    <div class='container'>
      <svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
    
        <defs>
          <!-- For the shadow -->
          <filter id="dropShadow">
            <feGaussianBlur in="SourceAlpha" stdDeviation="6" />
            <feOffset dx="3" dy="3" result="offsetBlur" />
            <feFlood flood-color="#AAA" flood-opacity="1" result="offsetColor" />
            <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlur" />
            <feMerge>
              <feMergeNode />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
          <!-- End of shadow -->
    
          <!-- For filling the top-left with pattern -->
          <pattern id='dots' patternUnits='userSpaceOnUse' width='25' height='25'>
            <polygon points='0,0 0,25 25,25 25,0' fill='yellowgreen' />
            <circle cx='12.5' cy='12.5' r='4' fill='rebeccapurple' />
          </pattern>
          <!-- End of pattern -->
        </defs>
    
        <!-- Actual sigmoid curve -->
        <path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,0 0,0 0,750' fill='url(#dots)' filter='url(#dropShadow)' />
    
      </svg>
      <div>Hello! Here is some text that is placed on the solid colored area of the page.</div>
    </div>


    我们可以尝试使用 CSS shape-outside属性(property)但browser support for that is pretty poor此刻。这是一个 demo使用这个 shape-outside属性(property)。无法在现场托管它,因为它需要创建一个单独的 SVG 文件。该演示是 W3C CSS Shapes Spec 中提供的版本的改编版本。 .

    替代方法: (将模式应用于容器而不是 SVG)

    由于您不希望图像被压扁或拉伸(stretch),另一种方法是执行以下操作:
  • 创建 SVG 形状,使其仅是纯色部分(而不是图案区域)
  • 将图案应用到 div.container然后将 SVG 绝对放在元素的顶部。 SVG 形状(具有白色填充)将防止图案在另一侧可见。
  • 将 SVG 上的阴影从普通投影更改为插入阴影。 (Inset Shadow 的代码完全取自 here


  • body {
      margin: 0;
    }
    div.container {
      position: relative;
      background: white url(http://famok.com/wp-content/uploads/2016/10/WhiteOnWhite.jpg) top left / 26px 32px repeat;
      width: 100%;
      height: 100vh;
    }
    svg {
      position: absolute;
      top: 0px;
      left: 0px;
      height: 100%;
      width: 100%;
    }
    .container div {
      position: absolute;
      top: 50%;
      right: 0px;
      height: 30vh;
      width: 33.33%;
      font-size: 20px;
    }
    <div class='container'>
      <svg viewBox='0 0 1024 768' preserveAspectRatio='none'>
        <defs>
          <filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
            <feComponentTransfer in=SourceAlpha>
              <feFuncA type="table" tableValues="1 0" />
            </feComponentTransfer>
            <feGaussianBlur stdDeviation="6" />
            <feOffset dx="2" dy="2" result="offsetblur" />
            <feFlood flood-color="#AAA" result="color" />
            <feComposite in2="offsetblur" operator="in" />
            <feComposite in2="SourceAlpha" operator="in" />
            <feMerge>
              <feMergeNode in="SourceGraphic" />
              <feMergeNode />
            </feMerge>
          </filter>
        </defs>
        <path d='M0,750 L250,750 C650,730 500,154 1024,154 L1024,768 0,768 0,750' fill='white' filter='url(#dropShadow)' />
      </svg>
      <div>Hello! Here is some text that is placed on the solid colored area of the page.</div>
    </div>


    这是Plunker Demo对于替代方法。这比前一个复杂一点,因为这里我们需要一个 SVG 来生成纯色区域(用作 img )和另一个 SVG 是与 shape-outside 一起使用的相反(图案区域)。 .

    关于css - 带 CSS 的 Sigmoid 曲线形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40350457/

    相关文章:

    pdf - Inkscape “PDF + Latex”导出

    css - 带图像的多边形

    html - 使按钮看起来与链接相同

    css - 如何避免没有溢出的水平滚动-x : hidden

    jquery - 屏蔽动画 GIF - 这可以用 Jquery 或其他吗?

    html - 如何使用 html5、css3 获得椭圆形

    html - 如何防止此 css 形状左右滚动

    jquery - 加载条显示在图像旁边

    css - svg 文本上的线性渐变问题

    javascript - 动态更改 SVG 元素后对其进行动画处理