網頁圖示

最後更新: 2022-09-26 18:12:04 +0800 +0800
tags: Web | Icons
原文以英文撰寫。您正在閱讀AI翻譯版本。

網頁圖示可以是文字字形、SVG 圖形或點陣圖。格式選擇會影響算繪精確度、快取、樣式、安全性,以及周圍控制項公開的無障礙名稱。

將圖示字型視為字型 #

圖示字型會將字元碼或連字映射至象形圖:

html
<span class="material-icons" aria-hidden="true">add_location</span>

字形會繼承 color、font-size 與其他文字屬性,因此單一字型檔可為單色圖示集套用佈景主題。相同的相依性也會造成限制:

  • 字型遭封鎖或延遲載入時,會顯示缺字方框或替代文字。
  • 取代字型的使用者樣式可能移除圖示。
  • 私人使用區碼位不具備可互通的文字意義。
  • 輔助技術可能會讀出連字名稱。
  • 字型平滑化與字型微調可能改變小尺寸下的形狀。

請對無障礙樹隱藏裝飾性字型字形,並將無障礙名稱放在其控制項上:

html
<button type="button" aria-label="Add location">
  <span class="material-icons" aria-hidden="true">add_location</span>
</button>

請勿將必要標籤只放在產生的 ::before 內容中。字型載入、自訂樣式與無障礙 API 都可能移除該資訊管道。

考量 Unicode 字形差異 #

Unicode 符號帶有標準化的字元識別資訊,而非標準化的圖示設計。所選字型決定其輪廓、度量,以及要算繪為單色文字或彩色表情符號。變體選擇符可要求某些字元以文字或表情符號呈現,但不同平台仍可能使用不同圖稿。

當字元本身屬於文字內容時(例如數學運算子或方向箭頭),請使用 Unicode。請勿將外觀相似的字元作為應用程式特定動作的唯一標籤。螢幕閱讀器會讀出字元的語意,而該語意可能不符合預期操作。

選擇 SVG 整合模型 #

SVG 描述與解析度無關的形狀,並支援多種填滿、描邊、漸層與動畫。整合方式決定樣式與安全性行為。

行內 SVG #

行內標記會參與文件的層疊:

html
<button type="button">
  <svg
    aria-hidden="true"
    focusable="false"
    width="20"
    height="20"
    viewBox="0 0 20 20">
    <path fill="currentColor" d="M3 10l4 4L17 4"></path>
  </svg>
  Save
</button>

currentColor 會跟隨按鈕的文字色彩。同一個複雜圖示多次出現時,行內標記會增加 HTML 大小,但它能提供直接樣式設定,並避免另外發出圖片請求。

具意義的獨立圖形需要無障礙名稱:

html
<svg role="img" aria-labelledby="network-title" viewBox="0 0 24 24">
  <title id="network-title">Network topology</title>
  <circle cx="12" cy="12" r="8"></circle>
</svg>

裝飾性 SVG 應改用 aria-hidden="true" 與 focusable="false"。對於只有圖示的按鈕,請命名按鈕本身,因為按鈕才是互動物件。

SVG Sprite #

行內 Sprite 會定義可重複使用的符號:

html
<svg aria-hidden="true" hidden>
  <symbol id="icon-check" viewBox="0 0 24 24">
    <path d="M4 12l5 5L20 6"></path>
  </symbol>
</svg>

<svg aria-hidden="true" focusable="false">
  <use href="#icon-check"></use>
</svg>

同源的外部 Sprite 會將定義移到可快取的檔案:

html
<svg aria-hidden="true" focusable="false">
  <use href="/icons/sprite.svg#icon-check"></use>
</svg>

瀏覽器刻意限制複製的 <use> 內容之樣式設定。請在符號中放置 fill="currentColor" 或穩定的呈現屬性,並設定外層 <svg> 的樣式。即使伺服器傳回 CORS 標頭,跨來源外部片段仍不具可攜性,因此應從相同來源提供 Sprite,或擷取、驗證後再將它嵌入行內。

將 SVG 作為圖片 #

透過 <img> 載入的 SVG 是隔離的圖片文件:

html
<img src="/icons/product-mark.svg" alt="Example product">

頁面 CSS 無法存取其內部路徑,currentColor 也不會從宿主元素繼承。圖片環境會停用指令碼,因此對於受信任的靜態資產,使用 <img> 比注入其標記更安全。空白的 alt="" 表示裝飾性圖片;具意義的圖片需要替代文字。

任意 SVG 標記嵌入行內或作為可導覽文件提供時,應將其視為主動式內容。請淨化不受信任的檔案、禁止指令碼與事件處理常式屬性、控制外部參照,並使用適當的內容安全政策,以預期的媒體類型提供檔案。

依顯示密度調整點陣圖示尺寸 #

PNG、WebP 或 AVIF 可保留創作時的像素、多色細節,以及難以用向量重現的效果。點陣圖放大時無法增加細節,因此應提供密度變體:

html
<img
  src="/icons/avatar-24.png"
  srcset="/icons/avatar-24.png 1x, /icons/avatar-48.png 2x"
  width="24"
  height="24"
  alt="">

明確的尺寸可保留版面空間。縮小取樣高密度來源能產生清晰的小型圖示,但大型密度變體會消耗頻寬與記憶體。像素圖圖示可能需要 image-rendering 規則與整數縮放;攝影或帶紋理的圖示應依所需的 Alpha 色版與壓縮行為選擇圖片格式。

CSS 背景圖片適合用於裝飾,因為它們不會提供無障礙名稱:

css
.status::before {
  background: url("/icons/status.svg") center / contain no-repeat;
  content: "";
}

背景用於傳達狀態時,請在 DOM 中保留文字標籤。

依語意與傳遞限制選擇 #

請使用符合實際契約的表示方式:

需求適合的表示方式
字元屬於正文Unicode 字形與經測試的後援字型堆疊
可直接設定樣式的單色 UI 圖示行內 SVG 或同源 SVG Sprite
可快取且無須宿主樣式的靜態向量透過 <img> 載入 SVG
多色向量標誌SVG 圖片或審慎限定範圍的行內 SVG
攝影或像素創作的細節可感知密度的點陣圖
既有舊式圖示字型系統具備後援與無障礙測試的圖示字型

快取需求可能有利於單一外部 Sprite 或圖片;元件隔離可能有利於行內 SVG;嚴格的內容安全政策可能偏向載入無作用圖片,而非注入標記。格式本身不提供語意。裝飾性圖示必須對輔助技術保持隱藏,而控制項與具意義的圖形則需要能在資產載入失敗時留存的無障礙名稱。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)