o'Reill的SVG精髓(第二版)学习笔记——第二章

时间:2022-12-28 15:13:42

在网页中使用SVG

将SVG作为图像:

SVG是一种图像格式,因此可以使用与其他图像类型相同的方式包含在HTML页面中,具体可以采用两种方法:将图像包含在HTML标记的<img>元素内(当图像是页面的基本组成部分时,推荐这种方式);或者将图像作为另一个元素的CSS样式属性插入(放图像主要用来装饰时推荐这种方式)。

四种方式在web页面中插入SVG:①将SVG作为图像②将SVG作为CSS背景③将SVG作为对象④内联SVG

2.1.1在<img>元素内包含SVG

<img src="cat.svg" title="cat image" alt="Stick Figure of a cat"/> 

注:会有一些老式的浏览器不知道如何渲染svg文件,会显示一个破碎的文件图标(或者什么都不显示)。还有一些浏览器可能需要你确认你的web服务器以.svg结尾的文件声明了正确的媒体类型头(image/svg+xml)。

图像的高度和宽度可以使用属性或者CSS属性(优先考虑)设置。其他CSS属性控制web页面内图像的位置。如果不指定<img>元素的尺寸,就会使用图像文件固有的尺寸。如果只指定高度(宽度),宽度(高度)就会按比例缩放,以使高宽比(宽高比)与图像文件固有的尺寸匹配。

对于SVG来说,如果文件中的根元素<svg>带有明确的height和width属性,则它们会被用作文件的固有尺寸。如果只指定heifht或者width而不是两个都指定,并且<svg>带有viewBox属性,那么将用viewBox计算宽高比,图像也会被缩放以匹配指定的尺寸。如果<svg>带有viewBox属性而没有尺寸,则viewBox的height和width将被视为像素长度。

如果<img>元素和svg根元素都没有任何有关图像尺寸的信息,浏览器应该为嵌入内容应用默认HTML尺寸,通常是150像素高、300像素宽,但是最好不要依赖默认尺寸。

2.2在CSS中包含SVG

默认情况下,背景图像会按照固有尺寸进行绘制,并且会在垂直和水平方向上重复,以填满该元素。如果没有固定尺寸,SVG会被缩放为元素高度和宽度的100%。

div.background-cat {
background-image:url("cat.svg");
background-size:100% 100%;
}

除了用作背景图像,在CSS中SVG文件还能用作list-image(用于创建装饰性项目列表)或者border-image(用于创建花哨的边框)

注:当多个小图标和标识使用栅格图像的时候,通常会将所有图像放在一个图像文件的网格内,然后使用background-size和background-position为每个元素设置对应的图像。这样浏览器只需要下载一个图像文件,从而可使网页显示的更快。这种组合图像文件被称为CSS精灵。

2.1.3将SVG作为应用程序。

要将外部SVG文件整合到HTML页面中,而又不想受到作为图像嵌入时的种种限制的话,可以使用嵌入图像。

<object>元素是嵌入外部文件到HTML以及XHTML文档中的一种通用的方式。它可以用于嵌入图像,类似于<img>,也可以用于嵌入独立的HTML/XML文档,类似于<iframe>,更重要的是,它还可以用于嵌入任意类型的文件,只要浏览器有解析该文件类型的应用程序(浏览器插件或者扩展)即可。使用<object>嵌入SVG,可以让那些不能显示SVG但是有SVG插件的老版本浏览器用户也能查看图像。

<object>元素的type属性表示嵌入的文件类型,这个属性应该是一个有效的网络媒体类型(通常被称为MIME类型)。对于SVG,使用type="image/svg+xml"

浏览器使用文件类型确定如何(或者是否可以)显示该文件,而不需要首先下载文件。文件的位置通过data属性指定。alt和title属性的用法和图像一样。

<object>元素必须有起始标签和结束标签,这两个标签之间的内容只会在对象数据本身不能被渲染时显示,可以用来指定在浏览器无法显示SVG时应显示的备用图像或者警告文本。

下面的代码会在浏览器不支持SVG时显示一个说明文本和一个栅格图像:

<object data="cat.svg" type="iamge/svg+xml" title="Cat Object" alt="Stick Figure of a cat">
<!-- 文本或者栅格图像用作备选项 -->
<p>No SVG support!Here's a substitute:</p>
<img src="cat.png" alt="A raster rendering of a Stick Figure of a Cat" title="Cat Fallback"/>
</object>

在引入<object>之前,有些浏览器使用的是<embed>元素来达到相同的目的。如需支持老版本浏览器,可以使用<embed>元素替换<object>元素。为了得到更广泛的支持,可以将<embed>作为<object>标签内部的备用内容。

