SVG 和設計工具實用指南

已發表: 2022-03-10
快速總結 ↬要充分利用 SVG,不僅要學習其語法,還要了解圖形設計軟件如何生成 SVG。 讓我們仔細看看使用流行的設計應用程序生成 SVG 的過程,以及我們如何利用它們來發揮自己的優勢。

對 SVG 有很好的理解是一項難得的技能。 令人驚訝的是,SVG 通常被視為另一種圖像格式。 我們使用 SVG 是因為它的可擴展性和更小的文件大小,但實際上,SVG 遠不止這些!

在本文中,我將介紹三種最流行的設計工具:Adobe Illustrator、Sketch 和 Figma。 還有其他可用的工具支持 SVG,它們可能具有其他功能並實現其他解決方案。

如無特別說明,本文內容均指SVG 1.1 2nd Edition。 下面討論的一些要點不適用於 SVG 2,但是,它仍然沒有達到推薦狀態,使 SVG 1.1 成為最新的規範。

為什麼要為設計工具煩惱?

SVG 是一種基於 XML 的標記語言,並且與任何其他編程語言一樣,可以在文本編輯器中編寫和編輯。 所以理論上,相對於 JPG 或 PNG 文件,我們不需要任何 GUI 軟件來創建 SVG。 但是,在絕大多數情況下,使用圖形設計應用程序是不可避免的。

以基於文本的格式處理複雜的形狀和圖形是完全可能的,但通常會非常棘手和乏味。 因此,通常的做法是使用 Adob​​e Illustrator、Sketch 或 Figma 等應用程序直觀地設計圖形,然後將它們導出為 SVG 格式。

因此,無論您是編碼設計師還是有設計意識的開發人員,要熟練使用 SVG 都需要雙方的一些知識:設計工具和 SVG 語言本身。 為了更好地理解兩者之間的關係,讓我們仔細看看圖形設計應用程序必須提供什麼以及它們的功能如何轉化為 SVG。

跳躍後更多! 繼續往下看↓

基本形狀

許多矢量圖形是由幾個基本形狀組成的——分組、轉換和相互組合。 下表顯示了 Illustrator、Sketch 和 Figma 中可用的形狀工具以及它們導出為哪些 SVG 元素。

插畫家草圖無花果生成的 SVG
橢圓工具橢圓形橢圓<circle /><ellipse />
矩形工具長方形長方形<rect />
圓角矩形工具圓形- <rect rx="…" />
線段工具<line /> (Illustrator 和 Figma) <path /> (素描)
-<path />
多邊形工具多邊形多邊形<polygon /> (Illustrator 和 Sketch) <path /> (Figma)
星形工具星星星星<polygon /> (Illustrator 和 Sketch) <path /> (Figma)
- 三角形- <polygon />

橢圓和圓

每個設計工具中的基本形狀之一是橢圓。 在 SVG 中,我們會找到一個匹配的<ellipse />元素,它由橢圓中心的坐標( cxcy )和兩個半徑( rxry )定義。

這是 SVG 中橢圓的樣子:

 <ellipse cx="400" cy="300" rx="250" ry="150"/>
SVG 橢圓
SVG 橢圓(大預覽)

非常特殊的橢圓類型是圓形。 圓是rxry半徑彼此相等的橢圓。 SVG 有自己的<circle />元素,它少了一個屬性,因為只有一個半徑需要考慮:

 <circle cx="400" cy="300" r="250"/>
SVG 圓圈
SVG 圓(大預覽)

在橢圓和圓形的情況下,所有設計工具的工作方式都是一樣的:Illustrator 中的Ellipse Tool 、Sketch 中的Oval工具和 Figma 中的Ellipse工具都會生成<ellipse />元素,除非半徑相等:在這種情況下,我們最終會得到<circle />元素。

矩形和圓角矩形

所有設計工具共有的另一個基本形狀是矩形。 在所有設計工具的情況下,使用矩形工具會在 SVG 中生成<rect />元素。 一個基本的<rect />由 4 個屬性定義:它的xy坐標,以及它的寬度和高度:

 <rect x="150" y="100" width="500" height="400"/>
SVG 矩形
SVG 矩形(大預覽)

請注意,雖然<ellipse /><circle />的位置是由它們的幾何中​​心定義的,但<rect />的位置是由其左上角的坐標定義的。

除了基本的矩形,我們經常使用圓角矩形。 在所有三個設計工具中,您可以通過在InspectorProperties面板中應用邊框半徑來將矩形變成圓角矩形。

此外,在 Sketch 和 Illustrator 中,有專門用於創建圓角矩形的工具(Illustrator 中的圓角矩形工具和 Sketch 中的圓角工具)。 但是,應用了半徑的常規矩形與使用圓角矩形工具繪製的圓角矩形之間沒有區別。

因此,無論如何創建,都將使用以下語法導出圓角矩形:

 <rect x="150" y="100" width="500" height="400" rx="30"/>

在這種情況下, rx是負責圓角半徑的屬性:

SVG圓角矩形
SVG 圓角矩形(大預覽)

帶橢圓角的圓角矩形

設計工具和 SVG 之間的一個顯著區別是如何定義半徑。 在我們考慮的所有設計工具中,邊界半徑由單個變量定義。 我們可以將邊框半徑視為用於掩蓋矩形角的小圓圈:

SVG中的圓角
SVG 中的圓角(大預覽)

同時,在 SVG 中,邊框半徑可以由兩個屬性定義: rx (如上例)和ry 。 它們允許我們創建帶有橢圓角的矩形。 您可以將這樣的圓角視為用作蒙版而不是圓形的橢圓:

 <rect x="150" y="100" width="500" height="400" rx="40" ry="30"/>
SVG中的橢圓角
SVG 中的橢圓角(大預覽)

因此,在這種情況下,SVG 為您提供了比設計工具更多的可能性。

注意儘管它與本文的主題並不完全相關,但值得注意的是,上述差異適用於 SVG 和 HTML/CSS。 CSS 屬性border-radius用於設置節點的樣式,例如 div 和 spans 也允許創建橢圓角。 您可以在下面看到一個示例。

 border-radius: 10px 5% / 20px 25em 30px 35em;

斜線 ( / ) 之前的值是水平半徑(相當於rx ),斜線之後的值是垂直值(相當於ry )。

具有多個半徑的圓角矩形

在設計工具中,與在 CSS 中一樣,可以單獨控制矩形的每個角。 換句話說,每個角都可以有自己的半徑(或完全沒有半徑)。 SVG 中的<rect />元素無法進行此類操作。 每個<rect />元素只有一個rx和一個ry屬性。 如果您創建一個矩形,其角應用了多個半徑,則設計工具將生成<path />元素而不是<rect />元素。 我們將在下一節中更多地討論<path />元素。

光滑的角落

Sketch 和 Figma 不久前引入的有趣功能之一是平滑角。 簡而言之,平滑的角落使用不規則的邊界半徑來實現看起來更自然且平滑的結果。 圓角最常見的應用是 iOS 上的應用圖標和其他圓角元素。 在 iOS6 之前,Apple 在其移動平台上使用“常規”圓角,然後在 2013 年 (iOS7) 推出的大規模重新設計中切換到我們今天所說的“平滑”角。

圓角和圓角的區別
圓角和平滑角之間的區別(大預覽)

在 Sketch 中,您可以通過在Inspector中切換圓角平滑角來實現平滑角效果。 Figma 讓您可以更好地控制拐角,因為您可以在“拐角平滑”菜單中操作平滑度。

不幸的是,這些都不能輕鬆轉換為 SVG,因為 SVG 根本不知道平滑角的概念。 如果您嘗試將具有平滑角的矩形導出到 SVG,Sketch 和 Figma 之間的操作還有一個重要區別。

Figma 會忽略平滑的角,並將矩形導出為具有圓角的常規<rect />元素。 另一方面,Sketch 將一個具有平滑角的矩形導出為<path /> ,它試圖複製平滑角的真實形狀。 因此 Figma 為我們提供了更差的準確性,以保持矩形為矩形,而 Sketch 則以語義和更大的文件大小為代價,以盡可能高的準確性為目標。 如果您想更好地了解這種差異意味著什麼,稍後我們將深入探討保留基本形狀的利弊。

線條

下一個基本類型的元素是線。 在這種情況下,我們將一條線稱為從 A 點到 B 點的一條直線。Illustrator、Sketch 和 Figma 都提供了自己的線條工具,專門用於繪製線條。 在 SVG 中,我們有一個<line />元素。 它的四個屬性是必需的:起點坐標和終點坐標:

 <line x1="100" y1="100" x2="200" y2="200"/>
SVG線
SVG 線條(大預覽)

在導出時,Illustrator 和 Figma 將盡可能將線條導出為<line />元素,而 Sketch 將始終將線條計算為<path />元素。

折線

現在讓我們來看看折線。 折線是一系列相連的直線。 折線在設計工具中沒有專用工具。 它們可以使用鋼筆工具(在 Illustrator 和 Figma 中)或使用矢量工具(在 Sketch 中)繪製。

在 SVG 中,折線是用<polyline />元素定義的。 <polyline />使用points屬性繪製,該屬性是定義創建折線的所有點的坐標列表。 讓我們看一個由三段和四個點組成的折線示例:

 <polyline points="10,20 10,20 30,10 40,20" />
折線
(大預覽)

Illustrator 和 Sketch 將折線轉換為<polyline/>元素,而 Figma 將折線導出為<path /> s。

箭頭

在所有三個工具中,您都可以控制線條的末端將它們變成箭頭等。 並且所有三個工具都會將這樣的線條導出為<path /> s,即使沒有應用帽子,相同的形狀也會被轉換為<line /> s 或<polyline /> s。 是因為 SVG 不支持箭頭嗎? 不完全是。

實際上,SVG 規範確實包括可定制的線端,稱為標記。 但是,我們提到的設計工具都沒有在它們生成的 SVG 中使用標記。

<marker>是一個單獨的 SVG 元素,可以在 SVG 的<defs>中定義,然後用於具有標記屬性的<line><polyline><path>元素: markermarker-startmarker-midmarker-end . 如果您想了解有關這些屬性的更多信息,我建議您查看官方 W3C 文檔。

多邊形和星星

我們要看的最後一個基本形狀是多邊形。 多邊形是由直線組成的封閉形狀,例如星形或六邊形。 您也可以將其視為閉合的折線。 SVG 中<polygon />元素的語法實際上與<polyline />相同。 兩者之間的唯一區別是,在<polygon />列表中的最後一個點始終與第一個點連接,以使<polygon />成為一個封閉的形狀。

SVG 多邊形
SVG 多邊形(大預覽)

一些多邊形是正多邊形。 正多邊形的特別之處在於它們的所有邊和角都相等。 要繪製正多邊形,例如六邊形或五邊形,您可以使用多邊形工具,在 Illustrator、Sketch 和 Figma 中相同。 Illustrator 和 Sketch 中的多邊形工具將在 SVG 中生成<polygon />元素。 另一方面,在 Figma 中,所有使用多邊形工具製作的形狀都會產生<path />元素。

這三個設計工具也都有專門的星形工具來繪製星形。 但是,在導出時,使用星形工具創建的形狀與使用多邊形工具創建的形狀完全相同。 在 SVG 中,星星只是多邊形,沒有~~<star />~~元素。

重要的是要記住StarPolygon工具用於創建規則的星星和多邊形,而 SVG 中的<polygon />元素可用於任何多邊形,規則的或不規則的。

條條大路通<path />

正如我們已經了解到的,在 SVG 中,有三種基本形狀專門用於繪製由直線構成的形狀: <line /><polyline /><polygon /> 。 但是如果我們希望我們的線條是彎曲的呢? 現在是我們談論<path />元素的時候了。

<path />元素

<path />是最通用的 SVG 元素。 它可用於繪製任何可能的線條和形狀,包括但不限於上面列出的所有基本形狀。 事實上,每個基本形狀( <circle/><ellipse /><rect /><line /><polyline /><polygon /> )都可以描述為一個<path />元素。 更重要的是,有許多形狀可以用<path />創建,但不能用任何其他 SVG 元素創建。 要了解有關<path />及其語法的更多信息,我建議您查看 Chris Coyier 撰寫的這篇出色的文章。

