流体宽度 SVG 形状上的重复图案?

Repeating pattern on a fluid-width SVG shape?

我正在尝试在 HTML/CSS 中重新创建此布局(跨浏览器兼容回 IE9):

基本上,它是一条跨越视口宽度的对角线,将两个背景图案分开。它将有一个固定的高度,但它应该动态拉伸到其容器的整个宽度。

我想不出使用纯 CSS 来实现此目的的方法,所以我的下一个想法是使用 SVG。这对纯色来说并不难:

http://codepen.io/troywarr/pen/EPXVRV?editors=110

但是,我对如何将重复背景图案应用到 SVG 形状感到困惑。它需要在上下 <section> 秒内与背景图案对齐,并且背景填充不应随形状的尺寸缩放,否则会显得扭曲。

正在应用 CSS 中的一些背景图片,我越来越接近了:

http://codepen.io/troywarr/pen/OMgyoE?editors=110

我只需要 SVG 填充部分的深色背景图案。

使用更明显的图像作为测试,我可以将其拉伸到 <polyline>:

的尺寸

http://codepen.io/troywarr/pen/BjZoEq?editors=110

但是,有一种我不想要的伸展。我需要平铺我的图案,或者至少不扭曲它的原始尺寸(这样我可以在需要时使用它的大样本),即使形状本身具有流动宽度。我已经为 <pattern> 元素尝试了几种不同的属性值组合,但我还没有找到任何按预期工作的东西,即使遵循相关答案的一些指导也是如此:

有什么建议吗?我也很想听听有关非 SVG 方法的任何想法。谢谢!


更新:

抱歉,我刚刚发现我的 CodePen 示例中的背景图案不起作用。我已经用有效的图片网址更新了它们。

这是一种仅需 CSS 即可完成的方法。您可以使用 after pseudo-elements 来帮助您获得这些角度,并且只有一个 png 用于对角线(或者如果您想避开元素则旋转一个元素)和另一个用于重复模式。由于我没有你的图片,所以我很快就做了一些,但这或多或少应该是你想要的。

html { height:100%; }
body {
  padding:0;
  margin:0;
  height:100%;
  background:#333;
}

.demo {
  width:100%;
  height:auto;
  position:absolute;
}

body:after {
  position:absolute;
  content:'';
  top:0;
  bottom:0;
  right:0;
  left:0;
  pointer-events:none;
  background: transparent url(http://i.imgur.com/iUhGezx.png) repeat top left;
}

.demo .top {
  min-height:100px;
  background:#FFF;
  position:relative;
}

.demo .bottom { min-height:60px; }

.demo .top:after {
  position:absolute;
  content:'';
  top:100%;
  left:0;
  right:0;
  height:100px;
  background: transparent url(http://i.imgur.com/iEubBd5.png) repeat top left;  
  background-size: 100% 100px;
}
<div class="demo">
   <div class="top"></div>
   <div class="bottom"></div>
</div>

考虑到您需要:

  • 相对于视口的倾斜宽度
  • 形状的固定高度

有一个简单的 CSS 方法可以用于边框和 viewport units :

body,html{padding:0;margin:0;}
div{
  border-bottom:50px solid rgba(0,0,0,.8);
  border-top: 50px solid transparent;
  background-image:url('http://i.imgur.com/iUhGezx.png');
}
div:before{
  content:'';
  display:block;
  border-right:100vw solid rgba(0,0,0,.8);
  border-top:50px solid transparent;
}
<div></div>

该模式与 background-image 属性 重复。倾斜是用伪元素上的边框制作的。
父级 div 的边框只是为了让顶部和底部 space 围绕倾斜。

视口相关单位 (vw) 受 IE9 及以上版本支持(有关详细信息,请参阅 canIuse)。


更新:

如果您需要为两个区域设置单独的 background-image,有 2 种可能的 CSS 方法:

转换: 受 IE9 支持,并支持 vendor prefixes。倾斜始终具有相同的角度。

body,
html {
  padding: 0;
  margin: 0;
  overflow:hideden;
}
div{
  width:100%;height:150px;  
  position:absolute;
}
.top {
  padding-top:50px;
  background: #fff url('http://i.imgur.com/dzFT6wB.png');
}
.bot {
  transform-origin:100% 0;
  transform:rotate(-5deg);
  overflow:hidden;
  top:50px; right:0;
  width:110%;
}
.bot:after{
  content:'';
  position:absolute;
  right:0;top:0;
  width:100%;height:100%;
  transform-origin:inherit;
  transform:rotate(5deg) translatez(0px);
  background: #262729 url('http://i.imgur.com/LxTJ685.png');
}
<div class="top"></div>
<div class="bot"></div>

配合clip-path property: although it has low browser support,可以更好的控制倾斜角度:

body,html{padding:0;margin:0;}
div{
  position:relative;
  height:150px;
}
div:before, div:after{
  content:'';
  width:100%; height:100%;
  position:absolute;
}
div:before{
  background: url('http://i.imgur.com/dzFT6wB.png');
}
div:after{
  -webkit-clip-path:polygon(0% 60%, 100% 40%, 100% 100%, 0% 100%);
          clip-path:polygon(0% 60%, 100% 40%, 100% 100%, 0% 100%);
  background:#262729 url('http://i.imgur.com/LxTJ685.png');
}
<div></div>

SVG 目前无法做到这一点。如果您使用 preserveAspectRatio="none" 拉伸 SVG,那么 SVG 的全部内容都会受到影响。某些内容无法选择退出拉伸转换。

将来,SVG2 中可能会有这样的方法,但当前版本的 SVG 还没有。

更新

如果您可以忍受它不能在 IE 中运行,您可以使用掩码或 clip-path 来实现您想要的效果。下面是使用 clip-path.

的示例

body {
  margin: 0;
}

section {
  height: 50px;
}

main {
  background-image: url('http://mass-relevance-all-access.massrel.io/template-static-2e84fe3d1c7dc87710f58b990263ad6c29dacafc/img/bg-pattern-light.png');
}

.dark {
  background: #262729 url('http://mass-relevance-all-access.massrel.io/template-static-2e84fe3d1c7dc87710f58b990263ad6c29dacafc/img/bg-pattern-dark.png');
}

.diagonal {
  background: url(http://www.boogdesign.com/examples/svg/daisy-grass-repeating-background.jpg);
  -webkit-clip-path: url(#diagonalclip);
  clip-path: url(#diagonalclip);
}
<svg width="0" height="0">
  <defs>
    <clipPath id="diagonalclip" clipPathUnits="objectBoundingBox">
      <polyline points="0,1 1,0 1,1 0,1"/>
    </clipPath>
  </defs>
</svg>
<main>
  <section class="light"></section>
  <section class="diagonal"></section>
  <section class="dark"></section>
</main>