将 SVG 与媒体查询结合使用

2021-09-13 11:31:25 浏览数 (1)

在 HTML 文档中,我们可以根据视口的条件显示、隐藏或重新排列页面的某些部分。例如,如果浏览器窗口的宽度为 480 像素,我们可能会将导航从水平导航移动到垂直可折叠列表。将 SVG 与媒体查询一起使用时,我们可以做类似的事情。

除了将 CSS 与 HTML 结合使用外,我们还可以将 CSS 与 SVG 或Scalable Vector Graphics 结合使用。SVG 是一种用于描述平面二维图像的标记格式。因为它是一种标记语言,所以它有一个文档对象模型,并且可以与 CSS 一起使用。

通过将 CSS 与 SVG 结合使用,我们可以根据用户交互更改 SVG 的外观。或者我们可以在多个地方使用同一个 SVG 文档,并根据视口的宽度显示或隐藏它的一部分。

所有主要的浏览器引擎都支持SVG 1.1规范,而且他们已经这样做了多年。另一方面,对SVG 2特性的支持仍在进行中。在撰写本文时,我们将在此处讨论的某些内容的浏览器支持有限。当您阅读本文时,这种情况可能已经改变。密切关注 Chromium 元问题 —实施 SVG2 功能— 以跟踪基于 Chromium 的浏览器的开发进度。观看支持 SVG 2 功能元问题以跟进 Firefox 的实现工作,以及 WebKit 的为 Safari实现 SVG 2元问题。问题跟踪器导航可能令人不快,但就目前而言,它们是跟踪 SVG 2 支持的最佳方式。

然而,在我们进一步讨论之前,让我们先谈谈什么是 SVG 以及为什么要使用它。

矢量图像与光栅图像

目前在网络上使用的大多数图像都是光栅图像,也称为位图图像。光栅图像由固定网格上的像素组成,每英寸具有一定数量的像素。JPEG、WebP、GIF 和 PNG 都是光栅图像格式的示例。

光栅图像与分辨率有关。144 PPI(每英寸像素)PNG 图像在具有 144 PPI 显示分辨率的设备上看起来很棒。然而,在更高分辨率的 400 PPI 显示器上查看时,相同的图像可能看起来很模糊。光栅图像也有固定尺寸,在原始尺寸下看起来最好。将 150 x 150 像素的图像缩放到 300 x 300 像素会使其失真。

矢量图像格式不使用网格上的像素,而是描述构成图像的原始形状(圆形、矩形、线条或路径)以及它们在文档坐标系中的位置。因此,矢量图像与分辨率无关,无论显示分辨率或显示尺寸如何,都可以保持其质量。

分辨率独立是SVG的最大优势。我们可以在不损失质量的情况下放大或缩小图像。相同的图像在高 PPI 和低 PPI 设备上看起来都很棒。也就是说,SVG 不太适合照片所需的颜色数据量。最适合绘图和形状。用它代替 PNG 和 GIF 图像,并作为图标字体更灵活的替代品。

SVG 的另一个优点是它旨在与其他 Web 语言一起使用。我们可以使用 JavaScript 创建、修改和操作 SVG 图像。或者,正如我们将在下面看到的,我们可以使用 CSS 为 SVG 设置样式和动画。

将 CSS 与 SVG 文档相关联

将 CSS 与 SVG 结合使用与将其与 HTML 结合使用非常相似。我们可以使用styleSVG 元素的属性来应用 CSS,使用该元素在文档中对 CSS 进行分组<style>,或者链接到外部样式表。每种方法的优缺点与在 HTML 中使用 CSS 时相同。

使用style属性

这是一个简单的 SVG 文档,其中的代码创建了一个黑色圆圈:

代码语言:javascript复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" 
➥enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>

下图显示了该代码在浏览器中的呈现方式。

让我们使用 CSS 和style属性为我们的圆圈填充粉红色:

代码语言:javascript复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" 
➥enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" style="fill: #f9f" />
</svg>

其效果如下所示。

这是在 HTML 中使用 CSS 和在 SVG 中使用 CSS 的一个区别:属性名称。我们在 HTML 文档中使用的许多 CSS 属性与 SVG 不兼容,反之亦然。我们将在本章后面回到这一点。

