SVG的正確使用姿式

原文地址: https://css-tricks.com/using-...

原文做者: Chris Coyierphp

翻譯做者: https://github.com/chenmf6css

翻譯出處:https://github.com/lightningm...html

SVG是一種向量圖的圖片格式,即可伸縮向量圖(Scalable Vector Graphics),能夠在Adobe Illustrator裏面生成。在Web中使用SVG很簡單,可是也有一些須要知道的事情。前端

爲何用SVG

  • 壓縮後文件體積小
  • 能夠無損伸縮到任意尺寸(除非尺寸特別小)
  • 在retina屏幕上能夠完美顯示
  • 設計可控,好比交互和濾鏡

怎麼生成SVG

能夠在Adobe Illustrator裏設計而且獲得SVG。下面是一個站在橢圓上的奇異鳥:
image
留意到畫板恰好貼着設計主體的邊緣,畫布的大小在SVG裏面的重要性和在PNG和JPG裏面是同樣的。
而後能夠直接在Adobe Illustrator裏面保存成SVG文件。
imagehtml5

保存的時候,能夠在duihua對話框裏面選擇SVG選項。完整的參考能夠看SVG 介紹。這裏選SVG 1.1就能夠了。
imagecss3

當點擊'OK'或者'SVG Code...'的時候,就會打開文本編輯器,顯示SVG的編碼。
imagegit

<img>標籤裏面使用SVG

若是把SVG保存成文件以後,能夠直接在<img>標籤裏面使用。github

HTML
<img src="kiwi.svg" alt="Kiwi standing on oval">

在Illustrator裏面,畫板的大小是612px ✕ 502px:
image
這正是圖片在頁面中的大小。能夠選擇<img>標籤而且改變widthheight來改變它的尺寸,就像PNG和JPG同樣,好比:web

前往codepen查看
imageshell

瀏覽器支持

<img>標籤裏面使用須要有瀏覽器支持。基本上在IE8以上和Android 2.3以上均可以用。
若是你想要在不支持的瀏覽器裏面使用,能夠這樣:

  1. 使用Modernizr來替換<img>src屬性:
jQuery

if (!Modernizr.svg) {
  $(".logo img").attr("src", "images/logo.png");
}
  1. David Bushell提供了一個更簡單的操做:
HTML

<img src="image.svg" onerror="this.onerror=null; this.src='image.png'">
  1. 使用SVGeezy

background-image裏面使用SVG

能夠在CSS的background-image裏面使用SVG。

HTML

<a href="/" class="logo">
  Kiwi Corp
</a>
CSS

.logo {
  display: block;
  text-indent: -9999px;
  width: 100px;
  height: 82px;
  background: url(kiwi.svg);
  background-size: 100px 82px;
}

注意把background-size設置成咱們想要的尺寸,不然只能看到很大的原始SVG圖片的左上角。這個尺寸設置成了跟原始尺寸保持寬高比,若是在不知道原始尺寸的狀況下想要保持寬高比,能夠把background-size設置成contain

瀏覽器支持

background-image裏面使用SVG也須要看瀏覽器支持,基本上跟在<img>中使用是同樣的。

若是要在不支持的瀏覽器裏面使用:

  1. 用Modernizr把background-image替換成一個支持的格式。它會在不支持SVG的狀況下加上一個no-svg的class,注意它也是隻會發送一個圖片的HTTP請求,不會發兩個。
CSS

.main-header {
  background: url(logo.svg) no-repeat top left;
  background-size: contain;
}

.no-svg .main-header {
  background-image: url(logo.png);
}
  1. 另外一個更方便的方法,就是利用多個背景(background),SVG的瀏覽器支持和多背景的很接近。
CSS

body {
  background: url(fallback.png);
  background-image: url(image.svg), none;
}

使用<img>background-image的問題

<img>background-image裏面使用SVG,無法利用CSS對SVG內部進行控制,因此接着看下面的兩種其餘方式。

使用內聯(inline)SVG

在保存SVG的時候能夠獲取SVG的代碼(也能夠直接在文本編輯器裏面打開SVG文件),直接把SVG的代碼複製到HTML裏面:

HTML

<body>

   <!-- 把SVG的代碼複製到這裏就能夠顯示圖片了  -->

</body>

這樣作的好處是把圖片的內容直接寫在文檔裏面,不須要額外發送HTTP請求獲取,它和使用Data URI的好處是同樣的,壞處也同樣:致使文檔變得臃腫,難以抓取和緩存。

若是使用後端語言的話,能夠獲取文件而且插入到文檔:

PHP

<?php echo file_get_contents("kiwi.svg"); ?>

說到PHP,這裏用file_get_contents()方法比較合適,而不是include()include_once(),由於SVG有時候會以<?xml version="1.0" encoding="UTF-8"?>開頭,致使PHP編譯有問題。

先優化SVG

