久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用css定義svg的樣式和動畫

 心然之月 2016-05-19

CSS可以用來定義可縮放矢量圖形的樣式和動畫,,就像CSS定義HTML元素一樣,。在本文中,我會告訴大家一些用CSS定義SVG的前提條件和技術(shù),。(我最近在CSSconf EUFrom the Front辦了一個講座,,這篇文章是講座的修正版)

同時我也會講一下導(dǎo)出和優(yōu)化SVG、嵌入SVG和每一個SVG如何影響它的樣式和動畫,,然后我們再討論用CSS定義SVG的樣式和動畫。

介紹

可縮放矢量圖形(SVG)是基于可擴(kuò)展標(biāo)記語言(XML),,用于描述二維矢量圖形的一種圖形格式,,它們支持交互行為和動畫。換句話說,,SVG是可以生成形狀和圖形的XML標(biāo)簽,,這些形狀和圖形可以像HTML元素一樣實(shí)現(xiàn)交互和動畫。

我們可以通過CSS或者Javascript給SVG定義動畫和交互行為,。在本文中,,我們著重討論CSS。

SVG為什么好,?為什么你應(yīng)該使用它,?其實(shí)答案有很多:

  • SVG圖形是可縮放并獨(dú)立于分辨率的,無論是在高分標(biāo)率的“Retina”屏還是印刷媒體,,SVG看上去都很棒,。
  • SVG的瀏覽器支持率很好,對于不支持的瀏覽器,,我們也能很容易的實(shí)施回退,。稍后這篇文章中也會提到。
  • 由于SVG基本上是純文本,它們可以Gzip壓縮,,這樣可以使文件比其他位圖(JPEG或者PNG)更小,。
  • SVG可以通過CSS和Javascript定義交互和樣式
  • SVG自帶內(nèi)置圖形效果,,如裁剪和遮罩,、背景虛化模式和濾鏡,基本上使用SVG就相當(dāng)于在你的瀏覽器中擁有了Photoshop的編輯照片功能,。
  • SVG是可訪問的,。其一,SVG的DOM API使得它們成為制作信息圖表和數(shù)據(jù)可視化最好的工具之一,,此外,,SVG相比HTML5 Canvas來說也更有優(yōu)勢,因?yàn)镠TML5 Canvas是不可訪問的,。其二,,你可以使用你最喜歡瀏覽器的開發(fā)者工具審查SVG的每一個元素,同時,,如果你愿意,,SVG對于屏幕閱讀器也是可訪問的。我們會在這篇文章的最后一個章節(jié)討論一下可訪問性,。
  • 我們可以使用一些工具來創(chuàng)建,、編輯和優(yōu)化SVG,還有一些其他的工具可以使我們更加便捷的操作SVG,,節(jié)省了很多開發(fā)時間,。下面我們也會討論一下這些工具。

從圖形編輯器導(dǎo)出SVG并優(yōu)化

以下是三個最流行的矢量圖形編輯器:

  1. Adobe Illustrator,
  2. Inkscape,
  3. Sketch

Adobe Illustrator是Adobe公司收費(fèi)的應(yīng)用程序,,它是最受歡迎的編輯器,,漂亮的UI和大量的功能使得它成為大多數(shù)設(shè)計師最喜歡的編輯器。

Inkscape是另一個免費(fèi)的編輯器,,雖然它的UI沒有Illustrator漂亮,,但是它仍然具有你所需要的所有功能。

Sketch是只能在Mac OS X上使用的app,,雖然它也要收費(fèi),,但是它在設(shè)計師中到處宣傳并收到了歡迎,最近Sketch又推出了許多資源和工具來改善工作流程,。

你可以選擇任意編輯器來創(chuàng)建你的SVG,。在選擇編輯器、創(chuàng)建SVG之后,,在把它嵌入網(wǎng)頁之前,,你需要把它從編輯器中導(dǎo)出并進(jìn)行清理,。

我會導(dǎo)出并優(yōu)化在Illustrator中創(chuàng)建的SVG,除了Illustrator特定的一些選項(xiàng),,其余步驟跟任何編輯器都基本一致,。

