前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将 SVG 与媒体查询结合使用

将 SVG 与媒体查询结合使用

作者头像
玖柒的小窝
修改2021-09-13 11:31:25
6.2K0
修改2021-09-13 11:31:25
举报
文章被收录于专栏:各类技术文章~各类技术文章~

在 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>

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

SVG 中的圆
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>

其效果如下所示。

使用 style 属性添加填充颜色
使用 style 属性添加填充颜色

这是在 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 图像
一个简单的圆形和星形 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 图像
一个简单的圆形和星形 SVG 图像

使用 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,就只会看到我们徽标的符号部分。

根据 SVG 视口大小显示/隐藏元素
根据 SVG 视口大小显示/隐藏元素

要从 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恢复到其初始值。

根据视口的宽度调整 viewBox 属性
根据视口的宽度调整 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;
}

结果如下图。

使用 CSS background-size 属性操作 SVG 视口
使用 CSS background-size 属性操作 SVG 视口

结论

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

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

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 矢量图像与光栅图像
  • 将 CSS 与 SVG 文档相关联
    • 使用style属性
      • 在 SVG 文档中嵌入 CSS
        • 从 SVG 链接到外部 CSS 文件
          • 使用<link>元素
          • 使用 @import
          • SVG 和<img>元素:限制
          • 内联 SVG 和外部资源
      • SVG 和 HTML 之间的差异
        • SVG 不遵循 CSS 盒模型
          • SVG 缺乏定位方案
          • 样式化 SVG 元素
            • 使用 SVG 属性作为 CSS 属性
            • 动画和转换 SVG CSS 属性
              • 动画路径未来
              • 将 SVG 与媒体查询结合使用
                • 使用媒体查询 background-size
                • 结论
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档