来源: http://www.w3ctech.com/topic/1555

原文地址:http://www.smashingmagazine.com/2014/03/rethinking-responsive-svg/

如果你还未曾见过乔•哈里森响应式图标http://responsiveicons.co.uk/的技术,那你很可能会像我第一次看到它时一样,对它印象深刻。在这篇文章中,我想探究一下,我们该如何使用SVG来做一些更有趣的事情,而不只是作为“可伸缩矢量图形”来对PNG位图进行替换。事实上,我们知道SVG作为一个独立的模块,不光能够通过封装CSS实现自定义视图,也能够通过封装javascript实现交互逻辑。

那现在,让我们深入了解一下该技术。

响应式SVG:流浪汉的方法

哈里森的响应式图标的网站实现方式很简单。它使用了一个众所周知的前端技术, image sprites。如果你不了解该技术,那我来介绍一下。 image sprites是一门以节省带宽、提升网络性能为目的的以往只用于光栅图像的技术。它的实现逻辑是让很多小图像组合成一个文件,这样客户端就只需要从服务器下载一张图片。

你可以使用CSS来移动图片,使其显示在需要让它显示的地方,这种方式相比于下载每个图片,将会更加节约网络流量。

除了将PNG替换成SVG,哈里森对于SVG的处理方式与image sprites并没有什么不同。他将所有图标合并为一个文件,如下图所示:

所有的图标组合在单个SVG文件,该文件之后会被设置为一个容器的背景,在该容器中,一个图标会显示出来:

  1. .icon {
  2. width: 300px;
  3. height: 300px;
  4. background: url(../images/home_sprite.svg);
  5. background-position: center top;
  6. }

上面所举的例子虽然很简单,但也存在一些问题。那就是该解决方案不够简便。实际上,想要使用这种方式,两部分必不可少:外联的CSS和SVG Sprite。

响应式SVG:穷人的方法

因为CSS可以在SVG内部定义,那我们来修改一下上面的例子,使用更简便的方法来封装图标。首先,删除sprite里图标的所有的空间相关属性。当然,这也给我们留下了一堆堆积杂乱的图标: http://codepen.io/pukhalski/embed/inxym?height=343&theme-id=8287&slug-hash=inxym&default-tab=result&user=pukhalski

然后,按照图标重新排列所有的形状和组,添加.icon类到每个组,还有编号,以便能够获取任意一个我们所需要的(例如,#home_icon_0,#home_icon_1到#home_icon_8):

  1. <svg>
  2. <g id="home_icon_0" class="icon">
  3. <!-- paths and shapes -->
  4. </g>
  5. <!-- ... -->
  6. <g id="home_icon_8" class="icon">
  7. <!-- paths and shapes -->
  8. </g>
  9. </svg>

现在,我们准备添加媒体查询,这样我们就可以选择我们想要显示的SVG文件中的图标了。为此,我们可以用<defs>标签把CSS直接写在<svg>标签中。

  1. <svg>
  2. <defs>
  3. <style>
  4. /* Hide all of the icons first. */
  5. .icon {
  6. display: none;
  7. }
  8. /* Display the first one. */
  9. #home_icon_0 {
  10. display: block;
  11. }
  12. /* Display the desired icon and hide the others according to the viewport's size. */
  13. @media screen and (min-width: 25em) {
  14. #home_icon_0 {
  15. display: none;
  16. }
  17. #home_icon_1 {
  18. display: block;
  19. }
  20. }
  21. @media screen and (min-width: 30em) {
  22. #home_icon_1 {
  23. display: none;
  24. }
  25. #home_icon_2 {
  26. display: block;
  27. }
  28. }
  29. /* And so on */
  30. </style>
  31. </defs>
  32. <!-- Icon groups go here -->
  33. </svg>

这样,相同的图标就可以适应视图的大小了,现在,CSS规则,媒体查询和SVG形状都封装在SVG文件中。缩放你的浏览器,来看看它在下面的例子中是如何运行的: http://codepen.io/pukhalski/embed/uxIKB?height=349&theme-id=8287&slug-hash=uxIKB&default-tab=result&user=pukhalski

响应式SVG:持枪男人的方法

上面的例子虽然看起来比第一个稍微好一点,但问题依然存在:

  • 响应式SVG能否以一种更好的方式实现?
  • 相比隐藏和显示部分文件,使用自定义元素与响应式的方式对图标进行布局是否更可行?

细查响应式网页设计所用的内容编排和布局结构调整的方法会发现,我们仍然可以优化我们的方法。我们可以使用响应式设计,图形重构和变换,以使图标适用不同的视图的大小。

首先,在我们的SVG sprite中重绘最大且最详细的房子的图标,拆分所有路径,并把形状加入到元素的形状中。这种方式更易读,而且移植性更强:

http://codepen.io/pukhalski/embed/Azqyn?height=325&theme-id=8287&slug-hash=Azqyn&default-tab=result&user=pukhalski

重绘的图标虽然看起来和sprite里最大的图标一样,但它包含更多的形状,而这仅多占用了一丢丢空间。神奇之处在于,我们把媒体查询和变换添加到新的变种中,通过改变图标本身的形状可以得到和SVG sprite相同的结果。


  1. <svg>
  2. <defs>
  3. <style>
  4. @media screen and (max-width: 65em) {
  5. #door-shadow, #tube-shadow, .backyard {
  6. display: none;
  7. }
  8. #door-body {
  9. fill: white;
  10. }
  11. #door-handle {
  12. fill: #E55C3C;
  13. }
  14. #door-body, #door-handle {
  15. -ms-transform: translate(0,0);
  16. -webkit-transform: translate(0,0);
  17. transform: translate(0,0);
  18. }
  19. #window {
  20. -ms-transform: translate(0,0) scale(1);
  21. -webkit-transform: translate(0,0) scale(1);
  22. transform: translate(0,0) scale(1);
  23. }
  24. #house-body {
  25. -ms-transform: scaleX(1) translate(0, 0);
  26. -webkit-transform: scaleX(1) translate(0, 0);
  27. transform: scaleX(1) translate(0, 0);
  28. }
  29. #tube-body {
  30. -ms-transform: translate(0, 0);
  31. -webkit-transform: translate(0, 0);
  32. transform: translate(0, 0);
  33. }
  34. #tube-upper {
  35. -ms-transform: translate(0, 0);
  36. -webkit-transform: translate(0, 0);
  37. transform: translate(0, 0);
  38. }
  39. }
  40. /* And so on */
  41. </style>
  42. </defs>
  43. <!-- Icon groups go here -->
  44. </svg>

只要我们使用上面提到的方法,图标就会表现的像乔•哈里森的SVG sprite一样,而且它自己会包含全部的逻辑。在新窗口中打开下面的例子,调整其大小以查看所有图标变种。

http://codepen.io/pukhalski/embed/hFLDG?height=336&theme-id=8287&slug-hash=hFLDG&default-tab=result&user=pukhalski

使图标适应父容器的尺寸

还有一件事,就是让图标能够对父容器的宽高变化实现响应。为了做到这一点,我尝试加载一个包裹在div中使用img标签的SVG文件。但似乎SVG文件所有的媒体查询都失效了。

我的第二次尝试是加载了一个由div包裹的object元素中的图标。这种方式下,所有的媒体查询都起作用了:让对象能够充满整个父容器。(记得将SVG元素的宽度和高度的设置为100%或者完全删除。)

  1. <div style="width: 100%; margin: 0 auto;">
  2. <object>
  3. <embed src="responsive3.svg" style="width: 100%; height: auto;" />
  4. </object>
  5. </div>

下面是其他将媒体查询和变换嵌入SVG的方式,你可以使用SVG作为块级元素的背景图像。内联的SVG也可以,但媒体查询将会对视图变化产生响应。

下面的例子演示了图标是如何适配不同大小容器的。根据SVG将要渲染的尺寸大小,SVG中将通过媒体查询来实现对图标的绘制。这里是八个嵌入在一个相同的SVG文件中但尺寸不同的例子。

http://codepen.io/pukhalski/embed/hszLl?height=485&theme-id=8287&slug-hash=hszLl&default-tab=result&user=pukhalski

添加JavaScript到SVG

其他的好消息! SVG文件不仅可以封装CSS,也可以封装JavaScript。本质上,我们在使用任何一种旧标记的语言时,都可以把一个被引用SVG文件当做一个独立的模块。

当JavaScript 内联到在元素中时,还能够完美地执行。多奇妙的世界,是吧?

浏览器支持

能够完美支持在SVG文件中实现媒体查询和变换的浏览器版本有:

  • 互联网浏览器9+
  • 火狐17+
  • 谷歌17+
  • 欧朋15+
  • Safari浏览器6.0+
  • Safari浏览器iOS 6.0或更高版本 Android浏览器 Android 3.0+

该技术有可能在某些旧版本的浏览器中能够实现,但一些转换效果,如缩放,可能还不支持。

结论

响应式SVG图标可以应用在很多方面,如下所示:

  • 响应式广告;
  • 标志;
  • 应用程序的图标。

我要指出的是,乔•哈里森提出的sprite技术并没有什么不妥。它能够实现,并且在某些场景下非常有用。