如果要從Illustrator中導(dǎo)出SVG,你需要選擇“File” -> “Save as”,,然后從文件擴(kuò)展名下拉菜單中選擇“.svg”,。一旦你選擇了.svg擴(kuò)展名,會出現(xiàn)一系列導(dǎo)出SVG的選項(xiàng)面板,,比如使用哪個版本的SVG,、是否在圖形中插入圖片或者在外部保存并把它們鏈入SVG、如何為SVG添加樣式(使用展示屬性或者使用CSS的style標(biāo)簽),。

下圖展示了導(dǎo)出SVG的最佳設(shè)置:

導(dǎo)出SVG的最佳設(shè)置

上圖中選項(xiàng)是最佳設(shè)置的原因可以參考Micha?l Chaize的文章:使用Illustrator CC導(dǎo)出SVG,。

無論你使用哪種圖形編輯器,輸出的都不會是優(yōu)化的代碼,。SVG文件,,尤其是從編輯器導(dǎo)出的文件,通常包含了很多多余信息,,比如編輯器的meta信息,、注釋、空白的組,、默認(rèn)值,、非優(yōu)值等,這些信息可以被安全的移除或者轉(zhuǎn)換,,而不會影響SVG的生成,。如果你在使用不是你自己創(chuàng)建的SVG文件,那么代碼基本上都是非優(yōu)的,,所以我們推薦使用獨(dú)立的優(yōu)化工具優(yōu)化它。

這里有些優(yōu)化SVG代碼的工具,。Peter Collingridge的SVG編輯器是一款在線的工具,,你可以直接輸入SVG代碼,或者上傳SVG文件,,然后它會提供一些優(yōu)化的選項(xiàng),,如移除多余代碼、注釋,、空白組,、空格等等。其中有一個選項(xiàng)可以讓你指定點(diǎn)坐標(biāo)小數(shù)的位數(shù),。

SVG編輯器

Peter的優(yōu)化工具也可以自動把inline SVG屬性移動到文檔頭部的style標(biāo)簽中去,,這個工具最好的地方在于,,當(dāng)你點(diǎn)擊某個選項(xiàng)之后,你能實(shí)時看到優(yōu)化的結(jié)果,,這樣你就可以自主決定使用哪種方法優(yōu)化,。某些特定優(yōu)化可能會損壞你的SVG。比如,,通常一位小數(shù)應(yīng)該足夠了,,但是當(dāng)你在使用一個路徑繁多的SVG文件時,如果把小數(shù)的位數(shù)從四削減到一,,你的文件會小掉一半,,但是你的SVG也會損壞,所以能夠預(yù)覽優(yōu)化也是一個很棒的加分點(diǎn),。

Peter的工具是在線的,,如果你喜歡使用離線工具,你可以嘗試SVGO(其中的“O”是“Optimizer”的縮寫),,這是一個基于Node.js的工具,,它有一個漂亮并簡易的拖放GUI。如果你不想要使用在線工具,,它會是一個很好的選擇,。

下面的截圖是用Peter的優(yōu)化工具優(yōu)化之前和之后的SVG代碼:

優(yōu)化之前和之后的SVG代碼

我們可以看到原始文件和優(yōu)化文件大小的變化,此外優(yōu)化的文件更具可讀性,。

在優(yōu)化SVG之后,,可以把它嵌入web頁面,之后用CSS自定義或動畫,。

用CSS定義SVG樣式

HTML和CSS之間的界線很明確:HTML是內(nèi)容和結(jié)構(gòu),,CSS是樣子。而SVG卻模糊了這條界線,。SVG 1.1不要求使用CSS定義SVG標(biāo)簽的樣式——樣式是通過“展示屬性(presentation attribute)”應(yīng)用到SVG元素中去的,。

展示屬性是在元素中設(shè)置CSS屬性的簡寫,可以把它們看成一種特殊的樣式屬性,。

下面的例子是使用展示屬性為一個星形多邊形定義邊框樣式(stroke)和背景顏色(fill):

