用 SVG 來代替圖形上的 CSS Hack

一铐然、前言

看到這個標題蔬崩,確實容易讓人產(chǎn)生疑惑,我的 CSS 這么 6搀暑,有了它沥阳,感覺我已經(jīng)無所不能了,為啥要用把它替代掉自点?
下面桐罕,我們將從自身定位、開發(fā)體驗、維護成本功炮、兼容性等各個方面溅潜,簡單分析一下。

二薪伏、自身定位

  • CSS 滚澜,Cascading Style Sheets,中文名叫層疊樣式表嫁怀,從它自身名字以及廣泛的使用方式來看设捐,它的功能,主要集中在格式化 HTML 樣式塘淑,主要包括字體萝招、排版等方面的內(nèi)容;
  • SVG 存捺,Scalable Vector Graphics槐沼,中文名可縮放矢量圖形,名字中的圖形二字捌治,就不難看出岗钩,它主要注重解決圖形處理方面的問題。

從一定程度上來講具滴,圖形處理方面,CSS 就像一個業(yè)余選手师倔,而 SVG 則是我們的專業(yè)運動員构韵。

三、開發(fā)體驗

閉著眼睛跟我談什么開發(fā)體驗趋艘?直接上代碼先疲恢!Talk is cheap! Show me the code!
下面我們就結(jié)合幾個常見的應(yīng)用場景來體驗一下 CSS 也 SVG 在開發(fā)上的不同體驗:

(一)畫一條斜線

這可能是最簡單、但又最直觀的例子了瓷胧。

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>

二者的實現(xiàn)效果大致如下圖:

line.png

我想显拳,聰明的你應(yīng)該已經(jīng)發(fā)現(xiàn)問題了吧,兩條線長度不一樣搓萧,原理其實也很簡單杂数。CSS 版的,是通過將一根長度為 100px 的線瘸洛,順時針旋轉(zhuǎn)了 45 度形成的揍移,其長度為 100px;SVG 版的反肋,是一根(0, 0)點到(100那伐,100)點的連線,根據(jù)勾股定理,其長度應(yīng)該是 100 * Math.sqrt(2)罕邀,也就是 100 乘以根號2畅形,所以會比前者長。于是诉探,更多問題就出來了日熬。。阵具。

  • 長度碍遍。常規(guī)的設(shè)計稿上,我們可以輕松拿到一條斜線首尾兩點的位置用于 SVG 繪制阳液,但是 CSS 依賴于它的長度怕敬。。帘皿。這樣的話东跪,只能說。鹰溜。虽填。勾三股四弦五。曹动。斋日。demo 中的線條,我們是一個順時針旋轉(zhuǎn) 45 度角的直線墓陈,可以認為是一個等腰直角三角形的斜邊恶守,要計算它的長度還比較方便,其它情況贡必,計算起來就更麻煩了
  • 角度兔港。和上說的一樣,我們可以輕松拿到設(shè)計稿上斜線首尾兩點的位置仔拟,所以使用 SVG 繪制的時候衫樊,我們可以完全關(guān)心它的角度問題;使用 CSS 繪制的時候利花,你可能需要拿一個量角器到屏幕上的設(shè)計稿中量一下斜線的傾斜角度科侈,哦,對了炒事,記得添加一條水平的輔助線便于測量
  • 位置兑徘。使用 SVG 繪制的斜線,畫到哪兒就在哪兒羡洛;使用 CSS 繪制的斜線挂脑,默認會有一個 transform-origin 控制它旋轉(zhuǎn)的時候以哪個點為中心藕漱,有時候,為了不讓它跑偏崭闲,你可能需要手動控制一下肋联。

(二)畫一個朝上的三角形箭頭

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>

二者的實現(xiàn)效果大致如下圖:


tri-angle.png

問題分析:

  • 大小。審查元素不難發(fā)現(xiàn)刁俭,使用 CSS 繪制的原本有效區(qū)域未 20 * 10 的箭頭橄仍,結(jié)果卻需要 20 * 20 的區(qū)域,頂上存在了 20 * 10 的無效區(qū)域牍戚。同樣的方式繪制朝右的箭頭侮繁,右側(cè)也會存在相應(yīng)大小的無效區(qū)域
  • 位置和布局。由于上面提到的無效區(qū)域的存在如孝,在管理圖標位置和頁面布局的時候宪哩,往往容易出現(xiàn)一些問題
  • 形狀。這里是繪制的等腰直角三角形第晰,通過改變兩側(cè) border 的寬度锁孟,我們還可以繪制出一般的等腰三角形。但如果要繪制三條邊不一樣長的三角形呢茁瘦?SVG 實現(xiàn)依舊沒有任何困難品抽,而 CSS。甜熔。圆恤。可能需要經(jīng)過繁雜的計算了腔稀。

依照類似的方式盆昙,CSS 還可以利用各種奇怪的方式,繪制出五邊形烧颖、六邊形弱左、五角星等各種典型的圖形窄陡,但是炕淮,其復(fù)雜程度,隨圖形的復(fù)雜程度不停的上升跳夭,在處理不規(guī)則圖形的時候涂圆,特為尤甚。

啥币叹?你說像五角星之類的润歉,頂點數(shù)量太多,也很難染备А踩衩?不好意思,在 PS 的圖層的右鍵菜單上,有一個復(fù)制 SVG 選項驱富,你要不試一試锚赤?

