【问题标题】:Draw double curved item with beveled edges绘制带有斜边的双曲线项目
【发布时间】:2018-07-12 17:10:16
【问题描述】:

我正在创建一个网站,顶部有一个标题/菜单。 中间有一个标志。为了强调这一点,我在徽标下方绝对放置了一个省略号:因此,在下方,您会看到省略号,它与菜单的其余部分完美融合。

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

现在客户希望看到左右“角”也弯曲了:

我知道“在菜单下方添加一个省略号”的方法是不够的。 我在考虑两种可能的解决方案:

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

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

我更喜欢 css 解决方案,因为我不是 SVG 的大英雄。但是如果使用 SVG 可以更容易地实现它。然后我会取消该解决方案。

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

椭圆需要涂成白色。

【问题讨论】:

  • 您可以使用 SVG 直接塑造您的 HTML 元素:sarasoueidan.com/blog/css-svg-clipping 有帮助吗?
  • 它会有所帮助。但我无法创建具有这种形状的 SVG..
  • @sjahan 请注意,CSS clip-path 属性目前仍是一项实验性功能,并非所有常见浏览器都支持。 Here's the support overview.
  • @NamelessLambda true,我已经使用过它,但它只适用于我认为复杂形状的 webkit 浏览器...:/
  • 安装一个 SVG 编辑器,比如 Inkscape 并绘制任何你想要的 SVG 形状。

标签: html css svg


【解决方案1】:

SVG 将是解决此类问题的方法,但对于 CSS 解决方案,我可能会使用具有线性/径向渐变的多个背景 ,缺点是可能难以计算不同的值并使整个形状响应。

这是一个可以帮助您了解一些想法的示例:

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;
}
<div class="header">

</div>

<div class="header-tr">

</div>

如果你愿意使用多个元素,你可以依赖伪元素和一些边框半径,但你还必须管理很多元素:

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;
}
<div class="header">
  <div class="top"></div>
</div>

这是一个 SVG 解决方案:

<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>

【讨论】:

  • 问题是:你画的渐变,是一张图片。所以那部分应该是透明的。椭圆必须是白色的。
  • @KornelitoBenito 是的,我们可以用透明的方式替换所有内容;)我会更新
  • 那么上面也是白色的吗?而不是“透明的”?另外,我假设边框宽度可以更薄?
  • @KornelitoBenito 是的白色,但如果你愿意,我可以设法让它变得透明 :) .. 我更新了我的答案以使内部透明。
  • 我需要得到边框@ 2px solid #dfe0e4。但这是我可以尝试实现的。我不是背景中的英雄。这似乎是相当先进的东西;)。谢谢!
【解决方案2】:

差不多了……它可能会妨碍你。

我在标题上使用了::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】:

我创建了 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;}

最终结果

【讨论】:

  • 是的一个 svg 家伙!比我们的 CSS 解决方案更好。我需要学习它。
  • @AlexVand 实际上我从 1 小时前开始就不知道该怎么做了。 :)
  • 你是凯尔 XY 吗?
  • 这有点容易扩展吗?
  • 正如我解释的那样,它是响应式的。尝试调整输出窗口的大小
【解决方案4】:

这是一个带有二次贝塞尔曲线的内联 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多