当然,使用style属性并不是使用 CSS 的最佳方式。这样做会限制在多个元素或文档中重用这些样式的能力。相反,我们应该使用内联或链接的 CSS。

在 SVG 文档中嵌入 CSS

style我们可以使用<style>元素来代替使用属性:

代码语言:javascript复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
    <style type="text/css">
        circle {
            fill: #0c0;
        }
    </style>
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>

在 SVG 文档中嵌入 CSS 让我们可以为同一文档中的多个元素重用这些样式,但它会阻止 CSS 在多个文档之间共享。对于徽标和图标来说这很好。但是,如果您要创建图表样式库之类的内容,则最好使用外部 CSS 文件。

使用标准文本编辑器,您还可以向使用 Sketch、Inkscape 或 Illustrator 等软件创建的 SVG 图像添加 CSS。这样做不会影响您使用绘图应用程序编辑图像的能力,但如果您使用图像软件编辑文件,应用程序可能会重写或删除您的 CSS。

从 SVG 链接到外部 CSS 文件

与 HTML 一样,链接到外部 CSS 文件可以在多个 SVG 文档之间共享样式。要链接外部 CSS 文件,请添加<? xml-stylesheet ?>到 SVG 文件的开头:

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
    <circle cx="101.3" cy="96.8" r="79.6" />
</svg>
使用<link>元素

或者,使用 HTML<link>元素。如果确实使用此方法,则需要包含xmlns命名空间属性,如下所示:

代码语言:javascript复制
<link href="style.css" type="text/css" rel="stylesheet"
    ➥ xmlns="http://www.w3.org/1999/xhtml" />

注意:一些较旧的浏览器需要将<link>元素用<defs><g>标签括起来。

<link>元素不是 SVG 元素。它属于 HTML 和 XHTML。XHTML 是根据 XML 标记规则解析的 HTML 变体。根据 XML 的规则,我们可以从其他 XML 方言(例如 XHTML)中借用元素及其行为。但是,为此,我们需要使用xmlns属性告诉浏览器该元素属于哪个命名空间。

使用 @import

我们还可以使用@importinside<style></style>标签链接到外部样式表:

代码语言:javascript复制
<style type="text/css">
@import('style.css');
</style>

该方法的功能与该<link>方法类似。

SVG 和<img>元素:限制

从 SVG 文件链接到外部资源,包括 CSS 文件,不适用于该<img>元素。这是<img>嵌入到浏览器中的元素的安全限制。

如果您想对 SVG 图像使用链接 CSS,则需要执行以下两项操作之一:

  • 使用<style>SVG 文档中的元素将 CSS 内联放置
  • 使用<iframe>or<object>元素(见下面的注释)

注意:Craig Buckler 的教程“如何将可缩放矢量图形添加到您的网页”讨论了使用<iframe><object>详细信息。

一般来说,你应该使用<iframe>over <object>。但是,<object>元素可以是元素的子<a>元素,而<iframe>不能。使用<iframe><object>也使 SVG 文档树可用于父文档的文档树。这意味着我们可以使用 JavaScript 与之交互(例如,与document.querySelector('iframe').contentDocument)。

内联 SVG 和外部资源

将 SVG 添加到 HTML 时,浏览器不会加载 SVG 文档引用的外部资源。但是,我们可以从<head>HTML 文档的链接到 SVG 文档的 CSS :

代码语言:javascript复制
<head>
    ⋮
    <link href="svg.css" type="text/css" rel="stylesheet" />
</head>

HTML 文档中的 SVG 元素也成为 HTML 文档树的一部分。如果您使用的是内联 SVG,那么将与 HTML 相关的 CSS 和与 SVG 相关的 CSS 组合在同一个样式表中是非常好的。

SVG 和 HTML 之间的差异

虽然 SVG 和 HTML 都是标记语言,但它们之间有两个显着差异会影响它们如何使用 CSS:

  • SVG 不遵循 CSS 盒模型
  • SVG 缺乏定位方案

SVG 不遵循 CSS 盒模型

