用 SVG 来代替图形上的 CSS Hack

一、前言

看到这个标题,确实容易让人产生疑惑,我的 CSS 这么 6,有了它,感觉我已经无所不能了,为啥要用把它替代掉?
下面,我们将从自身定位、开发体验、维护成本、兼容性等各个方面,简单分析一下。

二、自身定位

  • CSS ,Cascading Style Sheets,中文名叫层叠样式表,从它自身名字以及广泛的使用方式来看,它的功能,主要集中在格式化 HTML 样式,主要包括字体、排版等方面的内容;
  • SVG ,Scalable Vector Graphics,中文名可缩放矢量图形,名字中的图形二字,就不难看出,它主要注重解决图形处理方面的问题。

从一定程度上来讲,图形处理方面,CSS 就像一个业余选手,而 SVG 则是我们的专业运动员。

三、开发体验

闭着眼睛跟我谈什么开发体验?直接上代码先!Talk is cheap! Show me the code!
下面我们就结合几个常见的应用场景来体验一下 CSS 也 SVG 在开发上的不同体验:

(一)画一条斜线

这可能是最简单、但又最直观的例子了。

1. CSS version

<style>
    .line {
        width: 100px;
        border-bottom: 1px solid black;
        transform: rotate(45deg);
    }
</style>

<div class="line"></div>

2. SVG version

<svg>
    <line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="1"/>
</svg>

二者的实现效果大致如下图:

line.png

我想,聪明的你应该已经发现问题了吧,两条线长度不一样,原理其实也很简单。CSS 版的,是通过将一根长度为 100px 的线,顺时针旋转了 45 度形成的,其长度为 100px;SVG 版的,是一根(0, 0)点到(100,100)点的连线,根据勾股定理,其长度应该是 100 * Math.sqrt(2),也就是 100 乘以根号2,所以会比前者长。于是,更多问题就出来了。。。

  • 长度。常规的设计稿上,我们可以轻松拿到一条斜线首尾两点的位置用于 SVG 绘制,但是 CSS 依赖于它的长度。。。这样的话,只能说。。。勾三股四弦五。。。demo 中的线条,我们是一个顺时针旋转 45 度角的直线,可以认为是一个等腰直角三角形的斜边,要计算它的长度还比较方便,其它情况,计算起来就更麻烦了
  • 角度。和上说的一样,我们可以轻松拿到设计稿上斜线首尾两点的位置,所以使用 SVG 绘制的时候,我们可以完全关心它的角度问题;使用 CSS 绘制的时候,你可能需要拿一个量角器到屏幕上的设计稿中量一下斜线的倾斜角度,哦,对了,记得添加一条水平的辅助线便于测量
  • 位置。使用 SVG 绘制的斜线,画到哪儿就在哪儿;使用 CSS 绘制的斜线,默认会有一个 transform-origin 控制它旋转的时候以哪个点为中心,有时候,为了不让它跑偏,你可能需要手动控制一下。

(二)画一个朝上的三角形箭头

1. CSS version

<style>
    .tri-angle {
        width: 0;
        height: 0;
        border: 10px solid white;
        border-bottom: 10px solid black;
    }
</style>

<div class="tri-angle"></div>

2. SVG version

<svg>
    <polygon points="10 0, 20 10, 0 10" style="fill:black;"/>
</svg>

二者的实现效果大致如下图:


tri-angle.png

问题分析:

  • 大小。审查元素不难发现,使用 CSS 绘制的原本有效区域未 20 * 10 的箭头,结果却需要 20 * 20 的区域,顶上存在了 20 * 10 的无效区域。同样的方式绘制朝右的箭头,右侧也会存在相应大小的无效区域
  • 位置和布局。由于上面提到的无效区域的存在,在管理图标位置和页面布局的时候,往往容易出现一些问题
  • 形状。这里是绘制的等腰直角三角形,通过改变两侧 border 的宽度,我们还可以绘制出一般的等腰三角形。但如果要绘制三条边不一样长的三角形呢?SVG 实现依旧没有任何困难,而 CSS。。。可能需要经过繁杂的计算了。

依照类似的方式,CSS 还可以利用各种奇怪的方式,绘制出五边形、六边形、五角星等各种典型的图形,但是,其复杂程度,随图形的复杂程度不停的上升,在处理不规则图形的时候,特为尤甚。

啥?你说像五角星之类的,顶点数量太多,也很难取?不好意思,在 PS 的图层的右键菜单上,有一个复制 SVG 选项,你要不试一试?

P.S. 相邻位置上,还有一个复制 CSS 选项,一般情况下,除了复制阴影效果等,建议还是不要尝试了。

四、维护成本

1. 需求变更

产品和开发天生是一对冤家。我们没有办法保证需求不会变更,也不可能真让产品“扫码改需求”,那么作为开发我们真的就只能认命?也不全是,我们可以通过调整自己的开发模式,让需求变更的时候,做出相应修改时的时间、人力成本降低,进而降低项目的维护成本。比如一开始的那条斜线,这次我们需要让右下角的点不动,左上角的点向下移动 3 个像素,你可以用 CSS 、SVG 都试试怎么实现。

2. 普适性

还是拿最开始的斜线来说事。CSS 和 SVG 其实代表了两种不同的处理方式,CSS ——极坐标系,SVG 是笛卡尔(直角)坐标系。
大多数情况下,我们拿到的设计稿,一般都是基于笛卡尔坐标系的,只有少数专业性非常强的领域(如数学、物理等)才会必须使用类似极坐标系等方式,但这时候,大都会使用更加专业化的手法,而非 CSS。事实上,SVG 也能很好的处理极坐标系的图形,有兴趣可以学一下。所以,在图形绘制上,SVG 有着 CSS 难以企及的普适性。

3. 开源项目

事实证明,相比于用 CSS 中各种奇怪的手法,SVG 将更容易与我们的项目相结合,当然,这里说的是图形绘制。现在,CSS 已经有了很多相对成熟的“框架”,最典型的,莫过于 Bootstrap。但是纵观其功能,更多的是页面布局、风格样式相关的功能,框架内部的图形,基本都是依赖于其引用的 webfont,而没有通过 CSS 去 hack。反观 SVG,要不你去看一下这个项目 传送门。CSS 擅长的,本来就应该是各种布局、样式等效果,有时间可以去看一看这个项目传送门。个人精力有限,我这里列举的可能比较狭隘,大家有兴趣可以更多地去关注一下。

4.副作用

使用 CSS hack,往往会带来很多的副作用:一开始的斜线,使用 CSS 的时候,你去看过它所占的位置么?三角形箭头的实现,也必须占据更多的位置;CSS3 中的变形、旋转等,都可能会使得元素展示的位置与它实际在文档流中占据的位置不符,这使得我们在维护这样的代码的时候,经常需要额外的时间和精力。

五、兼容性
下面是 caniuse.com 中查询到的兼容性信息:

compatibility-svg.png

不难看出,比较主流的浏览器基本都已经实现了对 SVG 的支持,只有 IE8 例外,但实际上,它也可以通过安装插件的形式实现对 SVG 的支持。

综上,我们没有理由拒绝 SVG。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容