自定义形状与背景图像

时间:2017-02-05 06:04:58

标签: html css css3 background-image css-shapes

我想在我的导航栏菜单中间创建一个半圆形的水平矩形。除此之外,所有这些形状都必须有背景图像。

这样的事情:

sample

实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:10)

使用SVG: (推荐)

创建这样的形状的最佳工具是SVG而不是CSS。 SVG是可扩展的(对于响应式设计非常有用),它们允许我们更好地控制形状方面 - 例如圆形或椭圆的斜率/曲率,也可以将图像或渐变作为填充(背景),如下图所示。

使用SVG绘制形状非常容易。只需使用path元素以及移动(M),弧(A),行(L)和近路(z等命令)。绘制形状后,使用fillpattern元素将图像应用为imagexlink: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的背景图片。使用径向渐变的缺点是中心圆形状不是很平滑。

&#13;
&#13;
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;
&#13;
&#13;

使用伪元素:

我们可以使用具有大框阴影值的圆形形状的::before::after伪元素创建此叠加层。中心circle / ellipse创建时看起来比radial-gradient()更好,更流畅。

&#13;
&#13;
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;
&#13;
&#13;

  

注意:这些方法仅在具有背景属性的最近祖先应用了一些纯色时才有效。如果祖先将某些图像作为背景或线性/径向渐变,则此方法将不起作用。

有用的资源:

  1. 线性渐变:MDNQuackit
  2. 径向渐变:MDNQuackit