以下是Amelia Bellamy-Royds的来宾帖子。 作为SVG Essentials的合著者和即将出版的《 将SVG与CSS3和HTML5结合使用》的作者,Amelia在SVG方面拥有丰富的经验。 我和Amelia都将在即将到来的RWD峰会上就SVG发表演讲! 在这里,她分享了扩展SVG的史诗指南,涵盖了您可能要执行的所有方法。 它几乎不像缩放栅格图形那样简单,但是那样很好,因为它带来了有趣的可能性。
您已做出决定。 您终于要做到了。 今年,您将开始在Web设计中使用SVG 。 您在Inkscape中创建了精美的标题徽标,然后将其吐出的SVG代码复制并粘贴到WordPress标题文件中。 当然,您不会因为总是使用响应式设计而放弃去年的分辨率,因此您设置svg.banner { width: 100%; height: auto; }
svg.banner { width: 100%; height: auto; }
svg.banner { width: 100%; height: auto; }
,并认为您已设置好。
除非您在测试浏览器中打开网页,然后发现其中一些在图像的上方和下方都留有巨大的空白块,而另一些则将其裁剪得太短。
SVG代表可缩放矢量图形。 因此,缩放SVG应该很容易,对吧? SVG倡导者一直以来都在说SVG在任何大小上看起来都不错吗? 是的,但事实并非如此。 SVG在任何规模上都看起来不错,但是它可以以多种不同的方式进行扩展,以至于它只能按照您想要的方式运行,这会使SVG初学者感到困惑。 浏览器只是最近才开始采用标准方法来调整嵌入式SVG内容的大小,这无济于事。
SVG不是(只是)图像
缩放SVG如此困难的部分原因是因为我们对图像应如何缩放有一定的了解,并且SVG的行为方式不同。
JPG,PNG和GIF之类的光栅图像具有明确定义的尺寸。 图像文件描述了浏览器应如何在一定像素宽和一定像素高的网格中着色。 一个重要的副作用是,光栅图像具有明确定义的宽高比 : 宽高比 。
您可以强制浏览器以不同于其固有高度和宽度的大小来绘制光栅图像,但是如果将其强制为不同的宽高比,则事情将变得失真。 出于这个原因,自网络早期以来,就支持auto
缩放图像:设置高度或宽度,然后浏览器调整其他尺寸,以使纵横比保持恒定。
看到笔图像缩放基本由无肢贝拉米-罗伊兹( @AmeliaBR上) CodePen 。
相反,SVG图像可以以任何像素大小绘制,因此它们不需要明确定义的高度或宽度。 而且它们并不总是具有明确定义的宽高比。 如果希望SVG缩放以适合您提供的尺寸,则需要显式提供此信息(以及更多信息)。
如果您不这样做,SVG将根本无法扩展。 下面的示例使用嵌入式SVG,在不更改绘制图形大小的情况下,调整元素的尺寸(虚线):
见笔无标SVG被阿梅利亚贝拉米-罗伊兹( @AmeliaBR上) CodePen 。
为什么会这样呢? 因为SVG并非(仅仅是)图像。 SVG是一个文档。 尽管上面的示例使用了嵌入式SVG,但使用或
也很容易。 即使您使用
标签嵌入相同的SVG代码,其外观也将完全相同。
当包含带有HTML文件时,您不希望在更改框架大小时缩放其中的文本。 与SVG相同。 默认情况下,无论画布大小如何,都将以代码中指定的尺寸绘制它。如果将这些SVG的高度或宽度(或两者)设置为
auto
,会发生什么? 将使用HTML替换元素的默认大小:宽300px,高150px。 这适用于 ,
或
。 默认的300×150尺寸也适用于HTML文档中的内联
元素,但这是HTML5规范中的一个相对较新的共识:默认情况下,其他浏览器会将内联SVG扩展为视口的完整大小,相当于
width: 100vw; height: 100vh;
width: 100vw; height: 100vh;
—这是直接在自己的浏览器标签中打开的SVG文件的默认大小。 Internet Explorer通过使用100%的宽度和150px的高度(用于图像和嵌入式SVG)来缩小差异。
换句话说,即使您认为300×150是理想的图像尺寸(尽管为什么会这样?),也不要依赖于HTML中的默认尺寸。
除了确定SVG的大小,还必须确定希望图形缩放以适合该大小的方式。 下面,我描述了在最常见的情况下获取所需比例尺所需的代码:
- 缩放以适合特定大小,而不会扭曲图像
- 缩放以适合特定大小,并根据需要拉伸或压缩图形
- 缩放以适合可用宽度,同时保持宽高比
- 以非均匀的方式缩放,以使图形的某些部分缩放比例与其他部分不同
但首先:如果您想控制SVG的缩放比例,则需要熟悉SVG缩放比例属性和其他可用工具。
SVG缩放工具箱
其他图像可以缩放,因为浏览器知道图像的高度,宽度和纵横比,并且可以一起调整所有内容。 为SVG提供这些属性是按比例缩放的第一步。 但是,缩放SVG超出了其他图像可能实现的范围。
height
和width
属性
乍一看SVG规范将建议顶级svg
元素上的height
和width
属性将隐式设置长宽比,从而使SVG像其他图像一样缩放。 的确,当您将SVG用作图像时,设置高度和宽度会覆盖默认尺寸。 但是,这并非易事:
- 如果使用
嵌入SVG,则在大多数浏览器中(如果不是Internet Explorer),设置
height
和width
将使SVG缩放可预测。 使用CSS,例如img { width: 100%; height: auto; }
img { width: 100%; height: auto; }
img { width: 100%; height: auto; }
,IE将自动缩放图像区域以保持width:height纵横比恒定,但不会缩放实际图形以匹配图像尺寸的比例。 - 如果您使用
,
或
嵌入SVG,则在
上设置高度和宽度不会更改框架的大小;
。 如果SVG太大,您只会在iframe中获得滚动条。
- 如果您使用内联SVG(即
直接在您HTML5代码),那么
元素具有双重用途,在网页内以及在SVG中定义的图像区域。 您使用CSS为SVG设置的任何高度或宽度都将覆盖
上的height和width属性。 像
svg {width: 100%; height: auto;}
svg {width: 100%; height: auto;}
将取消您在代码中设置的尺寸和宽高比,并为您提供嵌入式SVG的默认高度。 如上所述,根据浏览器的不同,该分辨率将为150px或100vh。
因此,请忘记height
和width
。 您实际上并不想设置确切的高度和宽度,而是希望SVG缩放以匹配您在CSS中设置的宽度和/或高度。 您想要的是为图像设置长宽比 ,并使绘图比例适合。 您需要一个viewBox
。
viewbox
属性
SVG viewBox
在一个小属性中viewBox
了很多魔力。 这是使矢量图形可缩放矢量图形的最后一部分。 viewBox做很多事情:
- 它定义图像的纵横比。
- 它定义了如何缩放SVG内部使用的所有长度和坐标以适合可用的总空间。
- 它定义了SVG坐标系的原点,即x = 0和y = 0的点。
viewBox
是元素的属性。 它的值是四个数字的列表,用空格或逗号分隔:x,y,宽度,高度。 宽度是SVG代码中以用户坐标/ px为单位的宽度,应缩放以填充绘制SVG的区域的宽度(SVG语言中的视口 )。 同样,高度是应该缩放以填充可用高度的px /坐标数。 即使您的SVG代码使用其他单位,例如英寸或厘米,它们也将被缩放以匹配
viewBox
创建的整体比例。
x和y数字指定比例缩放的viewBox
坐标系中的坐标,该坐标用于SVG视口的左上角。 (坐标从左到右和从上到下增加,与在JavaScript中标识页面位置相同)。 为了进行简单缩放,可以将两个值都设置为0。但是,x和y值有两个用途:创建一个以图形为中心的原点的坐标系(这可以使定义和变换形状更加容易),或者裁剪比原始定义更紧的图像。
一些示例viewBox
值:
-
viewBox="0 0 100 100"
:定义一个坐标系,其宽度为100个单位,高度为100个单位。 换句话说,如果SVG包含一个以图形为中心且半径为50px的圆,则即使该图片以全屏显示,它也会填满SVG图像的高度或宽度。 如果您的SVG包含一个height="1in"
的矩形,它也会几乎填满整个屏幕,因为CSS中1英寸= 96像素,所有长度都将按比例缩放。 -
viewBox="5 0 90 100"
:几乎相同的视图,但在左右两侧裁剪了5%,因此总宽度= 90个单位,而x坐标在左侧= 5。 -
viewBox="-50 -50 100 100"
:具有相同比例的视图,但现在左上角已指定坐标(-50,-50)。 这意味着右下角的坐标为(+50 +50)。 在(100,100)处绘制的任何形状都将远离屏幕。 如果要绘制一个完全填满图像区域的圆,则该圆将以(0,0)为中心。
将viewBox
添加到 (默认情况下,Inkscape和Illustrator之类的编辑器会添加它)后,您可以将该SVG文件用作图像或内联SVG代码,并且可以完美缩放以适合任何大小你给它。 但是,它仍然无法像其他任何图像一样缩放。 默认情况下,如果您提供的尺寸与宽高比不匹配, 则不会拉伸或变形 。 相反,将调整比例,以保留代码中定义的宽高比。
preserveAspectRatio
属性
viewBox
属性具有一个补充, preserveAspectRatio
。 除非存在用于定义图像纵横比的viewBox
否则它无效。 当有viewBox时, preserveAspectRatio
描述了如果viewBox的纵横比与视口的纵横比不匹配时如何缩放图像。 在大多数情况下,默认行为效果很好:将图像缩放到恰好适合高度和宽度,并且将其居中放置在任何额外空间内。
就像viewBox
一样, preserveAspectRatio
在单个属性中具有大量信息。 可以使用preserveAspectRatio="xMidYMid meet"
显式设置默认行为。 第一部分, xMidYMid
告诉浏览器在x和y方向xMidYMid
缩放后的viewBox区域居于可用视口区域的中心。 您可以替换Mid
用Min
或Max
对齐图形平齐一方或另一方。 但是,请注意驼峰大写:SVG是XML,因此区分大小写。 x
是小写字母,而Y
是大写字母。
默认preserveAspectRatio
后半部分, meet
,是告诉浏览器缩放图形直到恰好适合高度和宽度的部分。 CSS背景图片的等效background-size: contain;
是background-size: contain;
。 SVG的替代值是slice
(相当于background-size: cover;
)。 slice
值将缩放图像以适合更大的尺寸,并切掉多余的部分。 除此以外,它并不一定要削减掉多余的部分。 这取决于overflow
属性的值。
(旁注:如果希望每个图像都可以在其给定的尺寸上居中,而不是被拉伸或变形, 则新的object-fit
CSS属性可让您对其他图像类型执行相同操作 。)
还preserveAspectRatio="none"
选项,以使SVG完全像光栅图像一样缩放(但分辨率要好得多),拉伸或压缩以适合您提供的高度和宽度。
如何缩放SVG以适合特定大小(不使图像失真)
可能最常见的要求是使SVG图标比例尺适合特定的大小,而不会失真。 尽管您可以使用preserveAspectRatio
来调整对齐方式,但是viewBox
属性实际上是您所需要的。
如前所述,如果要在图形编辑器中创建SVG,则它可能已经包含了viewBox。 但是,您可能需要调整viewBox以使定位恰到好处。 在其余的示例中,已为该金罐图形提供了viewBox="0 0 60 55"
。 在它周围留出一些额外的空间; 要创建一个裁剪图标,可以使用viewBox="4.5 1.5 51 49"
。 以下示例还显示了默认的preserveAspectRatio
的效果,该效果将图形居中放置在所提供的空间中:
参见Pen Normal SVG缩放,并在 CodePen上使用Amelia Bellamy-Royds( @AmeliaBR )的viewBox 。
如何缩放SVG以适合可用宽度(并调整高度以匹配)
带有viewBox
SVG可以缩放以适合您提供的高度和宽度。 但是自动调整大小呢? 对于光栅图像,您可以设置width
或 height
,并使另一个比例匹配。 SVG可以做到吗?
可以,但是变得复杂。 有两种不同的方法可供选择,具体取决于您包含SVG的方式。
选项1:使用图片自动调整大小
当SVG文件具有viewBox
并将其嵌入 ,浏览器将(几乎总是)缩放图像以匹配
viewBox
定义的宽高比。
在CodePen上查看 Amelia Bellamy-Royds( @AmeliaBR )的Pen Auto-Scaling SVG图像 。
但是,Internet Explorer仍然是SVG的祸根。 尽管通常正常工作,但我使用display: table-cell
在本示例的早期版本中布置了数字,并且IE以怪异的方式扭曲了图像。
如果完全自动调整图像大小,则Internet Explorer将应用标准的默认300×150大小。 但是,其他浏览器将应用{ width: 100%; height: auto; }
{ width: 100%; height: auto; }
{ width: 100%; height: auto; }
默认如果图像具有viewBox
; 此行为未在任何规范中定义。
回顾一下:要自动缩放用作 SVG,
- 设置一个
viewBox
属性。 - 设定为高度或宽度的至少一个 。
- 如果您想支持Internet Explorer,请不要将其放在表格布局中。
选项2:使用CSS背景图片和padding-bottom
Hack
在大多数情况下,将SVG用作CSS背景图片的方式与使用SVG的方式几乎相同(但还有一个额外的好处,即可以为旧版浏览器定义栅格后备)。 较旧的浏览器在将图像转换为光栅后而不是之前(即像素化)缩放图像时,存在一些错误,但是在大多数情况下,
viewBox
就是您所需要的。
但是,自动调整大小不是CSS背景图片的选项; 毕竟,该图像应该位于元素HTML内容之后。 如果您希望元素与要使用的图像的长宽比完全匹配,则将不得不对其进行一些修改。
有一定数量CSS属性,可让您根据可用宽度调整基于高度的属性。 如果将block-layout元素的border
, padding
或margin
设置为百分比值,则即使相对于顶部和底部边框,padding和margin,百分比也将相对于容器的可用宽度进行计算。
预期的目的是即使高度是自动的,也要创建均匀大小的边框和填充。 但这不是重点。 出于我们的目的,关键是您可以与宽度成比例地调整元素的总高度。 换句话说,您可以控制纵横比。 要创建宽度为100%的 注意事项: 对于黄金罐图像,长宽比为60:55,底部填充为92%。 实际上,它看起来像这样: 请参见CodePen上的Ascalia Bellamy-Royds( @AmeliaBR )将Pen 缩放 SVG图像很好,但是在许多情况下,您会更喜欢使用嵌入式SVG。 内联SVG减少了HTTP请求的数量,允许用户交互,并且可以通过您的主网页中CSS进行修改。 但是会扩展吗? 如果您使用的是最新的Firefox或Blink浏览器,它将使用。 只需在 见笔自动缩放SVG内联通过阿米莉亚·贝拉米-罗伊兹( @AmeliaBR上) CodePen 。 但是有可能,这些并不是您需要支持的唯一浏览器。 许多浏览器(2014年夏季之前发布的IE,Safari和Opera和Chrome版本)将不会自动调整内置SVG的大小。 如果您未同时指定高度和宽度,则这些浏览器将应用其通常的默认大小,如前所述,不同的浏览器会有所不同。 图像将缩放以适合该高度或宽度,再次在其周围保留额外的空白。 同样,如果同时保留height 和 width 解决方案是再次使用 要使用容器 除非您有很多具有相同长宽比的图形,否则通常最好声明内嵌 见笔缩放联SVG使用软垫集装箱被阿梅利亚贝拉米-罗伊兹( @AmeliaBR上) CodePen 。 容器方法可行,但要付出标记中额外包装元素的代价。 而且,它也不是通用容器:它必须根据您的SVG所需的确切长宽比进行自定义。 如果您不希望将其扩展到完整的100%,事情会变得更加棘手。 您将需要使用另一个包装器 若要使用padding-bottom hack控制整个 再次,我喜欢对 那里还有其他一些细节: 如果您希望SVG缩放到小于100%宽度的某个百分比,请记住相应地调整 见笔缩放SVG内联使用填充和切片的阿米莉亚·贝拉米-罗伊兹( @AmeliaBR上) CodePen 。 尽管通常希望保持宽高比,但有时图像是要拉伸以适合的抽象图像或灵活图像。 拉伸以适合的一种选择是对SVG中的所有大小和位置属性使用百分比值。 见笔Flex的缩放SVG使用百分比由阿梅利亚贝拉米-罗伊兹( @AmeliaBR上) CodePen 。 关于百分比和SVG的注意事项: 如果您想灵活地缩放还包括SVG路径的SVG,则需要使用 请参阅CodePen上的Amelia Bellamy-Royds( @AmeliaBR )的使用prepareAspectRatio =“ none”的Pen Flex-Scaling SVG 。 请注意,使用 要意识到的重要一点是,您不需要为整个SVG定义单个 见笔Flex的缩放SVG使用嵌套SVGs被阿梅利亚贝拉米-罗伊兹( @AmeliaBR上) CodePen 。 翻译自: https://css-tricks.com/scale-svg/.ratio4-3 {
width: 100%;
background-image: url(image-with-4-3-aspect-ratio.svg);
background-size: cover;
height: 0;
padding: 0; /* reset */
padding-bottom: calc(100% * 3 / 4);
}
calc()
浏览器,则需要自己(或使用CSS预处理器)进行数学calc()
。 box-sizing: border-box
,则必须将其重新设置为使用box-sizing: content-box
。 我们希望它是height: 0
毕竟是height: 0
加填充。 padding-bottom
属性代替了padding-top
属性。 尽管您可能并不担心支持IE5,但您还是应该保持一致。 毕竟,这被称为padding-bottom
hack。 选项3:使用嵌入式SVG和最新的Blink / Firefox浏览器
上设置
viewBox
,然后将height或width之一设置为auto
。 浏览器将对其进行调整,以使总纵横比与viewBox
相匹配。 美丽。 auto
,也会发生不一致的情况。 padding-bottom
hack自己控制宽高比。 适用于内联SVG以及 ,
和其他替换元素(如
的最简单方法是使用容器元素。
选项4:在容器上使用
padding-bottom
Hack position: relative
对于容器,以便它将成为绝对定位的内容的参考框架。 然后将SVG(或其他对象)设置为position: absolute
,高度和宽度为100%。 需要绝对定位,以便相对于padding-bottom
,以使它就在需要匹配的viewBox
旁边: .scaling-svg-container {
position: relative;
height: 0;
width: 100%;
padding: 0;
padding-bottom: 100%;
/* override this inline for aspect ratio other than square */
}
.scaling-svg {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
选项5:在Inline
区域的长宽比,则官方高度将(基本上)为零。 使用默认的
preserveAspectRatio
值,图形将按比例缩小到无。 相反,您希望图形可以拉伸以覆盖您提供的整个宽度,并溢出到您精心设置为正确的宽高比的填充区域上。 padding-bottom
宽高比使用内联样式,因为需要针对viewBox
属性对其进行自定义。 在下面的示例中,我也将其用于其他样式属性,尽管如果您有许多需要相同效果的图形,则可以使用一个类:
preserveAspectRatio
使用YMin
为垂直取向,从而使所述图形抵靠的顶整齐地对准内容区域中,溢出进入底部填充。
overflow: visible
可能是HTML的默认设置,但需要为SVG显式设置。 padding-bottom
。 或使用包装器 如何缩放,拉伸和压缩SVG以完全适合特定大小
选项1:使用百分比
viewBox
(尽管您可以指定默认的高度和宽度)。
和
元素的坐标。 选项2:使用
preserveAspectRatio="none"
viewBox
加上viewBox
preserveAspectRatio="none"
。 这是那条彩虹的稍加幻想的版本,有浮云 s: preserveAspectRatio="none"
,所有内容均会被均匀拉伸或压缩,就像您缩放其他图像类型的比例不均一样。 这意味着圆圈会变成椭圆形,并且文字也会变形。 为避免这种情况,您需要使用多种缩放方法。 如何分别缩放SVG的各个部分
viewBox
和preserveAspectRatio
属性非常灵活。 一旦你停止SVG的思维只是另一种图像格式,你就可以开始问自己, 你希望你的图形,以规模作为窗口改变大小。 viewBox
和preserveAspectRatio
选项。 相反,您可以使用嵌套的元素,每个元素都有自己的缩放属性,以独立地具有图形缩放的不同部分。 (您也可以在
和
元素上使用这些属性,并且可以在SVG中嵌入的其他图像上使用preserveAspectRatio
。)通过这种方法,您可以创建标题图,该图可以拉伸以填充宽屏显示而无需占用以及过高的高度: