iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Modern Web

從實務需求出發:前端視覺與 UI 互動開發實踐系列 第 6 篇

【Day 06】SVG 基礎:我把圖片內嵌在 HTML 了!

  • 分享至 

  • xImage
  •  

第一次注意到 SVG,是設計稿中使用到 Iconify Design 的 icon。在操作面板調整 icon 的顏色、大小的時候,發現 SVG 碼會有對應的變化。
一開始只是意識到 能直接在 HTML 複製貼上、能調整 fill 屬性改變顏色。沒想到,之後工作時能用 SVG 解決了許多難題。

今天先來了解 SVG 是什麼,以及它有哪些設定吧!


簡介

SVG,全名 Scalable Vector Graphics 可縮放向量圖形。是一種「用來畫向量圖」的 XML 規範。它繼承了 XML 的語法結構,並定義了一套特定標籤(例如圓形就是 <circle cx="6" cy="6" r="5" />)。透過標籤與屬性的設定,讓瀏覽器知道怎麼畫出對應的圖案。

來看個簡單的範例。下面這段 code 在瀏覽器會被渲染成一個「在 12px × 12px 的畫布中畫出紅色圓形」。也可以到 iconify 內手動操作面板看看。

<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
	<circle cx="6" cy="6" r="5" fill="#e74747" stroke="#e74747" />
</svg>

優勢

為什麼要用 SVG 呢?全用 PNG 不就好了嗎?用 SVG 處理向量圖,除了檔案大小會比 .png 小很多外,還有很多超讚的地方!

  • 向量圖形格式,可以縮放且圖像不失真。
  • 瀏覽器原生支援。
  • 擁有 DOM 介面,即 內的每一個標籤,都會被視為 HTML 節點(DOM tree 的概念)。所以可以:
    • 使用 CSS 與 JavaScript 來操作
    • 支援事件監聽
    • 如同調整 HTML 標籤般,抽換 SVG 內部

比較 SVG、PNG、Canvas

  • SVG:向量圖,用標籤描述「要畫什麼形狀」,由瀏覽器即時繪製。
  • PNG:點陣圖檔案,由一格格像素組成。
  • Canvas:HTML 的 元素,用 JavaScript 在畫布上畫出像素,畫完就變成一張點陣圖。

這三種方式都能處理圖形,但各自擅長的地方不太一樣。

SVG PNG Canvas
圖形類型 向量 點陣 點陣(由 JS 繪製)
縮放 不失真 放大會模糊 放大會模糊,需自行處理高解析度螢幕
內部元素 每個圖形都是 DOM 節點 一整張圖,無法個別操作 畫完只剩像素,沒有個別元素
CSS 樣式 可以 無法改內部顏色 無法
事件監聽 可綁定在單一圖形上 只能綁在整張圖 只能綁在整個畫布,需自行判斷點到哪個圖形
大量物件的效能 節點多了會卡頓 不受影響 表現最好
適合情境 icon、Logo、圖表 照片、複雜圖像 遊戲、網頁白板

拆解 <svg>

根元素

一個 SVG 從會 <svg> 標籤開始,需要設定:

  • width 和 height 定義了 SVG 容器寬度與高度,決定佔用多大空間。
  • viewBox 定義了 SVG 內部元素繪製時的座標系與邊界。能確保圖形縮放後保持比例,不失真。由左到右的四個數字分別是:
    1. min-x:相對畫布左上角的起始 x 座標
    2. min-y:相對畫布左上角的起始 y 座標
    3. width:畫布(可視)寬度
    4. height:畫布(可視)高度
  • 獨立的 .svg 檔必須再加上 xmlns="http://www.w3.org/2000/svg"宣告這是 XML 命名空間。

SVG 標籤

我自己常用 SVG 處理 icon 跟向量圖案,所以比較常看到的是 <path>、<circle>與 <text>

標籤 說明 主要屬性 範例
圓形 <circle> 以圓心和半徑畫出正圓 cx、cy(圓心座標)、r(半徑) <circle cx="6" cy="6" r="5" />
橢圓形 <ellipse> 與圓形類似,但水平、垂直半徑可以不同 cx、cy、rx(水平半徑)、ry(垂直半徑) <ellipse cx="10" cy="6" rx="8" ry="5" />
矩形 <rect> 畫出矩形,加上 rx、ry 可做出圓角 x、y(左上角座標)、width、height、rx、ry <rect x="1" y="1" width="10" height="8" rx="2" />
線條 <line> 連接兩個點的直線 x1、y1(起點)、x2、y2(終點) <line x1="0" y1="0" x2="10" y2="10" stroke="black" />
折線 <polyline> 連接多個點的線,起點與終點不會自動連起來 points(一連串座標) <polyline points="0,0 5,8 10,2" fill="none" stroke="black" />
多邊形 <polygon> 連接多個點並自動封閉成一個圖形 points(一連串座標) <polygon points="6,1 11,11 1,11" />
路徑 <path> 最靈活的標籤,能用指令畫出直線、曲線與任意形狀,icon 大多是用它畫的 d(路徑指令) <path d="M0 0h12v12H0z" />
文字 <text> 在指定位置顯示文字 x、y(文字基準線起點)、font-size 等 <text x="0" y="10">Hello</text>

常見通用屬性

屬性 說明 範例
fill 圖形的填充顏色。沒設定時預設為黑色,設成 none 則不填色 fill="#e74747"
stroke 圖形的線條 / 邊框顏色。沒設定時預設為無 stroke="#e74747"
stroke-width 圖形的線條 / 邊框粗細,預設為 1 stroke-width="2"
color 設定 currentColor 的值,搭配 fill="currentColor" 或 stroke="currentColor" 使用,可以讓圖形跟隨外層文字顏色變化 color="red" 或 CSS color: red
opacity 整體透明度,範圍 0 到 1 opacity="0.5"

另外,SVG 標籤也能接受 class、style 與 id 屬性。

.

.

.

簡介到這邊告一段落。

明天,來實際應用看看 SVG 能做到什麼事情吧!


參考資料

在收集資料階段,找到許多有趣的範例,像是這個聖誕節倒數月曆。除此之外,還有許多 D3.js 函式庫的教學文,實在大開眼界。尤其是 D3.js 能應用的情境非常廣。感覺能滿足之前專案的需求,有種相見恨晚的感覺。


上一篇
【Day 05】 同場加映:圖片 RWD
下一篇
【Day 07】SVG 實作:用 fill / stroke 告別海量 icon 靜態圖檔
系列文
從實務需求出發:前端視覺與 UI 互動開發實踐 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言