当与 HTML 一起使用时,CSS 布局遵循 CSS 盒模型的规则。另一方面,SVG 使用坐标进行布局。它遵循最好理解为“形状模型”的内容。

SVG 形状不限于矩形框。因此,大多数与盒模型相关的属性不适用于 SVG 元素。例如,您不能更改SVG 元素的paddingmargin。你也可以使用box-sizingbox-shadowoutline,或border-*性质。网格布局、浮动和 Flexbox 也不起作用。

但是,您可以使用 CSS 来设置或更改一系列 SVG 属性和属性值。SVG 2规范中概述了完整列表,尽管大多数浏览器的支持尚不完整。某些 CSS 属性(例如filter)可与 SVG 或 HTML 一起使用。在本章中,我们将在特定技术的背景下讨论其中的一些。

SVG 缺乏定位方案

当 CSS 与 HTML 一起使用时,元素框可以:

  • 存在于正常流程中
  • float属性一起从正常流程中删除
  • position属性一起从正常流程中删除

CSS 规范将这些称为定位方案。SVG 中不存在定位方案。该position属性对 SVG 元素没有影响。top,leftbottom等依赖于被定位元素的属性也不行。您也不能在 SVG 文档中浮动元素。

相反,SVG 使用坐标系来放置元素。<circle>例如,要创建一个,您需要使用cxcy属性设置其中心点坐标,并使用该r属性设置半径长度。多边形由一系列点坐标和在它们之间绘制的线段组成。换句话说,您可以定义将元素绘制到 SVG 画布的位置,但您不能在 CSS 词的意义上“定位”它们。

与定位方案相关,SVG 也缺乏z-index上下文的概念和堆叠。

注意:SVG 2规范确实定义z-index了 SVG 文档中的行为和堆叠上下文,但大多数浏览器尚不支持它。

SVG 元素是根据它们的源顺序堆叠的。出现在文档后面的那些位于堆栈的顶部。如果要更改 SVG 元素的堆叠顺序,则需要在源中移动它们或使用 JavaScript 在 DOM 树中对它们重新排序。

事实上,大多数 CSS 2.1 属性不适用于 SVG 文档。例外情况包括动画和变换、displayoverflowvisibilityfilter和一些字体和文本相关的属性。相反,您必须对SVG 文档使用特定于SVG 的样式属性。大多数这些属性也可以表示为 SVG 元素属性。

样式化 SVG 元素

这是一个如何使用 CSS 设置 SVG 元素样式的简单示例。首先是我们的 SVG 文档,它是一个独立的文件:

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="styles.css" type="text/css" ?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink=
➥"http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 497
➥ 184" enable-background="new 0 0 497 184" xml:space="preserve">
    <polygon id="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2,
➥106.9,119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5 55.8,
➥66.6 "/>
    <circle id="circle" cx="245" cy="88.9" r="67.5"/>
</svg>

此标记创建如下所示的图像。

尽管我们不能对 SVG 文档使用大多数 CSS 属性,但我们可以使用 CSS 来更改元素的颜色。让我们把星星变成黄色:

代码语言:javascript复制
#star {
    fill: hsl( 44, 100%, 50% );
}

您会经常看到fill与 SVG 标签一起使用的属性——例如<circle fill="rgb( 255, 185, 0 )" cx="3" cy="10" r="100">——但它也是一个可以与 CSS 一起使用的属性。

我们还可以使用 CSS 来调整元素的stroke,即 SVG 形状的轮廓。即使未stroke设置任何属性,也存在形状的笔触。让我们给我们的圆一个十像素宽的深蓝色虚线边框。我们还将其fill属性设置为cornflowerblue

代码语言:javascript复制
circle {
    fill: cornflowerblue;
    stroke: darkblue;
    stroke-width: 10;
    stroke-dasharray: 10, 15;
    stroke-linecap: round;
}

这给了我们下面的结果。

使用 SVG 属性作为 CSS 属性

我们也可以使用CSS来设置一些形状元件的坐标值:<rect><circle>,和<ellipse>。通常,我们会为这些元素使用 SVG 属性:

代码语言:javascript复制
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <rect x="20" y="200" width="300" height="300" fill="#f60" />
</svg>

