使用CSS3进行凹凸形状导航

Rak*_*nal 3 css css3 css-shapes

有没有办法创建透明背景颜色的导航栏,如下图所示?

在此输入图像描述

我尝试使用CSS3伪选择器,但曲线不符合设计:

div::before{
  width: 200px;
  height: 90px;
  background: rgba(255, 255, 255, 0.2);
  background: radial-gradient(circle 0 at -20% 50%,transparent,transparent 100px,rgba(255, 255, 255, 0.2) 100px),
   radial-gradient(circle 20px at 180px 50%,transparent,transparent 100px,rgba(255, 255, 255, 0.2) 100px);
  background-size:100px 90px, 100px 90px;
  background-position:0 0,100% 0;
  background-repeat:no-repeat
}
Run Code Online (Sandbox Code Playgroud)

Har*_*rry 10

您可以通过CSS以多种方式执行此操作,我在下面的答案中显示了其中的一些.我已经使用ulli标签,因为我觉得他们更适合于一个导航栏,但你可以很容易地转换它的工作div标签也.

CSS方法的一个缺点是父元素仍然基本上是一个矩形,因此鼠标交互将发生在曲线外(但在元素的边界内).我遇到这个问题的唯一方法是使用clip-path.

使用径向渐变:

这就像你开始做的那样.我刚刚将渐变设置在正确的位置,并使用它来产生右侧黑色边框.元素左侧的曲线使用border-radius属性完成.

径向渐变对于20px(元素高度的一半)是透明的,对于1px是黑色(以产生边框),对于其余部分具有所需的背景颜色.

使用渐变的缺点是它们不能在IE9中工作,因为它们不支持渐变.

li {
  position: relative;
  float: left;
  width: 33%;
  height: 40px;
  line-height: 36px; /* height - 2 * border width */
  text-indent: 10px;
  border: 2px solid rgba(0, 0, 0, .5);
  border-right: none;
  border-radius: 20px 0px 0px 20px;
  background: radial-gradient(20px 20px at calc(100% + 4px) 50%, transparent 18px, rgba(0, 0, 0, .5) 19px, rgba(0, 0, 0, .5) 20px, rgba(255, 255, 255, .25) 21px); /* the first color after transparent is border color, the last color is background color */
  background-clip: content-box;
  box-shadow: -1px 2px 1px rgba(0, 0, 0, .25);
  overflow: hidden;
}
ul {
  list-style-type: none;
}
* {
  box-sizing: border-box;
}
body {
  background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
  min-height: 100vh;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>
Run Code Online (Sandbox Code Playgroud)


使用Box Shadow:

这有更好的浏览器支持,因为box-shadow即使在IE9中也可以.对于这种方法,我们需要一个伪元素,它放在父元素的右边界内.两个元素(即伪和父)都有一个border-radius分配来创建曲线.使用box-shadow伪元素上的宽来实现背景颜色,因为将背景颜色分配给父元素或伪元素也将在形状外部流血.

li {
  position: relative;
  float: left;
  width: 33%;
  height: 40px;
  line-height: 36px; /* height - 2 * border width */
  text-indent: 10px;
  border: 2px solid rgba(0, 0, 0, .5);
  border-right: none;
  border-radius: 20px 0px 0px 20px;
  box-shadow: -1px 2px 1px rgba(0, 0, 0, .25);
  overflow: hidden;
}
ul {
  list-style-type: none;
}
li:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  left: calc(100% - 18px); /* 100% - (half of height  - border width) */
  top: -2px; /* inverse of border width */
  border-radius: 20px;
  border: 2px solid rgba(0, 0, 0, .5);
  box-shadow: 0px 0px 0px 999px rgba(255, 255, 255, .25); /* the color here is the background color */
  z-index: -1;
}
*{
  box-sizing: border-box;
}
body {
  background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
  min-height: 100vh;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>
Run Code Online (Sandbox Code Playgroud)


使用SVG:

您也可以使用SVG通过使用path元素创建所需的形状并相对于父元素绝对定位来实现此目的.

li {
  position: relative;
  float: left;
  width: 33%;
  height: 40px;
  line-height: 40px;
  text-indent: 10px;
}
ul {
  list-style-type: none;
}
svg {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
}
path {
  stroke: rgba(0, 0, 0, .5); /* border color */
  stroke-width: 2; /* border width */
  fill: rgba(255, 255, 255, .25); /* background color */
}
path:hover{
  stroke: red;
}
body {
  background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
  min-height: 100vh;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <svg viewBox='0 0 200 40' preserveAspectRatio='none'>
      <path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
    </svg>One</li>
  <li>
    <svg viewBox='0 0 200 40' preserveAspectRatio='none'>
      <path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
    </svg>Two</li>
  <li>
    <svg viewBox='0 0 200 40' preserveAspectRatio='none'>
      <path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
    </svg>Three</li>
</ul>
Run Code Online (Sandbox Code Playgroud)