首頁 > web前端 > css教學 > 6常見的SVG失敗(以及如何修復它們)

6常見的SVG失敗(以及如何修復它們)

Lisa Kudrow
發布: 2025-03-09 11:04:11
原創
670 人瀏覽過

6 Common SVG Fails (and How to Fix Them)

最近有人問我如何調試內聯 SVG。因為它屬於 DOM 的一部分,所以我們可以在任何瀏覽器的 DevTools 中檢查任何內聯 SVG。正因如此,我們能夠對事情進行範圍界定,並發現任何潛在問題或 SVG 優化的機會。

但有時,我們甚至根本看不到我們的 SVG。在這些情況下,調試時我會尋找六個特定方面。

1. viewBox 值

在使用 SVG 時,viewBox 是一個常見的混淆點。從技術上講,在沒有 viewBox 的情況下使用內聯 SVG 也沒問題,但我們會失去其最重要的優勢之一:隨容器縮放。同時,如果配置不當,它可能會對我們不利,導致出現意外裁剪。

當元素被裁剪時,它們就在那裡——它們只是在我們看不到的坐標系的一部分中。如果我們在某些圖形編輯程序中打開該文件,它可能看起來像這樣:

最簡單的解決方法是什麼?向 SVG 添加 overflow="visible",無論是在樣式表中、內聯樣式屬性中,還是直接作為 SVG 表示屬性。但是,如果我們還向 SVG 應用背景顏色,或者周圍有其他元素,事情可能看起來有點不對勁。在這種情況下,最佳選擇是編輯 viewBox 以顯示隱藏的坐標係部分:

關於 viewBox,還有一些額外的事情值得在討論時介紹:

viewBox 如何工作?

SVG 是一個無限畫布,但我們可以通過視口和 viewBox 來控制我們看到的內容以及如何看到它。

視口是無限畫布上的窗口框架。其尺寸由 widthheight 屬性定義,或在 CSS 中使用相應的 widthheight 屬性定義。我們可以指定任何我們想要的長度單位,但如果我們提供無單位的數字,它們默認為像素。

viewBox 由四個值定義。前兩個是左上角的起點(x 和 y 值,允許負數)。我正在編輯這些以重新構圖。後兩個是視口中坐標系的寬度和高度——在這裡我們可以編輯網格的比例(我們將在縮放部分討論)。

以下是顯示在 <svg></svg> 上同時設置了 SVG viewBox 和 widthheight 屬性的簡化標記:

<svg height="700" viewbox="0 0 700 700" width="700"></svg>
登入後複製
登入後複製
登入後複製
登入後複製

重新構圖

所以,這個:

<svg viewbox="0 0 700 700"></svg>
登入後複製
登入後複製
登入後複製

……映射到這個:

<svg viewbox="start-x-axis start-y-axis width height"></svg>
登入後複製

我們看到的視口始於 x 軸上的 0 和 y 軸上的 0 相交的地方。

通過更改此內容:

<svg viewbox="0 0 700 700"></svg>
登入後複製
登入後複製
登入後複製

……到這個:

<svg viewbox="300 200 700 700"></svg>
登入後複製

……寬度和高度保持不變(每個 700 個單位),但坐標系的起點現在位於 x 軸上的 300 點和 y 軸上的 200 點。

在下面的視頻中,我向 SVG 添加了一個紅色 <circle></circle>,其中心位於 x 軸上的 300 點和 y 軸上的 200 點。請注意,將 viewBox 坐標更改為相同的值也會將圓的放置位置更改為框架的左上角,而 SVG 的渲染大小保持不變(700×700)。我所做的只是用 viewBox“重新構圖”。

縮放

我們可以更改 viewBox 內的後兩個值以放大或縮小圖像。值越大,添加到視口中的 SVG 單位就越多,從而導致圖像變小。如果我們想保持 1:1 的比例,我們的 viewBox 寬度和高度必須與我們的視口寬度和高度值匹配。

讓我們看看在 Illustrator 中更改這些參數時會發生什麼。畫板是視口,由一個 700 像素的白色正方形表示。該區域之外的所有內容都是我們無限的 SVG 畫布,默認情況下會被裁剪。

下面的圖 1 顯示了一個藍色點,位於 x 軸上的 900 和 y 軸上的 900。如果我將後兩個 viewBox 值從 700 更改為 900,如下所示:

<svg height="700" viewbox="0 0 700 700" width="700"></svg>
登入後複製
登入後複製
登入後複製
登入後複製

