在 HTML 内容中应用 SVG 效果

现代浏览器支持在 CSS 样式中使用 SVG 来对HTML内容应用图像效果。

你可以在同一文件中使用SVG样式,也可以通过外部样式表引入。有三个属性可以使用: mask, clip-path, 和 filter

注意: 在外部文件引入的SVG必须与原始文件 同源

使用内嵌SVG

要想在CSS样式中应用SVG效果,首先需要创建一个引用SVG的CSS样式。

<style>p { mask: url(#my-mask); }</style>

在上面的例子中, 所有段落会被ID 为my-mask的SVG <mask>遮罩.

例子: Masking

例如,你可以在你的HTML文档中用SVG和CSS代码对HTML内容作渐变mask效果。

<svg height="0">
  <mask id="mask-1">
    <linearGradient id="gradient-1" y2="1">
      <stop stop-color="white" offset="0"/>
      <stop stop-opacity="0" offset="1"/>
    </linearGradient>
    <circle cx="0.25" cy="0.25" r="0.25" id="circle" fill="white"/>
    <rect x="0.5" y="0.2" width="300" height="100" fill="url(#gradient-1)"/>
  </mask>
</svg>
.target {
  mask: url(#mask-1);
}
p {
  width: 300px;
  border: 1px solid #000;
  display: inline-block;
}

Note that in the CSS, the mask is specified using a URL to the ID #mask-1, which is the ID of the SVG mask specified below it. Everything else specifies details about the gradient mask itself.

Applying the SVG effect to (X)HTML is accomplished by assigning the target class defined above to an element, like this:

<p class="target" style="background:lime;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua. Ut enim ad minim veniam.
</p>
<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing
    <b class="target">elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua.</b>
    Ut enim ad minim veniam.
</p>

The above example would be rendered with the mask applied to it.

例子: Clipping

此示例演示如何使用SVG剪辑HTML内容。请注意,即使链接的可点击区域也被剪切。

<p class="target" style="background:lime;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua. Ut enim ad minim veniam.
</p>
<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing
    <b class="target">elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua.</b>
    Ut enim ad minim veniam.
</p>
<button onclick="toggleRadius()">Toggle radius</button>
<svg height="0">
  <clipPath id="clipping-path-1" clipPathUnits="objectBoundingBox">
    <circle cx="0.25" cy="0.25" r="0.25" id="circle"/>
    <rect x="0.5" y="0.2" width="0.5" height="0.8"/>
  </clipPath>
</svg>
.target {
  clip-path: url(#clipping-path-1);
}
p {
  width: 300px;
  border: 1px solid #000;
  display: inline-block;
}

This establishes a clipping area made of a circle and rectangle, assigns it the ID #clipping-path-1, then references it in the CSS. The clip path can be assigned to any element with the target class.

You can make changes to the SVG in real time and see them immediately affect the rendering of the HTML. For example, you can resize the circle in the clip path established above:

function toggleRadius() {
  var circle = document.getElementById("circle");
  circle.r.baseVal.value = 0.40 - circle.r.baseVal.value;
}

例子: Filtering

This demonstrates applying a filter to HTML content using SVG. It establishes several filters, which are applied with CSS to three elements in both the normal and mouse hover states.

<p class="target" style="background: lime;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua. Ut enim ad minim veniam.
</p>
<pre class="target">lorem</pre>
<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing
    <b class="target">elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua.</b>
    Ut enim ad minim veniam.
</p>

Any SVG filter can be applied this way. For example, to apply a blur effect, you might use:

<svg height="0">
  <filter id="f1">
    <feGaussianBlur stdDeviation="3"/>
  </filter>
</svg>

You could also apply a color matrix:

<svg height="0">
  <filter id="f2">
    <feColorMatrix values="0.3333 0.3333 0.3333 0 0
                           0.3333 0.3333 0.3333 0 0
                           0.3333 0.3333 0.3333 0 0
                           0      0      0      1 0"/>
  </filter>
</svg>

And some more filters:

<svg height="0">
  <filter id="f3">
    <feConvolveMatrix filterRes="100 100" style="color-interpolation-filters:sRGB"
      order="3" kernelMatrix="0 -1 0   -1 4 -1   0 -1 0" preserveAlpha="true"/>
  </filter>
  <filter id="f4">
    <feSpecularLighting surfaceScale="5" specularConstant="1"
                        specularExponent="10" lighting-color="white">
      <fePointLight x="-5000" y="-10000" z="20000"/>
    </feSpecularLighting>
  </filter>
  <filter id="f5">
    <feColorMatrix values="1 0 0 0 0
                           0 1 0 0 0
                           0 0 1 0 0
                           0 1 0 0 0" style="color-interpolation-filters:sRGB"/>
  </filter>
</svg>

The five filters are applied using the following CSS:

p.target { filter:url(#f3); }
p.target:hover { filter:url(#f5); }
b.target { filter:url(#f1); }
b.target:hover { filter:url(#f4); }
pre.target { filter:url(#f2); }
pre.target:hover { filter:url(#f3); }

View this example live

例子: Blurred Text

In order to blur text, Webkit based browsers have a (prefixed) CSS filter called blur (see also CSS filter). You can achieve the same effect using SVG filters.

<p class="blur">Time to clean my glasses</p>
<svg height="0">
  <defs>
    <filter id="wherearemyglasses" x="0" y="0">
    <feGaussianBlur in="SourceGraphic" stdDeviation="1"/>
    </filter>
  </defs>
</svg>

You can apply the SVG and the CSS filter in the same class:

.blur { filter: url(#wherearemyglasses); }

Blurring is computation heavy, so ensure to use it sparingly, especially in elements that get scrolled or animated.

使用外部引用

用来clipping,masking,filtering的SVG可以从其他外部源载入,只要外部源是与要使用SVG的该HTML文档同源的。

例如,CSS规则在一个名为default.css的文件中,如下这样:

.target { clip-path: url(resources.svg#c1); }

这个SVG就可以从一个名为resources.svg的文件中导入,clip路径为ID c1。

参见

文档标签和贡献者