但是,SVG 2 将一些 SVG 属性重新定义为几何属性。这意味着我们可以使用 CSS 来设置它们的值:

代码语言:javascript复制
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">
      rect {
          x: 20px;
          y: 50px;
          width:  300px;
          height: 300px;
          fill: #f60;
      }
    </style>
    <rect />
</svg>

坐标属性(xand y)、中心坐标属性(cxand cy)和半径属性(rx, ry, and r)可以使用 CSS 设置。所以可以widthheight。单位对于 SVG 属性是可选的。另一方面,CSS 值需要单位。长度和百分比对于此处提到的属性都有效,但请注意,长度在 SVG 文档中的作用略有不同。请记住,SVG 中的 S 代表可扩展。SVG 元素的计算大小还取决于:

  • 根 SVG 元素的计算widthheight
  • 根元素的viewBox属性值
  • 应用于元素或其祖先的任何缩放变换

换句话说,我们的角<rect>元素是(20, 50)(20, 320)(350, 320),和(20, 350)SVG的坐标系统内。但是,实际尺寸可能更大或更小,具体取决于上述因素。

并非每个 SVG 属性都可以通过 CSS 获得——至少不是在每个浏览器中。比如Chrome和Edge支持使用CSSpath()函数设置路径数据,或者d属性:

代码语言:javascript复制
path {
    d: path("M 454.45223,559.21474 -304.96705,163.45948 417.4767,-296.33928 Z");
}

在撰写本文时,它们是唯一可以执行此操作的浏览器。在Firefox和 WebKit 中添加支持的工作尚未开始。

对于其他形状元素,SVG 2 规范完全不一致。迄今为止,您必须使用元素的属性来设置的属性<line><polyline><polygon>元素。

也就是说,我们不限于使用类型(或元素)选择器来设置属性。例如,我们可以使用类选择器定义小圆、中圆和大圆:

代码语言:javascript复制
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">

    .small {
        cx: 20px;
        cy: 20px;
        r:  20px;
        fill:  #0c0;
      }

      .medium {
        cx: 80px;
        cy: 80px;
        r:  60px;
        fill:  #fc0;
      }

      .large {
        cx: 220px;
        cy: 220px;
        r:  120px;
        fill: #00f;
      }

    </style>

    <circle class="small" />
    <circle class="medium" />
    <circle class="large" />
</svg>

不管选择器是什么,使用 CSS 语法来指定属性也可以很容易地为它们设置动画。我们将在下一节中了解如何执行此操作。

动画和转换 SVG CSS 属性

当我们将过渡和动画添加到混合中时,将 CSS 与 SVG 结合使用会变得更加有趣。该过程就像使用 CSS 为 HTML 元素设置动画一样,但具有 SVG 特定的属性。让我们使用以下 SVG 文档创建一个闪烁的星星效果:

代码语言:javascript复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px"
➥ y="0px" viewBox="0 0 497 184" xml:space="preserve">
    <defs>
        <link href="twinkle.css" type="text/css" rel="stylesheet"
➥ xmlns="http://www.w3.org/1999/xhtml"/>
    </defs>
    <polygon class="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2
➥,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5
➥ 55.8,66.6 "/>
    <polygon class="star twinkle" points="77,23.7 98.2,66.6 145.5,
➥66.5 111.2,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9
➥ 8.5,67.5 55.8,66.6 "/>
</svg>

我们的文档包含两个星形多边形元素,每个元素的类名都是star。为了创建闪烁效果,我们将动画第一个。这是我们的 CSS:

代码语言:javascript复制
@keyframes twinkle {
    from {
        fill-opacity: .4;
    }
    to {
        fill-opacity: 0;
        transform: scale( 2 );
    }
}
.star {
    fill: rgb( 255,195,0 );
    transform-origin: 50% 50%;
}
.twinkle {
    animation: twinkle 1.5s infinite forwards ease-in;
}

这里我们使用了 SVG 特定的属性fill-opacity。与 CSS 一样,如果我们可以插入 SVG 样式属性的值,我们就可以对其进行动画或过渡。您可以在下图中看到动画的两个不同点。

让我们再看一个例子。这次我们将通过转换stroke-dasharray属性来创建绘图效果。这是我们的 SVG 文档:

代码语言:javascript复制
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
        viewBox="0 0 200 200" enable-background="new 0 0 200 200">
    <circle fill="transparent" stroke-width="16" cx="101.3"
➥ cy="96.8" r="79.6"/>
</svg>

stroke-dasharray属性接受以逗号分隔的长度或百分比值列表,这些值创建虚线模式。奇数值确定划线长度。偶数值确定间隙长度。甲stroke-dasharray的值5, 10的装置,该行程将5px长带的间隙10px每一划线之间。5, 5, 10交替5px10px短划线长度的值,5px中间有间隙。

我们可以stroke-dasharray通过从零虚线长度和大间隙开始,并以大虚线长度和零虚线间隙结束来创建绘图效果。然后我们将在两者之间过渡。这是我们的 CSS 的样子:

代码语言:javascript复制
circle {
    transition: stroke-dasharray 1s ease-in;
    fill: transparent;
    stroke-dasharray: 0, 500;
}
.animate {
    stroke-dasharray: 500, 0;
}

在过渡开始时,我们的笔画是不可见的,因为虚线长度是0,我们的间隙是500。但是当我们将animate类添加到我们的圆圈中时,我们将划线长度移动到500并消除间隙。效果有点像用圆规画一个圆。为什么是500?这是创造这种特殊效果的最小值。

动画路径未来

还记得上一节中通过 CSS 定义路径的示例吗?有一天,我们或许可以在每个浏览器中使用 CSS 为路径设置动画:

代码语言:javascript复制
path {
    d: path("M357.5 451L506.889 192.25H208.111L357.5 451Z");
    transition: d 1s ease-in-out;
}
.straighten {
    d: path("M357.5 8871L406 -10113.75H208.111L357.5 351Z");
}

但是,迄今为止,只有基于 Chromium 的浏览器(例如 Google Chrome 和 Microsoft Edge)支持以这种方式动画化路径定义。要使其在其他浏览器中工作,请使用 JavaScript 库,例如GreenSock及其 MorphSVGPlugin。除了跨浏览器兼容性之外,GreenSock 和 MorphSVGPlugin 还可以更轻松地在两个形状之间进行变形,而不管每个形状中的点数如何。

将 SVG 与媒体查询结合使用

对于 HTML 文档,我们可能会根据视口的条件显示、隐藏或重新排列页面的某些部分。例如,如果浏览器窗口的宽度为 480 像素,我们可能会将导航从水平导航移动到垂直可折叠列表。我们可以对媒体查询和 SVG 文档做类似的事情。考虑一个徽标,例如下图中虚构的 Hexagon Web Design & Development 的徽标。

如果没有媒体查询,这个 SVG 标志会简单地拉伸或收缩以适应视口或其容器。但是通过媒体查询,我们可以做更聪明的事情。

让我们区分 HTML 文档视口和 SVG 文档视口。当 SVG 内联时,HTML 视口和 SVG 视口是一回事。SVG 文档的行为类似于任何其他 HTML 元素。另一方面,当一个 SVG 文档被链接时——就像<iframe>,<object><img>元素一样——我们正在处理 SVG 文档视口。

媒体查询在这两种情况下都适用,但是当 SVG 文档被链接时,它的视口独立于它的 HTML 文档。在这种情况下,浏览器窗口的大小不会决定 SVG 视口的大小。取而代之的是,视口尺寸由尺寸确定<object><iframe><img>元件。以下面的(删节的)SVG文档为例:

代码语言:javascript复制
<svg version="1.1" id="HexagonLogo" xmlns="http://www.w3.org/2000/
➥svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="0 0 555 174" xml:space="preserve">
    <defs>
        <style type="text/css">
        /* CSS goes here */
        </style>
    </defs>
    <g id="hex">
        <polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11
➥ 145.5,11 190.7,86.5 145.5,162  "/>
        <path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.
➥4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.
➥3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/>
    </g>

    <g id="word-mark">
        <g id="hexagon-word">
            ...
        </g>
        <g id="web-design-and-dev">
            ...
        </g>
    </g>
</svg>