……那麼藍色點幾乎完全回到了視野中,如下面的圖 2 所示。我們的圖像縮小了,因為我們增加了 viewBox 值,但 SVG 的實際寬度和高度尺寸保持不變,並且藍色點回到了更靠近未裁剪區域的位置。

有一個粉紅色正方形作為網格如何縮放以適應視口的證據:單位變小,並且更多網格線適合相同的視口區域。您可以在下面的 Pen 中使用相同的值來查看其工作原理:

2. 缺少寬度和高度

調試內聯 SVG 時,我查看的另一個常見問題是標記中是否包含 widthheight 屬性。在許多情況下,這沒什麼大不了的,除非 SVG 位於具有絕對定位或靈活容器的容器內(因為 Safari 使用 0px 而不是 auto 計算 SVG 寬度值)。在這些情況下,排除寬度或高度會阻止我們看到完整的圖像,正如我們通過打開此 CodePen 演示並在 Chrome、Safari 和 Firefox 中進行比較所看到的那樣(點擊圖像可查看更大的視圖)。

解決方案?添加寬度或高度,無論是作為表示屬性、內聯樣式屬性還是在 CSS 中。避免單獨使用高度,尤其是在將其設置為 100%auto 時。另一種解決方法是設置 rightleft 值。

您可以使用以下 Pen 並組合不同的選項進行嘗試。

3. 無意中的填充和描邊顏色

也可能是我們正在向 <svg></svg> 標籤應用顏色,無論是內聯樣式還是來自 CSS。這很好,但標記或樣式中可能還有其他顏色值與 <svg></svg> 上設置的顏色衝突,導致部分內容不可見。

這就是為什麼我傾向於在 SVG 的標記中查找 fillstroke 屬性並將其刪除的原因。以下視頻顯示了一個我在 CSS 中使用紅色填充進行樣式設置的 SVG。在 SVG 中,有一些地方的填充直接在標記中以白色填充,我將其刪除以顯示缺失的部分。

4. 缺少 ID

這個看起來可能非常明顯,但你會驚訝地發現我看到它出現的頻率有多高。假設我們在 Illustrator 中製作了一個 SVG 文件,並且非常努力地命名圖層,以便在導出文件時獲得不錯的匹配 ID。假設我們計劃通過連接到這些 ID 來在 CSS 中設置該 SVG 的樣式。

這是一種不錯的做法。但是,有很多次我看到相同的 SVG 文件第二次導出到相同的位置,並且 ID 不同,通常是在直接複製/粘貼矢量時。也許添加了一個新圖層,或者重命名了現有圖層之一,或者其他什麼。無論如何,CSS 規則不再與 SVG 標記中的 ID 匹配,導致 SVG 的渲染方式與預期不同。

在大型 SVG 文件中,我們可能難以找到這些 ID。這是一個打開 DevTools、檢查不起作用的圖形部分並查看這些 ID 是否仍然匹配的好時機。

因此,我會說在交換內容之前,打開代碼編輯器中的導出 SVG 文件並將其與原始文件進行比較是值得的。像 Illustrator、Figma 和 Sketch 這樣的應用程序很智能,但這並不意味著我們沒有責任審核它們。

5. 裁剪和蒙版的檢查清單

如果 SVG 被意外裁剪並且 viewBox 檢查正常,我通常會查看 CSS 中可能干擾圖像的 clip-pathmask 屬性。查看內聯標記很誘人,但最好記住 SVG 的樣式可能發生在其他地方。

CSS 裁剪和蒙版允許我們“隱藏”圖像或元素的部分。在 SVG 中,<clippath></clippath> 是一個矢量操作,它會裁剪圖像的部分,沒有中間結果。 <mask></mask> 標籤是一個像素操作,允許透明度、半透明效果和模糊邊緣。