html <svg xmlns="http://www./2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">   <polygon fill = "#FF931E" stroke = "#ED1C24" stroke-width = "5" points = "279.1,160.8 195.2,193.3 174.4,280.8   117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/> </svg> 

fill,、strokestroke-width屬性都是展示屬性。

在SVG中,,CSS屬性的子集可能是SVG屬性,,反之亦然。SVG規(guī)范羅列了一些可能被設(shè)定為CSS屬性的SVG屬性,,其中一些屬性和CSS共用,,如opacitytransform等,其他一些不是,,如fill,、strokestroke-width等,。

在SVG2中,這個列表包含x,、y,、widthheight,、cx,、cy和一些其他的展示屬性,這些屬性不能在SVG 1.1中通過CSS設(shè)置,。我們可以在SVG 2規(guī)范中找到這些新屬性,。

另一個設(shè)置SVG元素樣式的方法是使用CSS屬性。就像在HTML中一樣,,樣式可以用inline樣式屬性設(shè)置到元素中去:

html <svg xmlns="http://www./2000/svg" version="1.1" style="width: 300px; height: 300px;" viewBox="0 0 300 300"> <polygon   style = "fill: #FF931E; stroke: #ED1C24; stroke-width: 5;"   points = "279.1,160.8 195.2,193.3 174.4,280.8   117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/> </svg> 

樣式也可以使用style標(biāo)簽定義,,style標(biāo)簽可以放在svg標(biāo)簽中:

html <svg xmlns="http://www./2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">   <style type="text/css">   <![CDATA[   selector {/* styles */}   ]]>   </style>   <g id=".."> … </g> </svg> 

你也可以把它放在svg標(biāo)簽外:

html <!DOCTYPE html><!-- HTML5 document --> <html> <head> … </head> <body>     <style type="text/css">     /* style rules */     </style>     <!-- xmlns is optional in an HTML5 document →     <svg viewBox="0 0 300 300">     <!-- SVG content -->     </svg> </body> </html> 

如果你想要把svg跟標(biāo)簽完全分開,你可以使用<?xml stylesheet>標(biāo)簽鏈入外部樣式表,,代碼如下:

html <?xml version="1.0" standalone="no"?> <?xml-stylesheet type="text/css" href="style.css"?> <svg xmlns="http://www./2000/svg" version="1.1" width=".." height=".." viewBox="..">   <!-- SVG content --> </svg> 

樣式層級

我們之前提到展示屬性是一種特殊的樣式屬性,,它們是在SVG節(jié)點(diǎn)上設(shè)置CSS屬性的簡寫,正由于此,,SVG展示屬性也是樣式層級的一種,。

確實(shí),展示屬性只作為低端的“作者樣式表”,,它會被任何其他的樣式定義所覆蓋,,如外部樣式表、文檔樣式表和inline樣式,。

下面的圖表向我們展示了樣式的層級,,下方的樣式表會覆蓋上方的樣式表,你可以看到,,展示屬性樣式會被其他所有的樣式覆蓋,,除了客戶端樣式。

樣式層級

例如,,在下面的代碼片段中描畫了一個SVG圓形元素,,圓形的填充顏色是深粉色,覆蓋了展示屬性中定義的藍(lán)色:

html <circle cx="100" cy="100" r="75" fill="blue" style="fill:deepPink;" /> 

選擇器

大多數(shù)CSS選擇器可以用來選擇SVG元素,,除了一般類型的選擇器:樣式和ID選擇器之外,SVG還可以使用CSS2的動態(tài)偽類選擇器:hover,、:active:focus)和偽元素(例如:first-child,、:visited:link:lang),。剩下的CSS2偽元素,,包括生成內(nèi)容的選擇器(例如::before::after)不在SVG的定義中,,因此對SVG樣式無效。

下面是一個簡單的動畫代碼,,一個深粉色的圓形,,在hover的時候逐漸變成綠色:

css     <style>         circle {             fill: deepPink;             transition: fill .3s ease-out;         }          circle:hover {             fill: #009966;         }     </style> 

我們還可以創(chuàng)造許多更震撼的效果,Iconic有一個很簡單但是很棒的效果,,當(dāng)我們hover在的燈泡上時會點(diǎn)亮燈泡,,我們可以看一下這個demo

注意事項(xiàng)

由于展示屬性是用XML屬性表達(dá)的,,所以它們對大小寫敏感,,例如,當(dāng)我們要定義元素的填充顏色時,,屬性必須寫成fill = "...",,而不能寫成Fill = "..."

此外,,這些屬性的值(例如font-style = "italic"中的italic)也是大小寫敏感的,,必須按照規(guī)范定義中的格式書寫。

其他所有以CSS屬性定義的樣式——無論是inline樣式,,還是在<style>標(biāo)簽中,,或是在外部樣式表中——都是以CSS規(guī)范的語法規(guī)則定義的,通常它們對大小寫不敏感,。話雖如此,,SVG”樣式”規(guī)范建議我們完全按照CSS規(guī)范中定義的屬性名稱書寫,并使用同一種書寫規(guī)范(通常我們使用小寫字母和中劃線),,不要利用CSS忽略大小寫的特點(diǎn)任意書寫,。

用CSS制作SVG動畫

SVG可以做到像HTML元素一樣,用CSS keyframe,、animation屬性或者CSS transition制作動畫,。

多數(shù)情況下,復(fù)雜的動畫效果通常包含了一些變換,,有translate,、rotate、scale和skewing,。

在大多數(shù)情況下,,SVG元素和HTML元素對于transformtransform-origin的解讀是一樣的,然而還是會有一些不可避免的差異,。和HTML元素不同的是,,SVG元素不會被盒模型所局限,因此它就不會有margin,、border,、padding以及content boxes,。

對于HTML元素來說,transform的原點(diǎn)默認(rèn)是(50%,50%),,也就是元素的中心,。然而,SVG元素transform的原點(diǎn)默認(rèn)是用戶當(dāng)前的坐標(biāo)系統(tǒng),,也就是(0, 0),,在canvas的左上角。

假設(shè)這里有一個html元素<div>和一個SVG元素<rect>

html <!DOCTYPE html>     …     <div style="width: 100px; height: 100px; background-color: orange"> </div>     <svg style="width: 150px; height: 150px; background-color: #eee">         <rect width="100" height="100" x="25" y="25" fill="orange" />     </svg> 

如果不改變它們的transform原點(diǎn),,讓它們都旋轉(zhuǎn)45度,,我們可以得到如圖結(jié)果(紅色的小原點(diǎn)就是它們transform原點(diǎn)所在位置):

transform-origin

如果想讓SVG元素在旋轉(zhuǎn)的時候繞著它自己的中心,而不是SVG canvas的左上角,,應(yīng)該怎么做呢,?我們需要明確地設(shè)置transform-origin屬性來確定transform原點(diǎn)。

如何設(shè)置transform原點(diǎn)是很明確的:你設(shè)置的值與元素的border box模型相關(guān),。

在SVG中,,transform原點(diǎn)的值可以是一個百分?jǐn)?shù)或者絕對的數(shù)值(比如像素)。如果transform-origin的值是百分?jǐn)?shù),,那么它的位置就和元素的邊界框有關(guān),。如果它的值是一個絕對的數(shù)值,它的位置就和SVG canvas上用戶的當(dāng)前坐標(biāo)系統(tǒng)有關(guān),。

我們把<div><rect>的transform origin值設(shè)為百分?jǐn)?shù),,就像這樣:

html <!DOCTYPE html>     <style>         div,rect {         transform-origin: 50% 50%;         }     </style> 

那么最終的變換效果是這樣的:

transform-origin

話雖如此,在撰寫本文的時候,,F(xiàn)irefox還無法支持值為百分比的寫法,。這是一個大家熟知的bug,因此最好還是使用絕對數(shù)值,,我們肯定能得到所期待的效果,。當(dāng)然你依然可以選擇在WebKit瀏覽器上使用百分?jǐn)?shù)值。

在接下來的例子中,,我們會使用CSS animation來實(shí)現(xiàn)風(fēng)車效果,。為了使風(fēng)車?yán)@著自己的中心旋轉(zhuǎn),我們會用像素和百分比來設(shè)置它的transform origin,。