【转】【翻译】对响应式SVG的再思考的更多相关文章

  1. ProgressBar.js – 漂亮的响应式 SVG 进度条

    ProgressBar.js 是一个借助动态 SVG 路径的漂亮的,响应式的进度条效果.使用 ProgressBar.js 可以很容易地创建任意形状的进度条.这个 JavaScript 库提供线条,圆 ...

  2. Flexslider - 响应式的 jQuery 内容滚动插件

    FlexSlider 是一款轻量的响应式 jQuery 内容滚动插件,能够帮助你在项目轻松的创建漂亮的内容滚动效果.这款插件曾经连续多年入选 WDL 的年度最佳 jQuery 插件,值得大家在网站开发 ...

  3. 响应式编程(Reactive Programming)(Rx)介绍

    很明显你是有兴趣学习这种被称作响应式编程的新技术才来看这篇文章的. 学习响应式编程是很困难的一个过程,特别是在缺乏优秀资料的前提下.刚开始学习时,我试过去找一些教程,并找到了为数不多的实用教程,但是它 ...

  4. Pizza Pie Charts – 基于 Snap SVG 框架的响应式饼图

    Pizza Pie Charts 是一个基于 Adobe 的 Snap SVG 框架的响应式饼图插件.它着重于集成 HTML 标记和 CSS,而不是 JavaScript 对象,当然Pizza Pie ...

  5. ng2响应式表单-翻译与概括官网REACTIVE FORMS页面

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  6. Angular2响应式表单-翻译与概括官网REACTIVE FORMS页面

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  7. [技术翻译]预加载响应式图像,从Chrome 73开始实现

    本次预计翻译三篇文章如下: 01.[译]9个可以让你在2020年成为前端专家的项目 02.[译]预加载响应式图像,从Chrome 73开始实现 03.[译]您应该知道的13个有用的JavaScript ...

  8. 【翻译】使用Ext JS设计响应式应用程序

    原文:Designing Responsive Applications with Ext JS 在当今这个时代,用户都希望Web应用程序无论在形状还是大小上,既能在桌面电脑,也能在移动设备上使用.使 ...

  9. css3基础、(弹性、响应式)布局注意点

    E1>E2选择父元素为E元素的所有E2元素(子类选择器) E1+E2选择元素为E1之后的所有E2元素(兄弟选择器) E[attr]只使用属性名,但没有确定任何属性值 E[attr="v ...

随机推荐

  1. Android ProgressBar分析及自定义ProgressBar

    ProgressBar是在执行耗时操作时的一种人性化设计.分为两种形式:转圈的,能显示进度的. 而能取决于是什么样式的PregressBar,当然就是PregressBar的样式啦~ Widget.P ...

  2. 我的Android第五章

    今天我们来讲一下Android四大组件中的activity的生命周期, 首先我们可以看一张activity的生命周期的图解看一下 关于Activity的生命周期,有以下几个要注意的点: 1.最开始进入 ...

  3. 不用git将项目push到码云上

    1.在码云上创建一个项目: 2.打开STS(spring Tool Suite)   新建一个Maven(webapp)项目: 3.打开你的码云账号,把码云上的工程的URL复制: 4.重新在另一个目录 ...

  4. [DataBase] MongoDB (8) 副本集

    MongoDB  创建副本集 MongoDB复制是将数据同步在多个服务器的过程. 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性. 复制还允许您从 ...

  5. linux中断处理原理分析

    Tasklet作为一种新机制,显然可以承担更多的优点.正好这时候SMP越来越火了,因此又在tasklet中加入了SMP机制,保证同种中断只能在一个cpu上执行.在软中断时代,显然没有这种考虑.因此同一 ...

  6. GDUFE-OJ 1361校庆抽奖 翻转

    Problem Description: 在舞台中央有一个开奖盒,开奖盒有一个按钮,和一个显示屏,每轮抽奖是过程是这样的. 主持人请K个幸运观众上台,编号为1~K,围着开奖盒. 首先开奖盒上随机显示一 ...

  7. excel 怎么修饰图表

    文中的图表只是方便以后记忆,故不详,具体细节没有截图保存,详细了解的,请自行百度

  8. centos7 yum 方式安装nginx

    centos7系统库中默认是没有nginx的rpm包的,所以我们自己需要先更新下rpm依赖库 (1)使用yum安装nginx需要包括Nginx的库,安装Nginx的库 #rpm -Uvh http:/ ...

  9. Attribute

    Attribute介绍 咱们来说Attribute,他是一个类,所以自定义的Attribute都是继承自System.Attribute,一般命名的时候都是以Attribute结尾.在使用的时候我们可 ...

  10. quantile normalization原理

    对于芯片或者其它表达数据来说,最常见的莫过于quantile normalization啦. 那么它到底对我们的表达数据做了什么呢?首先要么要清楚一个概念,表达矩阵的每一列都是一个样本,每一行都是一个 ...