我想在我的导航栏菜单中间创建一个半圆形的水平矩形。除此之外,所有这些形状都必须有背景图像。
这样的事情:
实现这一目标的最佳方法是什么?
答案 0 :(得分:10)
使用SVG: (推荐)
创建这样的形状的最佳工具是SVG而不是CSS。 SVG是可扩展的(对于响应式设计非常有用),它们允许我们更好地控制形状方面 - 例如圆形或椭圆的斜率/曲率,也可以将图像或渐变作为填充(背景),如下图所示。
使用SVG绘制形状非常容易。只需使用path
元素以及移动(M
),弧(A
),行(L
)和近路(z
等命令)。绘制形状后,使用fill
和pattern
元素将图像应用为image
。 xlink:href
属性是指图片的来源。
以下是对上述命令的详细解释。详细说明可在this MDN page:
中找到M
- 将笔移动到命令后立即给出的坐标指定的点。A
- 绘制具有指定X和Y半径的圆弧,以命令后指定的点结束。L
- 从一个指定点到另一个指定一条直线。z
- 通过从路径的最后一个点到第一个点绘制一条直线来关闭路径。
path {
fill: url(#g-image);
}
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg viewBox='0 0 500 60' preserveAspectRatio='none'>
<defs>
<pattern id="g-image" width="1" height="1" patternUnits="objectBoundingBox">
<image xlink:href="http://lorempixel.com/500/60/abstract/6" width="500" height="60" />
</pattern>
</defs>
<path d='M0,0 0,25 205,25 A50,50 0 0,0 295,25 L500,25 500,0z' />
</svg>
使用剪辑路径:
另一种替代方法是使用clip-path
,但不能使用其纯CSS版本,因为(a)它只能创建简单/基本形状而不是我们需要的路径和(b)它在Firefox中不起作用。因此,我们必须使用clip-path
和内联SVG元素,如下所示。
使用clip-path
的缺点是,即使使用内联SVG元素,这也无法在IE中使用。
div {
height: 75px;
width: 600px;
background: url(http://lorempixel.com/500/100/abstract/6);
-webkit-clip-path: url(#clipper);
clip-path: url(#clipper);
}
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg width='0' height='0'>
<defs>
<clipPath id='clipper' clipPathUnits='objectBoundingBox'>
<path d='M0,0 0,.42 .41,.42 A.1,.83 0 0,0 .59,.42 L1,.42 1,0z' />
</clipPath>
</defs>
</svg>
<div></div>
使用CSS掩码:
由于浏览器支持不佳,目前不支持此选项,但在所有浏览器开始支持时,这是一个非常好的选择。在这种方法中,我们创建一个基于radial-gradient
的遮罩,除了圆弧区域外,它会切除图像的底部。由于渐变可以采用固定像素值作为圆形切割的X和Y轴的半径,因此即使图像被拉伸以响应,该弧形区域的长度也不会增加。
div {
height: 100px;
width: 100%;
background: url(http://lorempixel.com/600/100/abstract/6);
-webkit-mask-image: linear-gradient(to right, white, white), radial-gradient(145px 145px at 50% -25px, white 50%, transparent 51%);
-webkit-mask-position: 0% 0%, 0% 100%;
-webkit-mask-size: 100% 50%;
-webkit-mask-repeat: no-repeat;
}
<div></div>
答案 1 :(得分:1)
获得此布局的基本技巧是,我们将尝试创建一个具有一层纯色的叠加层,中间有透明圆圈,并将其放置在带有背景图像的元素上方。
这可以通过两种不同的方式实现:
使用径向渐变:
我们将使用css3 radial-gradient()
创建一个中心具有特定大小的透明circle
/ ellipse
的背景图片。使用径向渐变的缺点是中心圆形状不是很平滑。
body {
background: white;
}
.box {
background: url("https://i.imgur.com/waDgcnc.jpg") no-repeat;
background-size: cover;
position: relative;
height: 100px;
}
.overlay {
background: radial-gradient(95px 70px at 50% 0, transparent, transparent 40px, #fff 30px);
position: absolute;
overflow: hidden;
height: 30px;
bottom: 0;
right: 0;
left: 0;
}
&#13;
<div class="box">
<div class="overlay">
</div>
</div>
&#13;
使用伪元素:
我们可以使用具有大框阴影值的圆形形状的::before
或::after
伪元素创建此叠加层。中心circle
/ ellipse
创建时看起来比radial-gradient()
更好,更流畅。
body {
background: white;
}
.box {
background: url("https://i.imgur.com/waDgcnc.jpg") no-repeat;
background-size: cover;
position: relative;
height: 100px;
}
.overlay {
position: absolute;
overflow: hidden;
height: 30px;
bottom: 0;
right: 0;
left: 0;
}
.overlay:before {
box-shadow: 0 0 0 1000px #fff;
transform: translateX(-50%);
border-radius: 100%;
position: absolute;
height: 70px;
content: '';
width: 100px;
bottom: 0;
left: 50%;
}
&#13;
<div class="box">
<div class="overlay">
</div>
</div>
&#13;
注意:这些方法仅在具有背景属性的最近祖先应用了一些纯色时才有效。如果祖先将某些图像作为背景或线性/径向渐变,则此方法将不起作用。
有用的资源: