绘制带有斜边的双弯曲物品

时间:2018-02-02 08:29:36

标签: html css svg

我正在创建一个网站,顶部有标题/菜单。 在中间,有一个标志。为了突出这一点,我绝对在徽标下方放置了一个椭圆:所以在下面,你会看到椭圆,它与菜单的其余部分完美融合。

.ellips {
        border-radius: 50%;
        height: 130%;
        background: white;
        left: 0px;
        right: 0px;
        z-index: 1;
        position: absolute;
        top: 6%;
        border: 2px solid #dfe0e4;
    }

Absolutely positioned ellips

现在客户希望看到左边和右边的'角落'也是弯曲的:

enter image description here

我知道“在菜单下方推动椭圆”方法是不够的。 我在考虑两种可能的解决方案:

  1. 使用曲线创建一个SVG,并将其放在菜单下方。我尝试过这个解决方案,但我不是SVG专家,所以我尝试了一种CSS方法:

  2. 尝试使用这样的曲线创建CSS项目(div):上面是白色,下面是透明的。将数据项放在菜单下方。

  3. 我更喜欢css解决方案,因为我不是SVG中的大英雄。但是如果使用SVG可以更轻松地实现它。然后我会采取这个解决方案。

    编辑:您看到的蓝色背景是一个底层图像。所以这需要透明。

    椭圆需要涂上白色。

    enter image description here

4 个答案:

答案 0 :(得分:2)

我创建了2个SVG示例,因此您可以选择应用背景的位置

  

Codepen demo

每个SVG元素的外部容器保持特定的宽高比,因此整个元素可以响应(但是,当然,您也可以指定固定的宽度或高度)。

基本思路是创建path 溢出 SVG元素的大小,这样您就可以在顶部区域或底部定义一个封闭的形状区域,为了用颜色填充它(如果你将viewbox放大到例如-10 -10 610 130,你可以看到路径是如何实际定义的。)

应用的背景是渐变,但您也可以指定单个颜色停止(白色,在您的特定场景中)。 body元素的背景显示SVG的透明部分。

曲线,视箱,颜色的微调和调整留给读者。

对于形状的任何更改,您都可以阅读path documentation on MDN

<强>标记

<div class="doublecurve">
  <svg viewBox="0 0 600 120" xmlns="http://www.w3.org/2000/svg">

    <defs>
      <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%"   stop-color="#d8e5f1" />
        <stop offset="100%" stop-color="#91b4d3" />
      </linearGradient>
    </defs>

    <path class="concave" fill="url(#gradient)" d="M-2 2 
            L75 2 A75 75 0 0 1 110 20 C200 100 400 100 480 20
            A75 75 0 0 1 525 2 L602 2 L602 122 L-2 122 z"/>
  </svg>
</div>



<div class="doublecurve">
  <svg viewBox="0 0 600 120" xmlns="http://www.w3.org/2000/svg">

    <defs>
      <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%"   stop-color="#d8e5f1"/>
        <stop offset="100%" stop-color="#91b4d3"/>
      </linearGradient>
    </defs>

    <path class="concave" fill="url(#gradient)" d="M-2 2 
            L75 2 A75 75 0 0 1 110 20 C200 100 400 100 480 20
            A75 75 0 0 1 525 2 L602 2 L602 -2 L-2-2"/>
  </svg>
</div>

<强> CSS

.doublecurve {
  width: 100%;
  height: 0;
  margin: 20px 0;
  border: 1px dashed #bc9;
  padding-bottom: 20%;
  position: relative; }

.doublecurve svg { 
  position: absolute;
  width: 100%; height: 100%;}

.doublecurve path.concave { 
  stroke: #d0d0d0; 
  stroke-width: 4px;}

最终结果

enter image description here

答案 1 :(得分:1)

SVG将是这样的事情,但对于CSS解决方案,我可能会使用多个背景线性/径向渐变,缺点是可能很难计算出不同的价值并使整个形状响应。

以下是一个可以帮助您了解的示例:

&#13;
&#13;
body {
  background:grey;
}

.header {
  border: 5px solid red;
  border-top: none;
  height: 100px;
  width: 600px;
  background: 
  radial-gradient(ellipse at -7px 26px, transparent 50%, red 50%, red calc(50% + 11px), white 0%) 101px -3px/7% 19% no-repeat, 
  radial-gradient(ellipse at 60px 26px, transparent 50%, red 50%, red calc(50% + 11px), white 0%) 454px -4px/7% 19% no-repeat, 
  radial-gradient(ellipse at top, white 20%, red 20%, red calc(21% + 2px), transparent 0%) 50% 0/200% 200% no-repeat,
  linear-gradient(red 50%,transparent 0%) 0 0/100% 10px no-repeat, 
  linear-gradient(to right, gray, blue);
}
.header-tr {
  border: 5px solid red;
  margin-top:20px;
  border-top: none;
  height: 100px;
  width: 600px;
  background: 
  radial-gradient(ellipse at -7px 26px, transparent 50%, red 50%, red calc(50% + 11px), white 0%) 101px -3px/7% 19% no-repeat, 
  radial-gradient(ellipse at 60px 26px, transparent 50%, red 50%, red calc(50% + 11px), white 0%) 454px -4px/7% 19% no-repeat, 
  radial-gradient(ellipse at top, white 20%, red 20%, red calc(21% + 2px), transparent 0%) 50% 0/200% 200% no-repeat,
  linear-gradient(red 50%,transparent 0%) 0 0/110px 10px no-repeat,
  linear-gradient(red 50%,transparent 0%) 100% 0/110px 10px no-repeat;
}
&#13;
<div class="header">

