(翻译)SVG和media queries

关于SVG最棒的一件事就是,你可以使用media queries来添加图片响应

如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<style>
circle {
fill: green;
}
@media (min-width: 100px) {
circle {
fill: blue;
}
}
</style>
<circle cx="50" cy="50" r="50"/>
</svg>

但是什么情况下这个圈应该是蓝色的呢,规范说min-width必须是viewport的宽度,但是…

哪个viewport

1
2
3
4
5
6
7
<img src="circle.svg" width="50" height="50">
<img src="circle.svg" width="100" height="100">
<iframe src="circle.svg" width="50" height="50"></iframe>
<iframe src="circle.svg" width="100" height="100"></iframe>
<svg width="50" height="50">
…as above…
</svg>

如上,哪个圆是蓝色的圆(有可能被裁剪的),如上,哪个viewport会被使用
会是以下的么:

  • 主document的大小
  • svg上面的width/height/viewBox属性
  • img上面的width/height属性
  • img的layout

实际结果如下
Alt text

1
2
3
4
5
6
7
8
9
10
11
# 大多数浏览器会这样解析
对于<img>,svg会scale到图片大小,svg的viewport就是img的大小
所以第一个图片使用的viewport是50*50,所以第一个是绿色的
第二个图片使用的viewport是100*100,因此第二个是蓝色的
对于<iframe>,svg的viewport是iframe的大小
所以第三个是绿色,第四个是蓝色
对于<svg>,svg没有它自己的viewport,这是父级的一部分,这意味着style是被父级拥有的,作用域不是SVG。
# firefox怎么解析的呢
对于<img>,viewport,是device pixels里面的渲染大小,意味着,页面的viewport
# draw svg到canvas
可以draw<img>标签里面的内容到<canvas>
1
canvas2dContext.drawImage(img, x, y, width, height);

那么这种情况下,什么时候circle应该是蓝色的呢

  • 主窗口的css大小
  • svg的width/height/viewBox属性
  • img的width/height
  • img 的css layout
  • canvas 的像素大小
  • canvas的 css layout
  • drawImage调用时指定的width/height
  • drawImage调用时指定的width/height,乘以transfrom的倍数

svg demo
svg-media-queries