P.S. 相鄰位置上,還有一個復(fù)制 CSS 選項褐鸥,一般情況下线脚,除了復(fù)制陰影效果等,建議還是不要嘗試了叫榕。

四浑侥、維護成本

1. 需求變更

產(chǎn)品和開發(fā)天生是一對冤家。我們沒有辦法保證需求不會變更晰绎,也不可能真讓產(chǎn)品“掃碼改需求”寓落,那么作為開發(fā)我們真的就只能認命?也不全是,我們可以通過調(diào)整自己的開發(fā)模式芯侥,讓需求變更的時候很澄,做出相應(yīng)修改時的時間、人力成本降低考蕾,進而降低項目的維護成本。比如一開始的那條斜線会宪,這次我們需要讓右下角的點不動肖卧,左上角的點向下移動 3 個像素,你可以用 CSS 掸鹅、SVG 都試試怎么實現(xiàn)塞帐。

2. 普適性

還是拿最開始的斜線來說事。CSS 和 SVG 其實代表了兩種不同的處理方式巍沙,CSS ——極坐標系葵姥,SVG 是笛卡爾(直角)坐標系。
大多數(shù)情況下句携,我們拿到的設(shè)計稿榔幸,一般都是基于笛卡爾坐標系的,只有少數(shù)專業(yè)性非常強的領(lǐng)域(如數(shù)學(xué)矮嫉、物理等)才會必須使用類似極坐標系等方式削咆,但這時候,大都會使用更加專業(yè)化的手法蠢笋,而非 CSS拨齐。事實上,SVG 也能很好的處理極坐標系的圖形昨寞,有興趣可以學(xué)一下瞻惋。所以厦滤,在圖形繪制上,SVG 有著 CSS 難以企及的普適性歼狼。

3. 開源項目

事實證明馁害,相比于用 CSS 中各種奇怪的手法,SVG 將更容易與我們的項目相結(jié)合蹂匹,當(dāng)然碘菜,這里說的是圖形繪制。現(xiàn)在限寞,CSS 已經(jīng)有了很多相對成熟的“框架”忍啸,最典型的,莫過于 Bootstrap履植。但是縱觀其功能计雌,更多的是頁面布局、風(fēng)格樣式相關(guān)的功能玫霎,框架內(nèi)部的圖形凿滤,基本都是依賴于其引用的 webfont,而沒有通過 CSS 去 hack庶近。反觀 SVG翁脆,要不你去看一下這個項目 傳送門。CSS 擅長的鼻种,本來就應(yīng)該是各種布局反番、樣式等效果,有時間可以去看一看這個項目傳送門叉钥。個人精力有限罢缸,我這里列舉的可能比較狹隘,大家有興趣可以更多地去關(guān)注一下投队。

4.副作用

使用 CSS hack枫疆,往往會帶來很多的副作用:一開始的斜線,使用 CSS 的時候敷鸦,你去看過它所占的位置么息楔?三角形箭頭的實現(xiàn),也必須占據(jù)更多的位置轧膘;CSS3 中的變形钞螟、旋轉(zhuǎn)等兔甘,都可能會使得元素展示的位置與它實際在文檔流中占據(jù)的位置不符谎碍,這使得我們在維護這樣的代碼的時候,經(jīng)常需要額外的時間和精力洞焙。

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

compatibility-svg.png

不難看出拯啦,比較主流的瀏覽器基本都已經(jīng)實現(xiàn)了對 SVG 的支持,只有 IE8 例外熔任,但實際上褒链,它也可以通過安裝插件的形式實現(xiàn)對 SVG 的支持。

綜上疑苔,我們沒有理由拒絕 SVG甫匹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惦费,隨后出現(xiàn)的幾起案子兵迅,更是在濱河造成了極大的恐慌,老刑警劉巖薪贫,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恍箭,死亡現(xiàn)場離奇詭異,居然都是意外死亡瞧省,警方通過查閱死者的電腦和手機扯夭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞍匾,“玉大人交洗,你說我怎么就攤上這事∠鹗纾” “怎么了藕筋?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長梳码。 經(jīng)常有香客問我隐圾,道長,這世上最難降的妖魔是什么掰茶? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任暇藏,我火速辦了婚禮,結(jié)果婚禮上濒蒋,老公的妹妹穿的比我還像新娘盐碱。我一直安慰自己,他們只是感情好沪伙,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布瓮顽。 她就那樣靜靜地躺著,像睡著了一般围橡。 火紅的嫁衣襯著肌膚如雪暖混。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天翁授,我揣著相機與錄音拣播,去河邊找鬼晾咪。 笑死,一個胖子當(dāng)著我的面吹牛贮配,可吹牛的內(nèi)容都是我干的谍倦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼泪勒,長吁一口氣:“原來是場噩夢啊……” “哼昼蛀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起圆存,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤曹洽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辽剧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體送淆,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年怕轿,在試婚紗的時候發(fā)現(xiàn)自己被綠了偷崩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡撞羽,死狀恐怖阐斜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诀紊,我是刑警寧澤谒出,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站邻奠,受9級特大地震影響笤喳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碌宴,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一杀狡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贰镣,春花似錦呜象、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至上煤,卻和暖如春休玩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工哥捕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘉熊。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓遥赚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阐肤。 傳聞我的和親對象是個殘疾皇子凫佛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容