概括地說(shuō),我把調(diào)試流程分為 3 個(gè)階段:
評(píng)估并快速修復(fù)
還原和重現(xiàn)
定位根源并修復(fù)
我們挨個(gè)解釋每個(gè)階段并實(shí)踐一個(gè)例子。
評(píng)估并快速修復(fù)
如果 CSS 是你的主要工作語(yǔ)言,或者你對(duì) CSS 有一定的理解和實(shí)踐經(jīng)驗(yàn)的話(huà),解決 CSS 問(wèn)題就有很多簡(jiǎn)單的方法,否則的話(huà),方法就少一些。
有經(jīng)驗(yàn)的 CSS 開(kāi)發(fā)者可能都知道的一些 CSS 陷阱:
圖片周邊存在有趣的空白?設(shè)置 display: block(圖片默認(rèn)是內(nèi)聯(lián)的,因此會(huì)有空白)。
元素排列不正確?你可能有浮動(dòng)的元素。
絕對(duì)定位元素不顯示、位置錯(cuò)誤或者被遮擋?你可能沒(méi)有設(shè)置父元素的 position 屬性或者用 transform 及 opacity 創(chuàng)建一個(gè) z-index 上下文。
偽元素不顯示?你可能忘記了設(shè)置 ‘content’的值。
這樣的 “bug” 有一大堆。實(shí)際上根本沒(méi)有 bug,更多的是開(kāi)發(fā)者缺少對(duì)瀏覽器行為的理解。更準(zhǔn)確地說(shuō),是 CSS 代碼讓瀏覽器怎么做。
對(duì)這些 CSS 特性熟悉的開(kāi)發(fā)者能夠快速定位到問(wèn)題并且修復(fù)。他們對(duì) bug 的認(rèn)識(shí)與那些對(duì) CSS 不了解的人會(huì)產(chǎn)生分歧。這樣在解決 CSS bug 中對(duì)‘工作流’需求的重要性的認(rèn)識(shí)就會(huì)因人而異。
對(duì)于‘快速修復(fù)’中沒(méi)有覆蓋的陌生問(wèn)題,在開(kāi)發(fā)者工具中靠猜來(lái)解決問(wèn)題的方式已經(jīng)沒(méi)什么價(jià)值。即使運(yùn)氣好問(wèn)題被解決了,也很難判斷出問(wèn)題到底是怎樣被解決的。
如果出現(xiàn)的問(wèn)題不能被輕易解決,先確定問(wèn)題區(qū)域的范圍,抓取 HTML 標(biāo)簽(也就是拷貝 DOM),進(jìn)入下一個(gè)調(diào)試階段:還原和重現(xiàn)。
專(zhuān)業(yè)提示:大多數(shù)瀏覽器的開(kāi)發(fā)者工具會(huì)讓你選擇包裹元素并拷貝 HTML 區(qū)塊。在 Chrome 的開(kāi)發(fā)者工具中,要連同包裹元素一起拷貝,需要點(diǎn)擊 ‘Copy > Copy OuterHTML’。
還原和重現(xiàn)
本階段的 CSS bug 修復(fù)在類(lèi)似 Codepen 的幫助下異常簡(jiǎn)單。我們目的主要是復(fù)現(xiàn)出此問(wèn)題 – 也就是引起 bug 的代碼。這能讓我們快速定位 bug,直搗黃龍。
為清晰起見(jiàn),只把相關(guān)的 HTML 和 CSS 提取出來(lái)復(fù)現(xiàn)問(wèn)題。你既可以手打 HTML 對(duì)應(yīng)的 CSS,也可以復(fù)制真實(shí)的代碼。如果可能的話(huà),不用把所有 CSS 代碼一股腦拷貝過(guò)去重現(xiàn)問(wèn)題,保證最精簡(jiǎn)的要素即可。保持逐步增加 CSS 的習(xí)慣,問(wèn)題就會(huì)自己找到你。
在快要接近真相時(shí),往往只需要一個(gè)特殊的 CSS 屬性的改變就能讓 bug 暴露出來(lái)。
相對(duì)應(yīng)的做法是,把所有 CSS 都扔進(jìn)入復(fù)現(xiàn)問(wèn)題,然后每次移除一點(diǎn),直到問(wèn)題出現(xiàn)。在實(shí)踐中,我發(fā)現(xiàn)這略笨,不用也因人而異,你可能有不同的見(jiàn)解。
逐步地增加或刪除 CSS 代碼已經(jīng)是重現(xiàn)問(wèn)題和定位故障的固定套路了。
那么 HTML 標(biāo)簽?zāi)兀?br/>
假設(shè)使用最少 CSS 代碼復(fù)現(xiàn)問(wèn)題時(shí),效果有如原始代碼一樣。這也是有用的,我們現(xiàn)在看 HTML 標(biāo)簽。
第一件事要做的,也是不能跳過(guò)的,就是檢查標(biāo)簽的有效性。即使報(bào)告出我們不關(guān)心的問(wèn)題(比如 meta),至少能保證它不會(huì)以某種方式破壞美感。我們希望能發(fā)現(xiàn)未閉合的標(biāo)簽、沒(méi)有引號(hào)的屬性,以及其它任何可能影響瀏覽器解析的問(wèn)題。建議你使用 W3C validator。
一旦標(biāo)簽檢查通過(guò),將有助于消除瀏覽器引入意外樣式的可能性。這樣做:
首先,把所有元素改成 div(塊級(jí)元素)和 span(行內(nèi)元素),保證它們只被 CSS 的類(lèi)選擇器選中。也許有必要把額外的選擇器移除,如把 a.link 改為 .link。
通過(guò)使用固定的標(biāo)簽我們消除了瀏覽器針對(duì)特定元素引入默認(rèn)樣式的可能性。表單元素是個(gè)特例(馬上會(huì)在例子中見(jiàn)到)。
如果把所有元素改成 div 和 span,問(wèn)題消失了,那么瀏覽器引入默認(rèn)樣式的嫌疑就被確定了。現(xiàn)在在 computed styles 面板中尋找瀏覽器增加了什么樣式,想辦法覆蓋它??傊褪且从?jì)算后的樣式。