處理常見的 HTML 和 CSS 問題
在建立了基礎之後,我們將專門關注在 HTML 和 CSS 程式碼中經常遇到的跨瀏覽器問題,以及可以使用哪些工具來防止問題發生或修復已經發生的問題。 這包括程式碼 linting、處理 CSS 字首、使用瀏覽器開發者工具追蹤問題、使用 polyfills 向瀏覽器新增支援、解決響應式設計問題等等。
| 先決條件 | 熟悉核心 HTML、CSS 和 JavaScript 語言;瞭解 跨瀏覽器測試原則 的高階概念。 |
|---|---|
| 目標 | 能夠診斷常見的 HTML 和 CSS 跨瀏覽器問題,並使用適當的工具和技術來修復它們。 |
HTML 和 CSS 的問題
HTML 和 CSS 的一些問題在於這兩種語言都比較簡單,開發人員往往不會認真對待它們,沒有確保程式碼編寫良好、高效,以及語義上描述頁面功能的意圖。 在最糟糕的情況下,JavaScript 用於生成整個網頁內容和樣式,這會導致頁面不可訪問,效能降低(生成 DOM 元素開銷很大)。 在其他情況下,新生功能在不同瀏覽器中的支援並不一致,這會導致某些功能和樣式無法在某些使用者中使用。 響應式設計問題也很常見——一個在桌面瀏覽器中看起來很好的網站可能在移動裝置上提供糟糕的體驗,因為內容太小而無法閱讀,或者可能是因為動畫開銷大導致網站速度慢。
讓我們繼續研究如何減少由 HTML/CSS 引起的跨瀏覽器錯誤。
首先:修復一般問題
我們在 本系列的第一篇文章 中提到,一個好的策略是首先在桌面/移動裝置上的一些現代瀏覽器中進行測試,以確保您的程式碼總體上能夠正常執行,然後再繼續關注跨瀏覽器問題。
在我們的 除錯 HTML 和 除錯 CSS 文章中,我們提供了一些關於除錯 HTML/CSS 的基本指導——如果您不熟悉這些基礎知識,您應該在繼續之前仔細研究這些文章。
基本上,這只是檢查您的 HTML 和 CSS 程式碼是否格式正確,不包含任何語法錯誤。
注意:CSS 和 HTML 中的一個常見問題是不同的 CSS 規則開始相互衝突。 當您使用第三方程式碼時,這尤其成問題。 例如,您可能使用了一個 CSS 框架,並發現它使用的類名之一與您已經為其他目的使用的類名衝突。 或者您可能會發現由某種第三方 API 生成的 HTML(例如生成廣告橫幅)包含您已經為其他目的使用的類名或 ID。 為了確保這種情況不會發生,您需要首先研究您正在使用的工具,並根據它們設計您的程式碼。 還值得對 CSS 進行“名稱空間”,例如,如果您有一個小部件,請確保它具有一個獨特的類名,然後從這個類名開始選擇小部件內部元素的選擇器,這樣衝突的可能性就會降低。 例如 .audio-player ul a。
驗證
程式碼檢查工具
另一個不錯的選擇是所謂的程式碼檢查工具應用程式,它不僅會指出錯誤,還會標記 CSS 中不良實踐的警告,以及其他一些問題。 程式碼檢查工具通常可以自定義,使其在錯誤/警告報告中更加嚴格或更加寬鬆。
有很多線上程式碼檢查工具應用程式,例如 Dirty Markup,用於 HTML、CSS 和 JavaScript。 這些應用程式允許您將程式碼貼上到一個視窗中,它會用十字標記標記任何錯誤,然後可以透過懸停來獲取錯誤訊息,告知您問題是什麼。 Dirty Markup 還允許您使用“清理”按鈕修復您的標記。
但是,每次都要將程式碼複製貼上到網頁上以檢查其有效性並不方便。 您真正想要的是一個程式碼檢查工具,它可以以最小的麻煩融入您的標準工作流程中。
許多程式碼編輯器都有程式碼檢查工具外掛。 例如,請參見
- SublimeLinter for Sublime Text
- Notepad++ 程式碼檢查工具
- VSCode 程式碼檢查工具
瀏覽器開發者工具
大多數瀏覽器內建的開發者工具還提供了用於查詢錯誤的實用工具,主要用於 CSS。
注意:HTML 錯誤通常不會在開發者工具中很容易地顯示出來,因為瀏覽器會嘗試自動更正格式錯誤的標記;W3C 驗證器是查詢 HTML 錯誤的最佳方法——請參閱上面的 驗證。
例如,在 Firefox 中,CSS 檢查器將顯示未應用的 CSS 宣告,並帶有一個警告三角形。 將滑鼠懸停在警告三角形上將提供描述性錯誤訊息
其他瀏覽器開發者工具具有類似的功能。
常見的跨瀏覽器問題
現在讓我們繼續瞭解一些最常見的跨瀏覽器 HTML 和 CSS 問題。 我們將重點關注的主要領域是缺乏對現代功能的支援和佈局問題。
瀏覽器不支援現代功能
這是一個常見問題,尤其是在您需要支援舊瀏覽器或使用某些瀏覽器中已實現但在所有瀏覽器中尚未實現的功能時。 通常,大多數核心 HTML 和 CSS 功能(例如基本 HTML 元素、CSS 基本顏色和文字樣式)在您想要支援的所有瀏覽器中都能正常工作;更多的問題會在您開始想要使用更新的 HTML、CSS 和 API 時發現。 MDN 為每個記錄的功能顯示瀏覽器相容性資料;例如,請參閱 :has() 偽類的瀏覽器支援表。
確定了您將使用的並非普遍支援的技術列表後,最好研究一下哪些瀏覽器支援它們,以及哪些相關技術有用。 請參閱下面的 尋求幫助。
HTML 回退行為
有些問題可以透過利用 HTML/CSS 的自然工作方式來解決。
瀏覽器將無法識別的 HTML 元素視為匿名內聯元素(實際上是沒有任何語義值的內聯元素,類似於 <span> 元素)。 您仍然可以透過它們的名字引用它們,並使用 CSS 對它們進行樣式設定,例如——您只需要確保它們按照您的預期進行操作。 對它們進行樣式設定就像對任何其他元素一樣,包括在需要時將 display 屬性設定為 inline 以外的值。
更復雜的元素,如 HTML <video>、<audio>、<picture>、<object> 和 <canvas>(以及其他功能)具有自然的機制,用於在連結到的資源不支援的情況下添加回退。 您可以在開始和結束標記之間添加回退內容,不支援的瀏覽器將有效地忽略外部元素並執行巢狀內容。
例如
<video id="video" controls preload="metadata" poster="img/poster.jpg">
<source
src="video/tears-of-steel-battle-clip-medium.webm"
type="video/webm" />
<!-- Offer download -->
<p>
Your browser does not support WebM video; here is a link to
<a href="video/tears-of-steel-battle-clip-medium.mp4"
>view the video directly</a
>
</p>
</video>
此示例包含一個簡單的連結,允許您下載影片,即使 HTML 影片播放器無法正常工作,這樣至少使用者仍然可以訪問影片。
另一個例子是表單元素。 當為將特定資訊輸入表單引入新的 <input> 型別時,例如時間、日期、顏色、數字等,如果瀏覽器不支援新功能,瀏覽器將使用 type="text" 的預設值。 添加了輸入型別,它們非常有用,尤其是在移動平臺上,為使用者提供一種輕鬆輸入資料的方式對於使用者體驗非常重要。 平臺根據輸入型別提供不同的 UI 小部件,例如用於輸入日期的日曆小部件。 如果瀏覽器不支援輸入型別,使用者仍然可以輸入所需資料。
以下示例顯示了日期和時間輸入
<form>
<div>
<label for="date">Enter a date:</label>
<input id="date" type="date" />
</div>
<div>
<label for="time">Enter a time:</label>
<input id="time" type="time" />
</div>
</form>
此程式碼的輸出如下
注意:您也可以在 GitHub 上將其作為 forms-test.html 線上檢視(也請參閱 原始碼)。
如果您檢視該示例,您將在嘗試輸入資料時看到 UI 功能的實際執行情況。 在具有動態鍵盤的裝置上,將顯示特定於型別的鍵盤。 在不支援的瀏覽器中,輸入將只預設設定為普通文字輸入,這意味著使用者仍然可以輸入正確的資訊。
CSS 回退行為
可以說 CSS 比 HTML 更擅長回退。 如果瀏覽器遇到它不理解的宣告或規則,它只會完全跳過它,既不應用它也不丟擲錯誤。 如果這種錯誤在生產程式碼中漏掉了,這對您和您的使用者來說可能很令人沮喪,但至少這意味著整個網站不會因為一個錯誤而崩潰,如果您巧妙地使用它,您就可以利用它來發揮優勢。
讓我們看一個例子——一個用 CSS 樣式化的簡單框,它具有一些由各種 CSS 功能提供的樣式
注意:您也可以在 GitHub 上將其作為 button-with-fallback.html 線上檢視(也請參閱 原始碼)。
該按鈕具有許多樣式宣告,但我們最感興趣的兩個是:
button {
/* … */
background-color: #ff0000;
background-color: rgb(255 0 0 / 100%);
box-shadow:
inset 1px 1px 3px rgb(255 255 255 / 40%),
inset -1px -1px 3px rgb(0 0 0 / 40%);
}
button:hover {
background-color: rgb(255 0 0 / 50%);
}
button:active {
box-shadow:
inset 1px 1px 3px rgb(0 0 0 / 40%),
inset -1px -1px 3px rgb(255 255 255 / 40%);
}
這裡我們提供了一個RGB background-color,它在懸停時會改變不透明度,從而向用戶提示按鈕是可互動的,還有一些半透明的內嵌box-shadow陰影,為按鈕提供一些紋理和深度。雖然現在得到了完全的支援,但 RGB 顏色和盒子陰影並不總是存在的;從 IE9 開始。不支援 RGB 顏色的瀏覽器會忽略該宣告,這意味著在舊瀏覽器中,背景根本不會顯示,文字將無法讀取,這完全不好!
為了解決這個問題,我們添加了第二個background-color宣告,它只指定一個十六進位制顏色 - 這種顏色在非常舊的瀏覽器中得到了支援,並且在現代閃亮的功能無法正常工作時充當備用。發生的事情是,訪問此頁面的瀏覽器首先應用第一個background-color值;當它到達第二個background-color宣告時,如果它支援 RGB 顏色,它將用此值覆蓋初始值。否則,它會忽略整個宣告並繼續執行。
注意:對於其他 CSS 功能(如媒體查詢、@font-face和@supports塊)也是如此 - 如果不支援,瀏覽器會直接忽略它們。
選擇器支援
當然,如果你沒有使用正確的選擇器來選擇要設定樣式的元素,那麼所有 CSS 功能都將不會應用!
在用逗號分隔的選擇器列表中,如果你只是錯誤地編寫了一個選擇器,它可能不會匹配任何元素。但是,如果選擇器無效,則整個選擇器列表將被忽略,以及整個樣式塊。因此,只在寬容選擇器列表中包含:-moz-字首的偽類或偽元素,例如:where(::-moz-thumb)。不要在逗號分隔的選擇器組中包含:-moz-字首的偽類或偽元素,除非是在:is()或:where()寬容選擇器列表中,因為除 Firefox 之外的所有瀏覽器都會忽略整個塊。請注意,:is()和:where()都可以作為引數傳遞給其他選擇器列表,包括:has()和:not()。
我們發現,使用瀏覽器的開發工具檢查要設定樣式的元素很有幫助,然後檢視 DOM 檢查器通常提供的 DOM 樹麵包屑跟蹤,以檢視選擇器與之相比是否合理。
例如,在 Firefox 開發工具中,你會在 DOM 檢查器底部看到這種型別的輸出
例如,如果你試圖使用這個選擇器,你將能夠看到它不會像預期的那樣選擇輸入元素
form > #date
(date 表單輸入不是<form>的直接子元素;你最好使用通用後代選擇器而不是子選擇器)。
處理 CSS 字首
另一組問題與 CSS 字首有關 - 這些字首最初是一種機制,允許瀏覽器供應商在 CSS(或 JavaScript)功能處於實驗狀態時實現自己的版本,這樣他們就可以玩弄它並使其正確,而不會與其他瀏覽器的實現或最終的非字首實現衝突。
例如,Firefox 使用-moz-,Chrome/Edge/Opera/Safari 使用-webkit-。你可能在舊程式碼中遇到的其他可以安全刪除的字首包括-ms-,它被 Internet Explorer 和早期版本的 Edge 使用,以及-o,它在最初版本的 Opera 中使用。
字首功能原本不打算在生產網站中使用 - 它們可能會在沒有警告的情況下發生更改或刪除,可能會在需要它們的舊瀏覽器版本中造成效能問題,並且一直是跨瀏覽器問題的原因。這尤其是一個問題,例如,當開發人員決定只使用屬性的-webkit-版本時,這意味著該網站在其他瀏覽器中將無法正常工作。這種情況實際上發生的太多了,以至於其他瀏覽器供應商實現了幾個 CSS 屬性的-webkit-字首版本。雖然瀏覽器仍然支援一些字首屬性名稱、屬性值和偽類,但現在實驗性功能被放置在標誌後面,以便 Web 開發人員可以在開發期間測試它們。
如果使用字首,請確保它是必要的;該屬性是少數幾個剩餘的字首功能之一。你可以在 MDN 參考頁面上查詢哪些瀏覽器需要字首,以及像caniuse.com這樣的網站。如果你不確定,你也可以透過直接在瀏覽器中進行一些測試來找到答案。在帶字首的樣式宣告之後包含標準的非字首版本;如果該版本不受支援,則會忽略它,如果該版本受支援,則會使用它。
.masked {
-webkit-mask-image: url(MDN.svg);
mask-image: url(MDN.svg);
-webkit-mask-size: 50%;
mask-size: 50%;
}
嘗試這個簡單的例子
- 使用此頁面,或其他具有突出標題或其他塊級元素的網站。
- 右鍵/Command + 點選要檢查的元素,然後選擇檢查/檢查元素(或你瀏覽器中的任何選項)- 這應該會開啟瀏覽器中的開發工具,突出顯示 DOM 檢查器中的元素。
- 查詢可以用來選擇該元素的功能。例如,在撰寫本文時,MDN 上的此頁面有一個 ID 為
mdn-docs-logo的徽標。 - 將對該元素的引用儲存在一個變數中,例如js
const test = document.getElementById("mdn-docs-logo"); - 現在嘗試為該元素上感興趣的 CSS 屬性設定新值;你可以使用元素的style屬性來執行此操作,例如,嘗試在 JavaScript 控制檯中鍵入以下內容js
test.style.transform = "rotate(90deg)";
當你開始在第二個點之後鍵入屬性名稱表示形式時(請注意,在 JavaScript 中,CSS 屬性名稱以駱駝式編寫,而不是短橫線分隔式),JavaScript 控制檯應該開始自動完成瀏覽器中存在且與你到目前為止所寫內容匹配的屬性的名稱。這對於找出哪些屬性在該瀏覽器中實現很有用。
如果你確實需要包含現代功能,請使用@supports測試功能支援,它允許你實現本機功能檢測測試,並將字首或新功能巢狀在@supports塊中。
響應式設計問題
響應式設計是指建立能夠適應不同裝置外形尺寸的 Web 佈局的做法 - 例如,不同的螢幕寬度、方向(縱向或橫向)或解析度。例如,桌面佈局在移動裝置上檢視時會看起來很糟糕,因此你需要使用媒體查詢提供合適的移動佈局,並確保使用視窗正確應用它。你可以在響應式設計指南中找到有關此類做法的詳細說明。
解析度也是一個大問題 - 例如,移動裝置不太可能像桌上型電腦一樣需要大型、重量級的影像,而且移動裝置更有可能擁有速度較慢的網際網路連線,甚至可能擁有昂貴的資料計劃,這會使浪費的頻寬成為更大的問題。此外,不同的裝置可以具有各種不同的解析度,這意味著較小的影像可能會出現畫素化。有很多技術可以讓你解決這些問題,從媒體查詢到更復雜的響應式影像技術,包括<picture>和<img>元素的srcset和sizes屬性。
尋求幫助
你會遇到 HTML 和 CSS 的許多其他問題,因此瞭解如何在網上找到答案非常寶貴。
最好的支援資訊來源包括 Mozilla 開發者網路(你現在就在這裡!)、stackoverflow.com和caniuse.com。
為了使用 Mozilla 開發者網路 (MDN),大多數人會在搜尋引擎中搜索他們想要查詢資訊的科技,加上“mdn”一詞,例如“mdn HTML 影片”。MDN 包含幾種有用的內容型別
- 具有瀏覽器支援資訊的客戶端 Web 技術參考材料,例如<video> 參考頁面。
- 其他支援性參考材料,例如Web 上的媒體型別和格式指南。
- 解決特定問題的有用教程,例如建立跨瀏覽器影片播放器。
caniuse.com提供支援資訊,以及一些有用的外部資源連結。例如,請參見https://caniuse.com/#search=video(你只需將要搜尋的功能輸入文字框中)。
stackoverflow.com (SO) 是一個論壇網站,你可以在其中提問並讓其他開發人員分享他們的解決方案,查詢以前的帖子並幫助其他開發人員。建議你在釋出新問題之前檢視是否有問題的答案。例如,我們在 SO 上搜索了“停用 HTML 對話方塊的自動聚焦”,並且很快找到了使用 HTML 屬性停用 showModal 自動聚焦。
除此之外,嘗試使用你最喜歡的搜尋引擎搜尋問題的答案。如果你有錯誤資訊,搜尋特定錯誤資訊通常很有用 - 其他開發人員可能遇到過與你相同的問題。