html     <svg>     <style>     .wheel {         transform-origin: 193px 164px;         -webkit-transform-origin: 50% 50%;         -webkit-animation: rotate 4s cubic-bezier(.49,.05,.32,1.04) infinite alternate;         animation: rotate 4s cubic-bezier(.49,.05,.32,1.04) infinite alternate;     }      @-webkit-keyframes rotate {     50% {         -webkit-transform: rotate(360deg);         }     }      @keyframes rotate {     50% {         transform: rotate(360deg);         }     }      </style>     <!-- SVG content -->     </svg> 

你可以查看Codepen上的效果,。這里要注意的是,在撰寫此文的時候,,SVG元素上的CSS 3D transformation還不能使用硬件加速,,所以3D的效果跟2D完全一樣,然而,F(xiàn)irefox已經(jīng)能夠一定程度上提升transform的速度,。

為SVG路徑添加動畫

現(xiàn)在還無法用CSS animation將SVG路徑從一個形狀改變成另外一個形狀。如果你想要改變路徑,,也就是從一個動畫過渡到另一個路徑,,必須要用到JavaScript。如果你想要實(shí)現(xiàn)這樣的效果,,我建議你使用Dmitry Baranovskiy寫的Snap.svg,,他還寫了SVG LibraryRapha?l

Snap.svg相對于SVG的地位就好像jQuery相對HTML的地位一樣,,它能讓我們更簡單的處理SVG的一些特殊情況,。

雖然不能用CSS改變形狀,但是你卻可以用CSS來創(chuàng)建一個動態(tài)的畫線效果,。使用animation的時候,,你必須要先設(shè)定線條路徑的總長度,然后用SVG的stroke-dashoffsetstroke-dasharray屬性實(shí)現(xiàn)畫畫效果,。一旦你知道路徑長度,,就可以通過下面的方法來實(shí)現(xiàn)動畫了:

css #path {     stroke-dasharray: pathLength;     stroke-dashoffset: pathLength;     /* transition stroke-dashoffset */     transition: stroke-dashoffset 2s linear; }  svg:hover #path {     stroke-dashoffset: 0; } 

在上面的例子中,當(dāng)hover SVG時,,圖形路徑會在2秒內(nèi)畫好,。

在接下來的演示中,我們將會用到同樣的原理,,再加上CSS的transition延遲,,讓燈泡在路徑動畫完成時點(diǎn)亮。

css #cable {   stroke: #FFF2B1;   stroke-dasharray: 4000 4000;     stroke-dashoffset: 4000;   stroke-width: 4;   transition: stroke-dashoffset 8s linear; }  svg:hover #cable {   stroke-dashoffset: 0; }  /* turn lamp on */ .inner-lamp{   fill:grey;   transition: fill .5s ease-in 6s; }  svg:hover .inner-lamp {   fill: #FBFFF8; } /* … */ 

你可以在JS Bin中查看demo,,提醒大家,,你同樣可以寫成stroke-dasharray: 4000而不是stroke-dasharray: 4000 4000——如果兩個值相同,你可以只定義一個值,。

有時候,,可能你并不能知道動畫路徑的確切長度,這時,,你可以用到JavaScript的getTotalLength()方法來獲取,。

js var path = document.querySelector('.drawing-path'); path.getTotalLength(); //set CSS properties up path.style.strokeDasharray = length; path.style.strokeDashoffset = length; //set transition up path.style.transition = 'stroke-dashoffset 2s ease-in-out'; // animate path.style.strokeDashoffset = '0'; 

上面這個片段是一個非常簡單的例子,它用JavaScript實(shí)現(xiàn)了我們之前用CSS達(dá)到的效果,。

Jake Archibald針對此技術(shù)寫了一篇詳細(xì)的文章,。Jake在文章里寫了一個很棒的交互演示,展現(xiàn)了動畫到底是如何實(shí)現(xiàn)的,,以及這兩個SVG屬性如何共同實(shí)現(xiàn)我們想要的效果,。如果你對這個技術(shù)感興趣,我建議你讀一下他的文章。