注意:代码存档中提供了此技术的完整演示,包括此 SVG 文档的完整源代码

在较小的视口中,让我们仅在六边形符号中显示 H:

代码语言:javascript复制
@media (max-width: 320px) {
    [id=word-mark] {
        display: none;
    }
}

现在,只要我们的 SVG 的容器小于或等于20em,就只会看到我们徽标的符号部分。

要从 HTML 文档触发此视图,请设置 SVG 容器的宽度:

代码语言:javascript复制
<iframe src="hexlogo.svg" style="width: 320px; border:0"></iframe>

正如您在查看上图时可能已经注意到的那样,我们的 SVG 图像保留了它的内在尺寸,即使它的一部分被隐藏了。不幸的是,这是 SVG 的一个限制。要修复它,我们需要更改viewBoxSVG 文档的属性,但仅当视口低于特定大小时。这是一个很好的用例matchMedia(将在第 10 章“有条件地应用 CSS ”中讨论)。

viewBox顾名思义,该属性决定了 SVG 元素的可视区域。通过调整它,我们可以确定 SVG 图像的哪一部分填充了视口。以下是使用matchMedia媒体查询更新viewBox属性的示例:

代码语言:javascript复制
<script type="text/javascript">
const svg = document.querySelector( 'svg' );

/* Store the original value in a variable */
const originalViewBox = svg.getAttribute( 'viewBox' );

/* Define our media query and media query object */
const mq = matchMedia( '( max-width: 320px )' );

/* Define the handler */
const updateViewBox = () => {
    if (mq.matches) {
        /* Change the viewBox dimensions to show the hexagon */
        svg.setAttribute( 'viewBox', '0 0 200 174' );
    } else {
        svg.setAttribute( 'viewBox', originalViewBox );
    }
}

svg.addEventListener( 'SVGLoad', updateViewBox );

/* Fire if the media condition changes */
mq.addEventListener( 'change', updateViewBox );
</script>

现在,只要 SVG 容器小于等于 320 像素, 的值viewBox就会是"0 0 200 174"。当超过 320 像素时,viewBox恢复到其初始值。

由于此技术使用onload事件属性或SVGLoad事件,因此将我们的 CSS 和 JavaScript 嵌入到 SVG 文件中是个好主意。当 CSS 是外部的时,SVGLoad事件可能会在其关联的 CSS 完成加载之前触发。

使用媒体查询 background-size

SVG 文档和媒体查询不限于前景图像。我们还可以使用 CSSbackground-size属性调整 SVG 视口的大小。

我们将从这个 SVG 文档开始:

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥ xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="-20 -20 250 250" xml:space="preserve">
    <style type="text/css">
        circle {
            stroke: #000;
            stroke-width: 30;
            fill: #009688;
        }
        @media ( width: 100px ) {
            circle {
                fill: #673ab7;
            }
        }
        @media ( width: 300px ) {
            circle {
                fill: #ffc107;
            }
        }
    </style>
    </defs>
    <circle cx="100" cy="100" r="100" />
    <circle cx="100" cy="100" r="50" />
</svg>

这是一个简单的案例。我们的<circle>元素fill在特定视口宽度处获得新颜色。当视口为 20 像素宽时,该fill值为蓝绿色。当它是 300 像素宽时,它是黄色的。

为了完成这项工作,我们必须使用我们的 SVG 图像作为背景图像并设置选择器的background-size属性。在这种情况下,我们将使用我们的图像作为<body>元素和<li>元素的背景:

代码语言:javascript复制
body, li  {
    background: url(circles.svg);
}
body  {
    background-color: #9c27b0;
    background-size: 300px auto;
}
li {
    background-position: left center;
    background-repeat: no-repeat;
    background-size: 1em auto;
    padding-left: 40px;
    font-size: 24px;
    margin: 1rem 0;
}

结果如下图。

结论

将 SVG 与 CSS 结合使用为我们提供了更多灵活和自适应文档的可能性。您现在应该知道如何:

  • 使用 CSS 设置 SVG 元素的样式
  • 动画 SVG 属性
  • 使用 CSS 媒体查询和matchMediaAPI 来显示和隐藏部分 SVG 文档
svg

0 人点赞