現在,我們如何在設計工具中創建<path />元素? 首先,正如我們在上面了解到的,使用形狀工具創建的一些層計算為<path />元素,即使它們理論上可能是其他元素(例如 Figma 將所有多邊形導出為<path /> s,即使它們可能是定義為<polygon /> s。然後,我們使用鋼筆工具或矢量工具繪製的所有其他不規則形狀都必須導出為<path /> ,因為沒有其他 SVG 元素可以定義它們。最後,在 Sketch 和 Figma 中,我們可以將任何基本形狀轉換為計算為<path />的層。在 Sketch 中,我們可以通過選擇Layer > Combine > Flatten來完成此操作,而 Figma 我們可以在Object > Flatten Selection ( + E下找到此功能在 macOS 上,在 Windows 上為Ctrl + E )。

布爾運算

布爾運算是對形狀執行的函數,以幾種不同的方式組合它們。 在 Illustrator、Sketch 和 Figma 中,有 4 種標準布爾運算:

  • 聯盟(聯合)
    形狀的總和
  • 減法(減去前面)
    底部形狀減去形狀之間的公共區域
  • 相交
    形狀之間的公共區域
  • 差異(排除)
    形狀的總和減去形狀之間的公共區域。

在 Illustrator 中,所有這些功能都會生成一個形狀(輪廓)。 這是一個無法撤消的操作——除非使用撤消(在 macOS 上為 + Z ,在 Windows 上為Ctrl + Z )。 另一方面,在 Sketch 和 Figma 中,布爾運算會創建圖層組,這些圖層組可以在以後取消分組,而不會對內部形狀造成任何損害。 但是,您可以將這些組合併為一個形狀,以獲得與在 Illustrator 中使用上一段中提到的展平功能類似的結果。

問題是,SVG 是否支持布爾運算? 不,它沒有。 他們只是合併。 因此,您在 Figma 或 Sketch 中使用布爾運算創建的每個組合形狀都將導出為單個<path />元素。

看起來一樣,那麼為什麼重要?

就如何在 SVG 中定義不同的形狀而言,它的語法非常通用。 讓我們考慮一個基本的矩形:

無非是一個長方形
只不過是一個矩形(大預覽)

這種形狀可以在 SVG 中以幾種不同的方式定義。 它可以是一個<rect />元素,一個<polygon />元素。 它絕對可以是一個<path />元素(因為一切都可以是一個<path />元素)。 如果我們決定使用筆觸而不是填充來創建它,它也可以是<line />元素(或<polyline />元素)。

這些元素中的每一個都呈現一個看起來完全相同的矩形:

長方形<rect width="2" height="3" fill="black"/>
多邊形<polygon points="0,0 2,0 2,3 0,3" fill="black"/>
<line x1="1" y1="0" x2="1" y2="3" stroke="black" stroke-width="2"/>
小路例如<path d="M0,0 l2,0 l0,3 l-2,0" fill="black"/><path d="M1,0 l0,3" stroke="black" stroke-width="2"/>

但是,如果最終結果(用戶代理在瀏覽器中呈現的圖形)看起來相同,那麼我們選擇哪種方法真的很重要嗎? 嗯,確實如此。 根據經驗,我總是建議盡可能使用基本形狀。

最後但並非最不重要的一點是,在給定的情況下使用最明顯的形狀。 例如,如果您沒有充分的理由,請不要使用直線創建矩形或使用矩形創建圓形。 這背後至少有幾個論點:

  1. 語義/可讀性
    壓縮工具(例如 SVGO)為您提供了計算路徑元素的所有基本形狀的選項。 它可以為您節省一些時間,但肯定會降低代碼的可讀性。 <path />語法非常不直觀,因此如果您的 SVG 將在代碼編輯器而不是設計工具中進行修改,如果您將基本形狀保留為基本形狀,那麼它會更容易理解。
  2. 文件大小
    將形狀壓縮到路徑可能會幫助您縮小文件,但並非總是如此! 例如,圓角矩形作為<path />比作為<rect />佔用更多空間。
  3. 動畫
    您是否嘗試過為 SVG 設置動畫? 這很有趣——只要你在乾淨、語義化的 SVG 上進行操作。 使用基本形狀,您可以輕鬆地操作點的半徑、寬度、高度或位置等參數。 如果您將形狀合併到路徑中,大多數這些操作將更難實現或根本不可能。
  4. 變體/響應性
    請記住,SVG 不是 JPG 等靜態圖像。 您可以對其進行樣式設置、主題化、使其具有響應性等等。 與動畫一樣,保持文件結構良好且語義清晰肯定會幫助您完成任何這些任務。

與每條規則一樣,您可以找到一些例外情況。 但是,一般來說,保持 SVG 的可讀性、靈活性和結構化是一種很好的做法。

現在,讓我們看看其他屬性和特性,例如 viewBox、組、變換和視覺效果。

widthheightviewBox

如果您已經對 SVG 有一定的經驗,您可能會注意到開始<svg>標籤通常具有以下屬性: widthheightviewBox 。 在設計工具中,我們有畫板(或 Figma 的框架)的尺寸。 那麼這些值究竟是如何相互關聯的呢?

讓我們從解釋我們剛剛提到的<svg>屬性開始。 您可以將viewBox視為坐標系形式的虛擬畫布。 該坐標系的中心位於指定區域的左上角。 <svg viewBox="…">標籤內的所有項目都根據這個坐標系放置並被它剪裁——任何溢出viewBox的東西都不會被渲染。 viewBox接受 4 個數字作為其值:

 <svg viewBox="0 0 12 8"> … </svg>
SVG 中的 viewBox 模型
SVG 中的viewBox模型(大預覽)

由於 SVG 代表Scalable Vector Graphics,因此這些數字不需要單位。 把它想像成一個可以放大和縮小到任意大小的抽象坐標系。 不要太擔心前兩個數字,很可能你不需要它們。 後兩者通常很重要。 這些是我們的 SVG 畫布的實際尺寸。

viewBox不能確定 SVG 的大小。 它只是指定了繪製 SVG 的區域的坐標。 因此,當在 web 上使用時,帶有指定viewBox<svg>將始終佔用所有可用空間並保留viewBox設置的比例——除非我們用 CSS 阻止這種情況或設置width和/或height屬性。

widthheight是設置 SVG 元素的實際寬度和高度的<svg>屬性。 與viewBox相反,它們應該使用指定的單位,例如像素、ems 或 rems。 這意味著我們也可以用它們轉換height width viewBox width height viewBox的圖形:

viewBox 的縱橫比是 3:2 但它的 width 和 height 屬性使其顯示為正方形
viewBox的縱橫比是 3:2,但它的 width 和 height 屬性使其顯示為正方形。 (大預覽)

現在,當我們從設計工具導出 SVG 時會發生什麼? 在 Sketch 和 Figma 中,所有資源(無論它們是單層、組還是畫板)總是會得到一個等於導出元素的尺寸和以像素為單位設置的widthheightviewBox ,等於最後兩個值viewBox 。 在 Illustrator 中,所有資源都有一個viewBox ,指定方式與 Sketch 和 Figma 中相同,但沒有應用widthheight

團體

組是在設計工具中組織層的基本手段。 除了設置層次結構外,組還用於將批量操作(例如轉換)應用於多個元素。 群組在 Illustrator、Sketch 和 Figma 中的工作方式沒有顯著差異,幸運的是,SVG 群組 ​​( <g>…</g> ) 的基本功能幾乎相同。

變換

在 SVG 中,我們可以對元素應用五種基本變換:

  1. translate :沿垂直和/或水平軸移動元素;
  2. scale :沿垂直和/或水平軸縮放元素:
  3. rotate :圍繞給定點以度數指定的給定角度創建二維旋轉;
  4. skewskewXskewY ):沿垂直或水平軸以度數指定的給定角度傾斜元素;
  5. matrix :最複雜和最通用的可用變換函數。 由於解釋矩陣變換的工作原理需要大量的代數討論,因此它遠遠超出了本文的範圍。 讓我們承認matrix允許您執行許多複雜的變換,例如拉伸、擠壓、剪切等。