SVG的嵌入

一個SVG文件可以通過六種方法嵌入到文檔中,,每一種都有各自的優(yōu)點(diǎn)和缺點(diǎn),。

我們討論嵌入技術(shù)的原因是,你嵌入SVG的方法會影響到一些CSS樣式,、動畫,、交互是否會實(shí)現(xiàn)。

以下為SVG的嵌入方法:

  1. 作為圖片使用<img>標(biāo)簽嵌入:

    <img src="mySVG.svg" alt="" />

  2. 作為CSS中的背景圖片嵌入:

    .el {background-image: url(mySVG.svg);}

  3. 作為對象使用<object>標(biāo)簽嵌入:

    <object type="image/svg+xml" data="mySVG.svg"><!-- fallback here --></object>

  4. 作為框架使用<iframe>標(biāo)簽嵌入:

    <iframe src="mySVG.svg"><!-- fallback here →</iframe>

  5. 使用<embed>標(biāo)簽嵌入:

    <embed type="image/svg+xml" src="mySVG.svg" />

  6. 行內(nèi)使用<svg>標(biāo)簽嵌入:

    <svg version="1.1" xmlns="http://www./2000/svg" …>

    <!-- svg content →

    </svg>

從引入外部SVG文件現(xiàn)在大部分都使用<object>標(biāo)簽,,這個標(biāo)簽最大的好處是在SVG沒有渲染的時候能夠優(yōu)雅降級,,提供圖片(或者文本)。當(dāng)SVG因?yàn)槟承┰驔]有加載時——比如提供的URI錯誤——瀏覽器就會展現(xiàn)<object>起始標(biāo)簽和結(jié)束標(biāo)簽里面的內(nèi)容,。

html     <object type="image/svg+xml" data="mySVG.svg">         <img src="fallback-image.png" alt="…" />     </object> 

如果你想實(shí)現(xiàn)高級的SVG特效,,比如CSS或者scripting,HTML5的<object>標(biāo)簽就是你最好的選擇,。

因?yàn)闉g覽器在用它們各自的方式渲染SVG文檔,,所以可以用iframe來完成嵌入和展現(xiàn)SVG。如果你想要完全將SVG代碼和腳本在主頁面中分離,,這會是一個很好的方法,。然而,用JavaScript控制SVG圖片有點(diǎn)困難,,并且同時還會受到同源策略的限制,。

<iframe>標(biāo)簽就像<object>一樣,當(dāng)瀏覽器不支持SVG或者因?yàn)槟承┰驘o法渲染的時候會提供回退機(jī)制,。

html     <iframe src="mySVG.svg">         <img src="fallback-image.png" alt="…" />     </iframe> 

<embed>標(biāo)簽不是HTML規(guī)范的一部分,,卻仍然得到了廣泛的支持,它用來囊括需要外部插件才能工作的內(nèi)容,。Adobe公司的Flash插件就需要用到<embed>標(biāo)簽,,支持這個標(biāo)簽為唯一原因是為了使用SVG,<embed>標(biāo)簽沒有默認(rèn)回退機(jī)制,。

SVG也能使用<svg>標(biāo)簽inline嵌入到文檔中——作為一個”代碼塊”,,這是當(dāng)下嵌入SVG最主流的方法之一。使用inline的SVG和CSS會比較容易,,因?yàn)闊o論樣式規(guī)則放置在頁面的哪個位置都可以輕松定義SVG的樣式和動畫,。也就是說,樣式不需要包含在<svg>標(biāo)簽里,,這對于其他技術(shù)來說這也是很必要的,。

inline嵌入SVG是一個很好的選擇,只要你愿意增加頁面的尺寸,,并且放棄它向下兼容性(因?yàn)樗鼪]有默認(rèn)回退機(jī)制),。要注意的是,,inline嵌入SVG不能緩存。

在定義CSS樣式和動畫的時候,,用<img>標(biāo)簽和作為CSS背景圖片嵌入SVG很類似,。一旦嵌入了SVG,外鏈的CSS資源中的樣式和動畫不會被保留,。