</div>

<div class="header-tr">

</div>
&#13;
&#13;
&#13;

如果您打开使用多个元素,您可以依赖伪元素和一些border-radius,但您还需要管理很多元素:

&#13;
&#13;
body {
  background: gray;
}

.header {
  margin-top: 30px;
  border: 5px solid red;
  border-top: none;
  height: 100px;
  position: relative;
  overflow: auto;
}

.top {
  position: absolute;
  top: -40px;
  right: 80px;
  left: 80px;
  height: 80px;
  border: 5px solid red;
  border-top: none;
  border-radius: 0 0 50% 50%;
  background: #fff;
}

.top:before {
  content: "";
  position: absolute;
  top: 23px;
  right: calc(100% - 11px);
  left: -80px;
  border-top: 18px solid #fff;
  border-radius: 0 50% 0 0;
  border-bottom: 0;
  border-left: 0;
  height: 52px;
  z-index: 0;
}

.top:after {
  content: "";
  position: absolute;
  top: 23px;
  left: calc(100% - 11px);
  right: -80px;
  border-top: 18px solid #fff;
  border-radius: 50% 0 0 0;
  border-bottom: 0;
  border-right: 0;
  height: 52px;
  z-index: 0;
}

.header:before {
  content: "";
  position: absolute;
  top: 0;
  right: calc(100% - 88px);
  left: 0;
  border-top: 5px solid red;
  border-radius: 0 50% 0 0;
  border-bottom: 0;
  border-left: 0;
  height: 25px;
  z-index: 99;
}

.header:after {
  content: "";
  position: absolute;
  top: 0;
  left: calc(100% - 88px);
  right: 0;
  border-top: 5px solid red;
  border-radius: 50% 0 0 0;
  border-bottom: 0;
  border-right: 0;
  height: 25px;
  z-index: 99;
}
&#13;
<div class="header">
  <div class="top"></div>
</div>
&#13;
&#13;
&#13;

这是一个SVG解决方案:

&#13;
&#13;
<svg
  xmlns='http://www.w3.org/2000/svg'
  viewBox='0 0 75 50'
  width='600' height='300'
  fill='transparent'>
  <path d='M0 24 L64 24 L64 2 L58 2 C36 2 46 10 32 10 C18 10 26 2 4 2 L0 2 Z' stroke="red" stroke-width="1" />
</svg>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

几乎在那里......它可能会阻碍你。

我在标题上使用了::before::after来添加两条曲线。

使用半径值稍微玩一下,得到你想要的东西。

椭圆具有固定的宽度,因此尽可能地响应。调整屏幕大小时,角落不会破裂,但椭圆的大小不会改变。

html,
body {
  margin: 0;
  padding: 0;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  background: linear-gradient(to right, #d2e1f1, #86acd0);
}

header {
  height: 100px;
  background: white;
  position: relative;
}
header::before, header::after {
  content: "";
  display: block;
  width: calc(50% - 80px);
  position: absolute;
  top: 95px;
  height: 80px;
  border: 6px solid #dadbe0;
  border-right-color: transparent;
  border-left-color: transparent;
  border-bottom: 0;
  z-index: 3;
}
header::before {
  left: 0px;
  border-radius: 0px 140px 0px 0px/0px 60px 0px 0px;
}
header::after {
  right: 0px;
  border-radius: 140px 0px 0px 0px/60px 0px 0px 0px;
}

.ellips {
  background: white;
  height: 120px;
  width: 300px;
  position: absolute;
  bottom: -40px;
  z-index: -1;
  border-radius: 0px 0px 90% 90%/0px 0px 90px 90px;
  left: 50%;
  transform: translate(-50%);
  border: 6px solid #dadbe0;
}

.masks {
  background: white;
  height: 9px;
  width: 330px;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  border-radius: 0px 0px 90% 90%/0px 0px 90px 90px;
  bottom: -8px;
}
<header>
  <div class="ellips">
  </div>
  <div class="masks"></div>
</header>

答案 3 :(得分:1)

这是一个带有二次贝塞尔曲线的内联SVG解决方案 svg图像的尺寸为500x50像素,绝对位于标题中。

.your-header {
  border-top: 2px solid #dfe0e4;
  position: relative;

  /* These two are just for demo */
  background-color: lightblue;
  height: 75px;
}

svg.ellipse {
  height: 50px;
  width: 500px;
  /* Centers the svg horizontal */
  left: 50%;
  margin-left: -250px;
  position: absolute;
  /* 2px up due to the parents border */
  top: -2px;
}

svg.ellipse > .border-clear{
  /* A white line to cover up the parents border */
  stroke: white;
  stroke-width: 3px;
}

svg.ellipse>.wave {
  stroke: #dfe0e4;
  stroke-width: 2px;
  fill: white;
}
<div class="your-header">
  <svg class="ellipse">
    <path d="M0 0 H499" class="border-clear" />
    <path d="M0 1 Q 62.5 1, 125 26 T 250 49 T 375 26 T 500 1" class="wave"/>
  </svg>
</div>