凹凸形状导航使用CSS3
Concave and convex shape navigation using CSS3
有什么方法可以创建像下图这样具有透明背景色的导航栏吗?
我尝试使用 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
}
您可以使用 CSS 以多种方式执行此操作,我在下面的答案中展示了其中的一些。我使用了 ul
和 li
标签,因为我觉得它们更适合导航栏,但您也可以轻松地将其转换为与 div
标签一起使用。
这两种 CSS 方法都有一个缺点,即父元素基本上仍然是一个矩形,因此鼠标交互会发生在曲线外(但在元素边界内)。我对这个问题的唯一解决方案是使用 clip-path
.
使用径向渐变:
这就像你开始做的一样。我刚刚将渐变设置在正确的位置,并用它来生成右侧的黑色边框。元素左侧的曲线是使用 border-radius
属性.
完成的
20px 的径向渐变(元素高度的一半)是透明的,1px 是黑色的(产生边框),其余部分具有所需的背景色。
使用渐变的缺点是they would not work in IE9 and lower因为它们不支持渐变。
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;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
使用框阴影:
这有更好的浏览器支持,因为 box-shadow
works even in 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;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
使用 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;
}
<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>
有什么方法可以创建像下图这样具有透明背景色的导航栏吗?
我尝试使用 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
}
您可以使用 CSS 以多种方式执行此操作,我在下面的答案中展示了其中的一些。我使用了 ul
和 li
标签,因为我觉得它们更适合导航栏,但您也可以轻松地将其转换为与 div
标签一起使用。
这两种 CSS 方法都有一个缺点,即父元素基本上仍然是一个矩形,因此鼠标交互会发生在曲线外(但在元素边界内)。我对这个问题的唯一解决方案是使用 clip-path
.
使用径向渐变:
这就像你开始做的一样。我刚刚将渐变设置在正确的位置,并用它来生成右侧的黑色边框。元素左侧的曲线是使用 border-radius
属性.
20px 的径向渐变(元素高度的一半)是透明的,1px 是黑色的(产生边框),其余部分具有所需的背景色。
使用渐变的缺点是they would not work in IE9 and lower因为它们不支持渐变。
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;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
使用框阴影:
这有更好的浏览器支持,因为 box-shadow
works even in 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;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
使用 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;
}
<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>