下面的表格展現(xiàn)了用六個不同的方法嵌入SVG時,,CSS動畫和交互(比如hover效果)是否會被保留。最后一列是將它與SMIL animations比較,,無論哪種情況, SVG animations (SMIL) 都支持,。

  CSS交互 (例如:hover) CSS動畫 SVG動畫 (SMIL)
<img> 是 只在<svg>
CSS背景圖片 是 只在<svg>
<object> 是 只在<svg> 是 只在<svg>
<iframe> 是 只在<svg> 是 只在<svg>
<embed> 是 只在<svg> 是 只在<svg>
<svg>(inline)

表格展示了當(dāng)SVG嵌入時,,CSS樣式、動畫和交互是否會被保留

以上表格中都是標(biāo)準(zhǔn)行為的,,然而,,在每個瀏覽器中實(shí)現(xiàn)效果可能有差異,也可能存在bug,。

這里要注意的是,,即使SMIL animations會被保留,但在SVG被當(dāng)做圖片嵌入的時候(比如<img>或者CSS背景圖片),,SMIL的交互效果也是沒有的,。

讓SVG響應(yīng)化

在嵌入SVG之后,你需要保證它是響應(yīng)的,。

根據(jù)你選擇的嵌入技術(shù),,你需要應(yīng)用一些特定的hack使得你的SVG是跨瀏覽器響應(yīng)的,這是由于每個瀏覽器判定SVG的尺寸都不同,,每個瀏覽器中SVG的實(shí)施方法也不同,。因此,SVG的操作方法不盡相同,,我們需要調(diào)整一些樣式讓SVG一直能跨瀏覽器響應(yīng),。

我不會過多贅述瀏覽器矛盾,我只會簡單介紹一下讓SVG響應(yīng)式所需的調(diào)整和hack,。如果你想要了解瀏覽器矛盾和bug,,可以看一下我在Codrops上的文章

無論你選擇什么技術(shù),,第一步要做的事情就是從<svg>元素中刪除heightwidth屬性,。

你需要保留viewBox屬性,并把preserveAspectRatio屬性設(shè)為xMidYMid meet,,記住如果preserveAspectRatio的值已經(jīng)默認(rèn)為xMidYMid meet的話就不需要特意設(shè)置了,。

當(dāng)SVG作為CSS的背景圖片嵌入時,不需要額外的調(diào)整或者h(yuǎn)ack,SVG會表現(xiàn)的和其他位圖背景圖片一模一樣,。

在所有瀏覽器中,,如果SVG是通過<img>標(biāo)簽嵌入的話,SVG會自動拉伸到容器寬度(當(dāng)然是在刪除<svg>標(biāo)簽上的寬度值之后),,然后它會按照預(yù)期伸縮,,在除了IE之外的所有瀏覽器中自適應(yīng)。IE會把SVG的高度設(shè)為150像素妨礙正確的伸縮,。為了解決這個問題,,你需要把<img>的寬度設(shè)為100%。

html <img src="mySVG.svg" alt="SVG Description." /> img {   width: 100%; } 

這同樣也適用于<object>標(biāo)簽嵌入,,出于同樣的原因考慮,,你也需要設(shè)置<object>標(biāo)簽的寬度為100%:

css object {   width: 100%; } 

即使<iframe><object>有很多相同之處,瀏覽器也會分別對待,。所有瀏覽器會默認(rèn)設(shè)置CSS中替換元素的尺寸為300*150像素,。

保持SVG寬高比同時讓iframe響應(yīng)式的唯一方法,是使用由A List Apart的Thierry Koblentz首創(chuàng)的“padding hack”,。padding hack的思路是利用元素padding和寬度的關(guān)系,,來創(chuàng)建一個寬高比固定的元素。

當(dāng)一個元素的padding值設(shè)為百分比,,這個百分比會根據(jù)元素的寬度來計算,,即使你設(shè)置的是元素的padding-toppadding-bottom

為了應(yīng)用padding hack并使SVG響應(yīng)化,,SVG需要被裝在一個容器中,,然后你需要在容器和SVG(例如iframe)中添加樣式。