注意請注意,儘管某些 SVG 變換看起來與 CSS 變換非常相似,但它們並不相同。 例如,CSS 提供 2D 和 3D 旋轉功能,而 SVG 只有一個 2D 旋轉功能。 此外,雖然 CSS 接受各種角度單位,例如度或弧度,但 SVG 旋轉始終以度為單位設置,因此可以省略單位(例如rotate(45)NOT ~~rotate(45deg)~~ )。

所有這些變換都可以應用於任何 SVG 元素,例如形狀或組,並且是非破壞性的,即不會影響元素的原始幾何形狀。 我們通過一個transform屬性應用變換:

 <g transform="scale(3) rotate(90) translate(50,100)"> … </g>

現在讓我們來看看設計工具吧! 因此,我們在設計工具中應用的大多數變換都直接與對象的幾何形狀及其在畫布上的位置交互。 它們不獨立於形狀,也不會作為 SVG 變換函數導出。

旋轉在這裡是個例外,它們的值與元素的幾何圖形分開存儲在檢查器中,並且它們確實導出為transform="rotate(…)"函數。

有趣的是,同樣的規則適用於 Sketch 和 Figma 中的翻轉(反射)(不在 Illustrator 中!)。 不過,他們每個人都有自己的方法。 Sketch 使用負縮放和平移的組合來實現翻轉效果,而 Figma 在單個矩陣函數中執行翻轉。

邊界半徑

我們已經談到了圓角矩形,但是如何將其他形狀弄圓呢? 事實上,在我們討論的所有設計工具中,您可以將任何形狀的角弄圓,而不僅僅是矩形。

但是 SVG 呢? <polygon /><path />元素也有rxry屬性嗎? 很不幸的是,不行。 矩形以外的任何形狀,一旦你將它的任何角弄圓,將始終作為<path />元素導出,將圓角視為形狀幾何圖形的一個組成部分。

填充和描邊

Illustrator、Sketch 和 Figma 都支持填充和描邊作為任何形狀的基本屬性,SVG 中也是如此。 因此,在設計工具中指定的填充在fill屬性中導出,而描邊在stroke屬性中導出。 不要認為這一切都那麼簡單。 細節決定成敗。

顏色填充