這是一個用於調試涉及裁剪和蒙版的情況的小型檢查清單:

  • 確保裁剪路徑(或蒙版)和圖形相互重疊。重疊的部分是顯示的部分。
  • 如果您有一個複雜的路徑沒有與您的圖形相交,請嘗試應用轉換直到它們匹配。
  • 即使 <clippath></clippath><mask></mask> 未渲染,您仍然可以使用 DevTools 檢查內部代碼,因此請使用它!
  • 複製 <clippath></clippath><mask></mask> 內的標記,然後將其粘貼在關閉標籤之前。然後向這些形狀添加填充並檢查 SVG 的坐標和尺寸。如果您仍然沒有看到圖像,請嘗試向 <svg></svg> 標籤添加 overflow="hidden"
  • 檢查是否為 <clippath></clippath><mask></mask> 使用了唯一的 ID,以及是否將相同的 ID 應用於被裁剪或蒙版的形狀或形狀組。不匹配的 ID 會破壞外觀。
  • 檢查 <clippath></clippath><mask></mask> 標籤之間的標記中是否有錯別字。
  • 應用於 <clippath></clippath> 內元素的 fillstrokeopacity 或其他一些樣式是無用的——唯一有用的部分是這些元素的填充區域幾何形狀。這就是為什麼如果您使用 <polyline></polyline>,它會表現得像 <polygon></polygon>,而如果您使用 <line></line>,您將看不到任何裁剪效果。
  • 如果在應用 <mask></mask> 後沒有看到圖像,請確保蒙版內容的填充不是完全黑色。蒙版元素的亮度決定最終圖形的不透明度。您將能夠透過較亮的部分看到,而較暗的部分會隱藏圖像的內容。

您可以在此 Pen 中使用蒙版和裁剪元素進行練習。

6. 命名空間

您知道 SVG 是一種基於 XML 的標記語言嗎?是的,它是! SVG 的命名空間設置在 xmlns 屬性上:

<svg height="700" viewbox="0 0 700 700" width="700"></svg>
登入後複製
登入後複製
登入後複製
登入後複製

關於 XML 中的命名空間有很多需要了解的內容,MDN 上有一個很好的入門介紹。可以這麼說,命名空間為瀏覽器提供上下文,告知它標記特定於 SVG。其思想是,當同一個文件中有多種類型的 XML 時(例如 SVG 和 XHTML),命名空間有助於防止衝突。這在現代瀏覽器中是一個不太常見的問題,但可以幫助解釋舊版瀏覽器或像 Gecko 這樣的瀏覽器在定義文檔類型和命名空間時嚴格的 SVG 渲染問題。

SVG 2 規範在使用 HTML 語法時不需要命名空間。但如果支持舊版瀏覽器是一個優先事項,那麼這一點至關重要——此外,添加它也不會造成任何損害。這樣,當定義元素的 xmlns 屬性時,在那些罕見的情況下就不會發生衝突。

<svg height="700" viewbox="0 0 700 700" width="700"></svg>
登入後複製
登入後複製
登入後複製
登入後複製

在使用內聯 SVG 在 CSS 中時(例如將其設置為背景圖像)也是如此。在下面的示例中,成功驗證後,複選標記圖標會出現在輸入框中。 CSS 的外觀如下所示:

<svg viewbox="0 0 700 700"></svg>
登入後複製
登入後複製
登入後複製

當我們在背景屬性中刪除 SVG 內的命名空間時,圖像會消失:

另一個常見的命名空間前綴是 xlink:href。當引用 SVG 的其他部分時,我們經常使用它,例如:圖案、濾鏡、動畫或漸變。建議開始將其替換為 href,因為另一個自 SVG 2 以來已被棄用,但可能與舊版瀏覽器存在兼容性問題。在這種情況下,我們可以同時使用兩者。請記住,如果您仍在使用 xlink:href,請包含命名空間 xmlns:xlink="http://www.w3.org/1999/xlink"

提升您的 SVG 技能!

如果您發現自己正在對渲染不正確的內聯 SVG 進行故障排除,我希望這些技巧可以幫助您節省大量時間。這些只是我尋找的東西。也許您有不同的危險信號需要關注——如果有,請在評論中告訴我!

最重要的是,至少對 SVG 的各種使用方法有基本的了解是值得的。 CodePen Challenges 經常包含 SVG 並提供良好的實踐。以下是一些提升水平的更多資源:

  • 使用 SVG、CSS3 和 HTML5(Amelia Bellamy-Royds、Kurt Cagle、Dudley Storey)——我認為它是 SVG 聖經。
  • Lea Verou 擁有豐富的 SVG 知識,並且多次就此主題發表過演講(例如來自 Frontend United 2019 的此視頻)。
  • SVG 動畫(Sarah Drasner)
  • SVG Essentials(Amelia Bellamy-Royds、J. David Eisenberg)
  • Practical SVG(Chris Coyier)

我建議關註一些與 SVG 相關的優秀人士:

  • Sara Soueidan
  • Carl Schoof
  • Cassie Evans
  • Val Head
  • Ana Tudor

以上是6常見的SVG失敗(以及如何修復它們)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板