Adobe Illustrator裏面導出的SVG可能不是最優的,會包含一些冗餘信息,好比DOCTYPE和生成信息。咱們能夠進一步優化,減小體積。Peter Collingridge給出了在線的SVG 優化,把須要優化的SVG上傳,而後下載新的就能夠了。
若是你是硬核玩家,能夠直接用這個NodeJS工具本身優化。

用CSS來控制SVG

SVG的代碼看起來是否是很像HTML?由於它們都是基於XML的。咱們的SVG裏面包含了兩個元素:<ellipse><path>,能夠直接在代碼裏面給它們加上class,就像HTML元素同樣:

SVG

<svg ...>
  <ellipse class="ground" .../>
  <path class="kiwi" .../>
</svg>

而後就能夠用特殊的SVG CSS來控制這些元素了。SVG元素由着特殊的CSS屬性,好比它沒有background-color,而是用fill,可是也可使用一些其餘的普通屬性,好比:hover

CSS

.kiwi {
  fill: #94d31b; 
}
.kiwi:hover {
  fill: #ace63c; 
}

更厲害的是,SVG可使用濾鏡(filter),好比模糊濾鏡。好比在SVG代碼裏面能夠加上一個濾鏡:

SVG

<svg ...>
  ...
  <filter id="pictureFilter" >
    <feGaussianBlur stdDeviation="5" />
  </filter> 
</svg>

而後能夠在CSS裏面使用這個濾鏡

CSS

.ground:hover {
  filter: url(#pictureFilter);
}

下面是一個完整的例子:

前往codepen查看
image

更多閱讀:

瀏覽器支持

內聯SVG的瀏覽器支持看這裏,基本和前面的同樣。兼容的方法:

HTML

<svg> ... </svg>
<div class="fallback"></div>
CSS

.fallback { 
  display: none;
  /* Make sure it's the same size as the SVG takes up */
}
.no-svg .fallback { 
  background-image: url(logo.png); 
}

<object>裏面使用SVG

若是想要經過CSS控制SVG,可是又想避免內聯SVG的弊端,能夠在<object>裏面使用SVG。

HTML

<object type="image/svg+xml" data="kiwi.svg" class="logo">
  Kiwi Logo <!-- fallback image in CSS -->
</object>

一樣可使用Modernizr來兼容:

CSS

.no-svg .logo {
  width: 200px;
  height: 164px;
  background-image: url(kiwi.png);
}

這種狀況下,若是想要用CSS控制SVG,就不能用外部的樣式或者文檔裏面的<style>了,要用SVG文件內部的<style>:

SVG

<svg ...>
  <style>
    /* SVG specific fancy CSS styling here */
  </style>
  ...
</svg>

<object> SVG裏使用外部樣式

能夠在SVG文件開頭的<svg>標籤前面引入:

HTML

<?xml-stylesheet type="text/css" href="svg.css" ?>

若是把這個放在HTML裏面,頁面會崩潰無法渲染,若是把這個放在<img>或者background-image的SVG裏面,頁面不會崩潰,可是也不起做用。

在Data URL裏面使用SVG

還能夠把SVG轉換成Data URL,轉換以後可能不止原來的文件大小,可是它很方便,由於不須要額外產生網絡請求。
Mobilefish.com上面有一個base64在線轉換器,能夠轉成base64編碼,可是這種方式不太推薦。記得去掉換行:
image
它能夠在上述的全部場景裏面使用,除了內聯SVG。

我的比較推薦這個在線轉換器,由於轉換以後可讀性比較強。

  • 用在<img>裏面
HTML

<img src="data:image/svg+xml;base64,[data]">
  • CSS裏面
CSS

.logo {
  background: url("data:image/svg+xml;base64,[data]");
}
  • <object>裏面
HTML

<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]">
  fallback
</object>

若是,SVG在base64編碼以前有嵌套的<style>,那麼它依然能夠在<object>裏面起做用。

Data URI格式

上面的例子都是base64編碼的,可是也不必定要轉換成base64編碼,實際上對於SVG最好不要轉成base64編碼。由於SVG的原始格式文本重複性比較高,gzip壓縮效果更好。

HTML

<!-- base64 -->
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL...

<!-- UTF-8, not encoded -->
data:image/svg+xml;charset=UTF-8,<svg ...> ... </svg>

<!-- UTF-8, optimized encoding for compatibility -->
data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://...'

<!-- Fully URL encoded ASCII -->
data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//...

自動化工具

從CSS的角度來看比較易用,爲每一個icon生成一個class,不用CSS sprites。grunticon輸入一個SVG/PNG文件的目錄,而後輸出對應的3種格式的CSS:SVG data url,png data url和一個引用普通的png圖片的兼容性CSS文件。
一個PHP命令行工具,把SVG圖片轉換成CSS icon,支持圖片優化和SASS輸出。

相關參考

相關文章
相關標籤/搜索