顏色填充是最基本的可用填充,並指定為單一純色(例如#3fd8e2 )。 在 SVG 中,該值直接放在fill屬性中(例如fill="#3fd8e2" )。

設計工具使用十六進制值(例如#0000ff )導出顏色填充,儘管在 SVG 中,您也可以使用 CSS 已知的所有其他命名方案,例如顏色名稱(例如blue )、RGB 值(例如rgb(0,0,255) ) 甚至 HSL 值(例如hsl(240,100%,50%) )。

填充不透明度

當涉及到填充不透明度時,SVG 接受半透明顏色(例如 RGBA 值),儘管它也提供了一個fill-opacity屬性。 由於兼容性問題,推薦使用fill-opacity的方法,它也是 Figma 和 Sketch 使用的方法。 (我在這裡沒有提到 Illustrator,因為 Illustrator 不允許您控制填充不透明度。)因此,如果您想創建一個填充有半透明紅色的 SVG 正方形,您可以執行以下操作:

 <rect width="100" height="100" fill="rgba(255,0,0,0.5)" />

但更推薦的方法(由 Sketch 和 Figma 使用)是:

 <rect width="100" height="100" fill="#ff0000" fill-opacity="0.5" />

漸變填充

如果您熟悉 CSS,您可能知道在背景方面,顏色和漸變背景之間的切換相對簡單。 在這兩種情況下都可以使用相同的background-color (或background )屬性。 由於 SVG 中的漸變比 CSS 漸變更古老,它們的語法也大不相同。

要使用漸變是 SVG,您首先需要在<defs>…</defs>標記中定義它,然後在fill屬性中引用它,例如:

 <defs> <linearGradient> <stop stop-color="red" offset="0%"></stop> <stop stop-color="blue" offset="100%"></stop> </linearGradient> </defs> <rect fill="url(#myGradient)" />

因此,當您使用漸變填充時,在 SVG 導出期間發生的情況是漸變被添加到<defs>並且在下面的代碼中被引用。

要記住的重要一點是 SVG 僅支持線性和徑向漸變。 角度漸變或漸變網格等效果不會導出到 SVG。

圖案/圖像填充

Sketch 和 Figma 還提供圖像填充,其中光柵圖形用於填充整個元素或作為重複圖案。

在將圖像填充導出到 SVG 時,它實際上與漸變非常相似。 圖像在<defs>中使用<pattern>…</pattern>元素定義,然後在fill屬性中引用:

 <defs> <pattern patternUnits="objectBoundingBox"> <use xlink:href="#picture"></use> </pattern> </defs> <rect fill="url(#myPattern)" />

要使其工作,必須在某處定義引用的#picture圖像。 設計工具會將它們作為<image/>元素直接嵌入到 SVG 中,儘管在性能方面不推薦使用這種方法。 如果您確實需要在 SVG 中使用光柵圖像,我建議您從 SVG 中刪除圖像標籤,並將其用作獨立文件:

 <defs> <pattern patternUnits="objectBoundingBox"> <use xlink:href="#picture"></use> </pattern> <image xlink:href="image.png"/> </defs> <rect fill="url(#myPattern)" />

筆劃

SVG 中的stroke屬性,與fill屬性相同,接受各種格式的顏色,例如 hex、RGB 或 HSL。 與fill類似,您可以使用stroke-opacity控制描邊的不透明度。 此外,與fill相同,筆劃可以使用漸變作為其值。 所有這些效果都可以在設計工具中實現並成功導出到 SVG。

中風帽和連接

不過,也有一些特定於筆劃的屬性。 首先,您可以控製筆畫寬度。 設計工具支持它並將其導出為stroke-width屬性。 您還可以控製筆畫的結束和連接。 SVG 允許您通過stroke-linecapstroke-linejoin屬性來定義它們。 有三種可能的端蓋: butt端蓋、 round端蓋和square端蓋,以及三種可能的連接: miter連接、 round連接和bevel連接。 Caps 和 Joins 都可以在 Illustrator、Figma 和 Sketch 中控制,並且可用的 caps 和 joins 與 SVG 中可用的相匹配。

虛線和虛線筆劃

我們可以用筆劃實現的另一個效果是虛線筆劃。 在 Illustrator 和 Figma 中,您可以設置多個虛線和間隙,而在 Sketch 中,只能設置單個虛線和間隙序列。

SVG 允許您使用stroke-dasharray屬性創建虛線。 stroke-dasharray允許將一系列多個破折號和間隙作為其值傳遞,該值與 Figma 和 Illustrator 的功能相匹配。 這也意味著 Sketch 不允許您在這種情況下使用 SVG 的全部可能性。

一個有趣的邊緣案例是虛線。 我們通過將stroke-linecap設置為round並將破折號的長度設置為零來實現它,例如:

 <line … stroke="black" stroke-dasharray="0 2" stroke-linecap="round"/>

注意目前,Figma 用戶遇到了一個不允許他們創建虛線的錯誤。 例如,使用0, 1010, 0作為破折號的解釋方式與10, 10相同,並給出常規的虛線而不是虛線。 幸運的是,有一種方法可以繞過它。 與其使用零,不如使用一個非常小的值,例如0.0001, 10這應該會產生完美的虛線,正如預期的那樣。

筆劃對齊

設計工具和 SVG 之間還有另一個更顯著的區別:筆劃對齊。 Illustrator、Sketch 和 Figma 都允許您控製筆畫的對齊方式,並將其設置為內部、外部或居中對齊。 但猜猜怎麼了? SVG 1.1 不支持筆劃對齊。 在 SVG 中,所有筆劃都是居中對齊的筆劃。 沒有內筆劃或外筆劃。 這就是為什麼當您將外部和內部對齊的筆劃導出到 SVG 時會發生一些非常奇怪的事情的原因。

在這種情況下,Illustrator 會將形狀及其筆劃導出為兩個單獨的形狀。 因此,如果您在 Illustrator 中將內部筆劃或外部筆劃應用於矩形,則在 SVG 中,它將生成一個矩形和一個單獨的<path />元素表示矩形的筆劃,例如:

 <rect x="10" y="10" width="120" height="120"/> <path d="M120,20V120H20V20H120M140,0H0V140H140V0Z"/>

這種行為有一些非常重要的影響。 例如,您不能再更改筆劃的寬度或使其變為虛線。 它也不會像“真實”筆劃那樣縮放。 更重要的是,Illustrator 會更改原始形狀的尺寸,例如,一個 100×100 的正方形和一個 20 單位的粗體內部筆劃實際上會導出為 120×120 的正方形,以避免渲染問題。 最終,這不是中風。 它只是另一種帶有填充的形狀。

Figma 和 Sketch 有不同的方法。 它們忠實地將所有筆劃導出為筆劃,但它們會重新計算形狀的尺寸。 因此,如果您有一個半徑等於 5 且內部筆劃等於 2 的圓,那麼您將在 SVG 中找到一個半徑等於 4 的圓(並且筆劃仍然等於 2)。

這種方法允許 Figma 和 Sketch 避免 Illustrator 中提到的大多數問題。 然而,對於一些更複雜的形狀,這種技術可能會變得不精確,最終結果與預期的有點不同。 這就是為什麼 Sketch 和 Figma 的方法不一定更好的原因——它肯定更具語義、性能和靈活性,但 Illustrator 的解決方案更準確。

注意:筆劃對齊的相同問題也適用於 CSS。 CSS border屬性也不支持內部或外部對齊。 但是,如果您願意,您可以使用outlinebox-shadow屬性來破解此行為。

多個填充和描邊

在設計工具中,您可以為每層添加多個填充和描邊。 一旦結合不透明度和混合模式等屬性,這很有意義。 不幸的是,SVG 不支持這樣的功能。 如果您導出具有填充和/或描邊的圖層,它將成倍增加,並且每個描邊和填充將應用於其自己的圖層。

陰影、濾鏡和其他效果

現在讓我們談談一些不太受歡迎的效果。 SVG 是一種非常強大的語言,實際上比它通常在網絡上使用的方式要強大得多。 SVG 最有趣的功能之一是廣泛的高級視覺效果,稱為 SVG 濾鏡。

SVG 過濾器的全部可能性範圍太廣,無法在本文中描述。 如果您想了解更多關於它們的信息,我強烈建議您查看 Sarah Soueidan 關於此主題的一些演講和文章。

過濾器,與圖案或漸變相同,需要定義以稍後將它們應用於圖層。 每個過濾器都被定義為一個<filter>…</filter>元素,可以包含許多效果,稱為過濾器原語,每個都代表一個單獨的視覺效果。

過濾器基元可以組合在一起以創建過濾器。 For example, this is what a basic blur effect applied to a rectangle looks like:

 <defs> <filter> <feGaussianBlur stdDeviation="10"/> </filter> </defs> <rect filter="url(#GaussianBlur)" width="200" height="300"/>

…but you can also create a more complex filter that consists of more than one filter primitive:

 <defs> <filter> <feGaussianBlur stdDeviation="10"/> <feMorphology operator="dilate" in="SourceGraphic" radius="3" /> </filter> </defs> <rect filter="url(#GaussianBlur)" width="200" height="300"/>

Out of the three design tools we discuss, only Illustrator lets you play with SVG filters. You can find them in the app's menu, under Effect > SVG Filters . Sketch and Figma are a completely different story. Any effects these applications offer are mostly focused on CSS and native implementations, eg Background Blur effect was implemented primarily for designing iOS apps and Drop/Inner Shadow effects parameters are matching CSS properties ( box-shadow and text-shadow ).

It doesn't mean we can't export these effects to SVG. 我們可以。 However, translating these effects to SVG is utterly not as straightforward as to CSS. Let's consider a square with a drop shadow applied.

A rectangle with a shadow
A rectangle with a shadow (Large preview)

This is how our square could look like, once exported to HTML/CSS:

 <style> .square { width: 100px; height: 100px; background: red; box-shadow: 10px 10px 24px 0 rgba(0,0,0,0.5); } </style> <div class="square"></div>

A similar square exported from Sketch to SVG gives us a significantly more complex piece of code:

 <defs> <rect x="14" y="14" width="100" height="100"></rect> <filter x="-31.0%" y="-31.0%" width="182.0%" height="182.0%" filterUnits="objectBoundingBox"> <feOffset dx="10" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="12" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> </filter> </defs> <g> <use fill="black" filter="url(#filter-2)" xlink:href="#square"></use> <use fill="#FF0000" fill-rule="evenodd" xlink:href="#square"></use> </g>

What happens here is that Sketch duplicates the square, so we have two identical squares, one above another, and turns the duplicate into a shadow.

To accomplish this, it applies a filter to a duplicated square that consists of three different filter primitives:

  • one to offset the square;
  • one to set its color to semi-transparent black;
  • one to blur it.

In other design tools, we would encounter a similar situation.

It doesn't mean that we should never, by all means, use shadows in SVG. It's handy to keep in mind though that as long as SVG gives you a very powerful toolkit to modify your graphics, some seemingly simple effects are not that simple to achieve at all.

混合模式

混合模式(例如DarkenMultiplyOverlay )允許通過以不同方式組合它們的值來混合兩個或多個元素。 平面設計師(以及 Adob​​e Photoshop 等應用程序)眾所周知,混合模式也適用於 Sketch、Figma 和 Illustrator。

在 SVG 中,混合模式作為過濾器之一存在。 他們有自己的<feBlend />過濾器原語。 然而,由於<feBlend />的語法相當複雜,Sketch、Figma 和 Illustrator 使用 CSS 代替:

 .rectangle { mix-blend-mode: overlay; }

現在mix-blend-mode瀏覽器支持相當不錯,這應該不是一個大問題。 但是,如果確保包括 Microsoft Edge 和 IE 在內的防彈瀏覽器支持對您很重要,您將不得不手動將 CSS 混合模式替換為 SVG 過濾器。

與多個填充和描邊一樣,SVG 不支持直接應用於填充和描邊屬性(而不是整個圖層)的混合模式。 如果您嘗試使用自己的混合模式將填充和描邊從設計工具導出到 SVG,則圖層將成倍增加,並且混合模式將應用於圖層的各個副本。

符號和組件

在上面的一些代碼示例中,您可能已經註意到我們尚未討論的元素: <use>…</use>元素。 <use>讓我們在 SVG 中定義和重用元素,有點類似於 Illustrator 中的 Symbols 和 Figma 中的 Sketch 或 Components。 還記得在<defs>…</defs>標記中定義模式、漸變和過濾器,以便它們可以在 SVG 代碼的其他部分中使用嗎? 事實上,任何 SVG 元素都可以通過這種方式定義和重用。 一旦定義了形狀或組,您可以在文檔的其餘部分多次引用它,例如:

 <defs> <circle cx="100" cy="100" r="20"/> </defs> <use fill="red" xlink:href="#circle"> </use> <use fill="green" xlink:href="#circle"> </use> <use fill="blue" xlink:href="#circle"> </use> …

您還可以使用<symbol>…</symbol>標籤重用更複雜的結構。 Symbol 在我們的 SVG 中充當一個單獨的主體,並且可以擁有自己的viewBox屬性(參見 Width、height 和 viewBox 以供參考)。

這是否意味著我們的設計工具的符號和組件將被導出為 SVG 符號? 在 Illustrator 中——是的,確實如此。 在 Sketch 和 Figma 中——不,它沒有。 為什麼? 首先,因為 Illustrator 符號相當簡單,可以輕鬆轉換為 SVG,而 Sketch 的符號和 Figma 的組件根本沒有那麼簡單,並且導出它的一些功能(例如嵌套覆蓋)將非常棘手甚至不可能。

文本

如果我們不提及排版,它就不是一個全面的指南。 所有設計工具都提供了與文本相關的各種工具。 SVG,即使通常用於圖形,也支持文本元素。

Illustrator、Sketch 和 Figma 都支持將文本導出為 SVG,並將文本層計算為 SVG 中的<text>…</text>元素。 SVG 文本元素像任何其他圖形元素、形狀等一樣呈現,唯一的區別是它們是文本。

與 CSS 一樣,我們可以控制所有基本文本的參數,例如粗細、行高或對齊方式。 事實上,如果您知道如何在 CSS 中設置文本樣式,那麼您就已經知道如何在 SVG 中進行設置了。 但是,它可能會感覺有點老派。 首先,所有參數都必須設置在內聯屬性中,類似於 HTML 3.2 的黃金標準。 其次,沒有速記。 例如,您不會找到任何類似於font CSS 屬性的東西。 這是因為 SVG 文本屬性實際上是基於 CSS 2 規範,它把我們帶回到了 90 年代,並且比我們今天所知道的 CSS 更古老。

儘管如此,每當我們希望某些文本層成為 SVG 代碼時,所有這些屬性都可以從設計工具中完美導出。

自定義字體

不幸的是,當涉及到自定義字體時,事情變得有點棘手。 回到過去,當 SVG 1 標準被創建時,自定義字體對於 Web 來說並不常見。 每個人都使用標準字體,例如 Tahoma、Verdana 或 Courier。 花哨並使用人們默認情況下在他們的機器上沒有的字體,通常意味著無情地將它們光柵化並將它們用作圖像。 但是,SVG 實現了自己的字體格式,稱為 SVG 字體。 今天,在 SVG 1.0 發布 18 年後,大多數主流瀏覽器不再支持 SVG 字體。

幸運的是,SVG 與 CSS 配合得非常好,這意味著我們可以使用 Web 字體代替 SVG 字體,例如:

 <style> @import url("https://fonts.googleapis.com/css?family=Roboto"); </style> <text x="20" y="50" font-family="Roboto">Text</text>

除了一個重要的注意事項外,讓我不要在這裡詳細介紹實現網絡字體:不要忘記它。 換句話說,如果您在 SVG 中使用自定義字體,您需要記住將這些字體提供給客戶端,就像在 HTML/CSS 中一樣。

大綱字體

有人可能會爭辯說,比爭論字體和所有內容更容易的是勾勒出所有的文本層,以後再也不用擔心它們了。 儘管如此,至少有幾個很好的理由不將文本更改為形狀:

  1. 您不能在導出之前或之後編輯輪廓文本。
    使用輪廓文本時,您需要記住始終在 Illustrator、Sketch 或 Figma 文件中保留可編輯的副本。 否則,一旦它們被勾勒出來,您將無法編輯文本圖層。 這給流程增加了不必要的複雜性。 更不用說在 SVG 導出後編輯概述的文本了。 SVG 中的文本可以隨時更新。 每次您想要進行最小的副本更改時,大綱文本都需要打開源文件。
  2. 大綱文本不可訪問
    SVG 中的文本與 Web 上的其他文本元素一樣,可以由屏幕閱讀器和其他可訪問的技術讀取。 通過概述文本層,您可以防止人們使用此類技術訪問您的內容。
  3. 人們期望 text 是 text
    大多數使用網絡的人對 SVG、HTML 或設計工具一無所知。 如果他們看到文字,他們希望它只是那樣。 他們可能想要選擇、複製或放入搜索引擎。 所有這一切都可以通過 SVG 中的文本實現 — 除非您對其進行概述。
  4. 不要忘記搜索引擎優化
    SVG 中的文本也可以被搜索引擎訪問和使用。 通過概述文本,您可以使您的內容不那麼容易被搜索到,並且可能不那麼被公眾看到。

概括

非常感謝您與我一起了解使用 SVG 和設計工具的來龍去脈。 本文絕對沒有涵蓋該主題的全部範圍,儘管它應該足以處理最常見的用例。 如果您對此處未提及的內容有任何疑問或疑問,請隨時在評論中發表!