html     <!-- wrap svg in a container -->     <div class="container">         <iframe src="my_SVG_file.svg">         <!-- fallback here -->         </iframe>     </div>  .container {   /* collapse the container's height */   height: 0;            /* specify any width you want (a percentage value, basically) */        width: width-value;        /* apply padding using the following formula */   /* this formula makes sure the aspect ratio of the container equals that of the SVG graphic */   padding-top: (svg-height / svg-width) * width-value;   position: relative;    /* create positioning context for SVG */ } 

svg-heightsvg-width變量分別是<svg>的高度和寬度值——就是我們之前刪除的尺寸,。width-value是你想要設(shè)置的任何SVG容器寬度,。

最后,SVG自身(iframe)需要在容器中絕對定位:

css iframe {   position: absolute;   top: 0;   left: 0;   width: 100%;   height: 100%; } 

我們把iframe絕對定位的原因是合并容器的高度再加上padding會導(dǎo)致iframe超出容器邊界,。所以,,“為了把它拉回來”,我們把它絕對定位,。欲知詳情,,請看我Codrops上的文章

最后,,當(dāng)我們把高度和寬度刪除之后,,<svg>標(biāo)簽里的SVG會響應(yīng)化,因?yàn)闉g覽器會假定一個100%的寬度,,使得SVG按照這個寬度伸縮,。然后,,IE會像我們之前提到的<img>標(biāo)簽一樣,有一個150像素的固定高度,。不幸的是,,把SVG的高度設(shè)為100%對這個bug無用。

為了讓SVG在IE中自適應(yīng),,我們也需要添加padding hack,。所以,我們在<svg>標(biāo)簽外套一個容器,,在容器中添加padding hack,,最后讓<svg>絕對定位,這里唯一的不同是,,我們不需要設(shè)定<svg>的寬高,。

css svg {   position: absolute;   top: 0;   left: 0; } 

使用CSS媒體查詢

SVG也會接受并相應(yīng)CSS媒體查詢。你可以使用媒體查詢來告便SVG在不同viewport下的樣式,。

然后這里有個很重要的注意事項(xiàng),SVG相應(yīng)地viewport是SVG本身的viewport,,不是頁面的viewport,!

這跟元素查詢的概念很像。

當(dāng)SVG插入<img>,、<object><iframe>中時,,它響應(yīng)的是這些元素建立起來的viewport。也就是說,,這些元素的尺寸會生成描繪SVG的viewport,,也會生成CSS媒體查詢條件應(yīng)用的viewport。

下面這個例子展示了包含媒體查詢的SVG,,SVG指定為<img>標(biāo)簽:

html <svg xmlns="http://www./2000/svg" version="1.1" viewBox="0 0 194 186">   <style>     @media all and (max-width: 50em) {       /* select SVG elements and style them */     }      @media all and (max-width: 30em) {       /* styles  */     }   </style>   <!-- SVG elements here --> </svg> 

當(dāng)<img>max-width50em或者30em時,,SVG會應(yīng)用媒體查詢中的樣式。

html <img src="my-logo.svg" alt="Page Logo." /> 

如果你想了解更多SVG中的媒體查詢,,你可以看一下Dev.Opera中Andreas Bovens的文章,。

最后的話

SVG是圖片,就像圖片有可訪問性一樣,,SVG也有,,你需要保證你的SVG具有可訪問性。

我還是要再強(qiáng)調(diào)一遍:讓你的SVG具有可訪問性,,你有很多種方法實(shí)現(xiàn),,如果你想要一個全面的概覽,我推薦SitePoint上Leonie Watson的文章,,她提出一些很好的方法,,比如在<svg>中使用<title><desc>標(biāo)簽,、使用ARIA屬性等。

除了可訪問性,,不要忘記優(yōu)化你的SVG,,為不支持的瀏覽器提供回退。我推薦Todd Parker的演講,。

最后,,你可以在caniuse上查看不同SVG特性的支持情況。我希望你覺得我這篇文章對你有用的,,感謝你的閱讀,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多