<embed>和<object>的区别:首先<embed>中源数据文件使用src而不是data属性指定;其次,<embed>元素不能包含任何字内容,因此如果嵌入失败就没有备用选项。

当SVG文件作为嵌入对象引用时,SVG文件的渲染方式与它被包含在<img>元素中时大致相同:它会被缩放以适配嵌入元素的宽高,并且不会继承定义在父文档中的任何样式。

然而与图像不同,嵌入的SVG可以包含外部文件,同时脚本可以在该对象和父页面之间进行通信。

2.3混合文档中的SVG标记

2.3.1 SVG中的foreign object

混合内容的一种方式是在SVG内插入部分HTML(或其他)内容,SVG规范定义了一种在图像指定区域嵌入这种“foreign”内容的方式

<foreignObject>元素定义了一个矩形区域,Web浏览器(或者其他SVG阅读器)应该在其中绘制子XML内容。浏览器负责确定如何绘制内容。子内容通常是XHTML(XML兼容的HTML)代码,但它也可能是SVG阅读器能显示的任意形式的XML。内容类型通过子内容上的xmlns属性声明的XML命名空间来定义。

矩形绘制区域通过<foreignObject>元素的x、y、width和height属性定义,方式类似于<use>或者<image>元素。

对于创建混合SVG/XHTML文档,<foreignObject>元素极具潜力,但是目前未得到很好的支持,IE(到版本11为止)根本不支持它,在其他浏览器实现中也还存在错误和不一致性。

<g transform="skewX(20)">
<switch>
<!-- 选择一个子元素 -->
<foreignObject x="1em" y="25%" width="10em" height="50%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<body xmlns="http://www.w3.org/1999/xhtml">
<p>
this is an XHTML pragraph embedded within a SVG!
So this text will wrap nicely around multiple lines,
but it will still be skewed from the SVG tranform.
</p>
</body>
</foreignObject>
<text x="1em" y="25%" dy="1em">
This SVG text won't wrap,so it will get cut off...
</text>
</switch>
</g>

如果想定义备用内容,以防SVG阅读器不能显示foreign object内容,可以结合使用requiredFeatures属性和<switch>。在支持XHTML和foreign object的浏览器中。在其他浏览器中,只显示SVG文本。

<switch>元素会告诉SVG阅读器只有在元素的requiredFeatures、requiredExtensions一级systemLanguage属性求值为true或者缺失的时候,才绘制第一个直接子元素(以及所有子节点)。

2.3.2在XHTML或者HTML5中内联SVG

另一种混合SVG和XHTML的方式是在XHTML文档中包含SVG标记,它还可以在使用HTML5语法的非XML兼容的HTML文档中使用。称为内联SVG。

对于XHTML,可以通过在SVG命名空间内定义SVG元素来表明正在切换到SVG。最简单的方式就是在*<svg>元素上设置xmlns="http://www.w3.org/2000/svg",它会改变改元素以及其所有子节点的默认命名空间。

对于HTML5,<svg>元素上的xmlns属性是可选的。对于XHTML文档,需要干煸文件顶部的DOCTYPE声明,以及使用<![CDATA[...]]>块包裹<style>元素的CSS代码。

<!DOCTYPE html>
<html>
<head>
<title>SVG in html</title>
<style>
svg {
display: block;
width: 500px;
height: 500px;
margin:auto;
border:thick double navy;
background-color: lightblue;
}/* SVG应该如何放置以及在HTML文档内的尺寸 */ body{
font-family: cursive;
}
circle{
fill:lavender;
stroke:navy;
strike-width:5;
}
</style>
</head>
<body>
<h1>Inline SVG in HTML Demo Page</h1>
<svg viewBox="0 0 250 250"
xmlns="http://www.w3.org/2000/svg">
<title>An SVG circle</title>
<circle cx = "125" cy = "125" r="100" />
<text x = "125" y = "125" dy = "0.5em" text-anchor="middle">
Look Ma,Same Font!
</text>
<p>And here is regular HTML again...</p>
</svg>
</body>
</html>

2.3.3其他XML应用程序中的SVG

XML命名空间除了可以用于XHTML以外,也可以用于在其他XML文档中标识SVG,具体的细节依赖于主XML文档的语法,但是又两个基本要求:XML文档必须为SVG元素明确定义一个布局盒子,并且用于显示这个文档的程序必须知道如何绘制SVG。

一种经常内联SVG的XML文档类型是可扩展样式语言格式化对象文件(XSL-FO)。一个XSL-FO文件顶一个一个多页文档的内容和布局,可以用于发布或者创建一个PDF文件。XSL-FO数据类型定义包含一个<instream-foreign-object>元素,它类似于SVG的<foreignObject>元素,定义一个矩形区域来容纳来自不同命名空间的内容。