經(jīng)典面試題:瀏覽器是怎樣解析CSS的?

摘要: 理解瀏覽器原理议纯。

解析

一旦 CSS 被瀏覽器下載崩溪,CSS 解析器就會被打開來處理它遇到的任何 CSS运嗜。這可以是單個(gè)文檔內(nèi)的 CSS、<style>標(biāo)記內(nèi)的 CSS悯舟,也可以是 DOM 元素的style屬性內(nèi)嵌的 CSS担租。所 有 CSS 都根據(jù)語法規(guī)范進(jìn)行解析和標(biāo)記。解析完成后抵怎,就會生成有一個(gè)包含所有選擇器奋救、屬性和屬性各自值的數(shù)據(jù)結(jié)構(gòu)。

例如反惕,考慮以下 CSS:

.fancy-button {
    background: green;
    border: 3px solid red;
    font-size: 1em;
}

以上 CSS 片段將生成如下數(shù)據(jù)結(jié)構(gòu)尝艘,以便在后續(xù)的過程中方便使用:

值得注意的一件事是,瀏覽器將 backgroundborder 的簡寫還原成普通寫法姿染,也就是一個(gè)一個(gè)屬性的聲明背亥,因?yàn)楹唵螌懼饕奖汩_發(fā)人員的編寫,但從這里開始悬赏,瀏覽器只處理普通寫法狡汉。完解析成之后,瀏覽器引擎繼續(xù)構(gòu)建 DOM 樹闽颇。

計(jì)算

既然我們已經(jīng)解析了現(xiàn)有內(nèi)容中的所有樣式盾戴,接著就是對它們進(jìn)行樣式計(jì)算了。我們嘗試盡量對所有值減少到一個(gè)標(biāo)準(zhǔn)化的計(jì)算值兵多。當(dāng)離開計(jì)算階段時(shí)尖啡,任何維度值都被縮減為三個(gè)可能的輸出之一:auto橄仆、百分比或像素值。為了清晰起見衅斩,讓我們看幾個(gè)例子盆顾,看 web 開發(fā)人員寫了什么,以及計(jì)算后的結(jié)果:

現(xiàn)在我們已經(jīng)計(jì)算了數(shù)據(jù)存儲中的所有值畏梆,是時(shí)候處理級聯(lián)了椎扬。

級聯(lián)

由于 CSS 來源有多種,所以瀏覽器需要一種方法來確定哪些樣式應(yīng)該應(yīng)用于給定的元素具温。為此蚕涤,瀏覽器使用一個(gè)名為 特殊性(specificity) 的公式,它計(jì)算選擇器中使用的標(biāo)記铣猩、類揖铜、id 和屬性選擇器的數(shù)值,以及 !important聲明的數(shù)值达皿。

通過內(nèi)聯(lián) style 屬性在元素上定義的樣式被賦予一個(gè)等級天吓,該等級優(yōu)先于 <style> 塊或外部樣式表中的任何樣式。如果 Web 開發(fā)人員使用 !important 某個(gè)值峦椰,則該值將勝過任何 CSS龄寞,無論其位置如何,除非還有 !important 內(nèi)聯(lián)汤功。

同一級別的個(gè)數(shù)物邑,數(shù)量多的優(yōu)先級高,假設(shè)同樣即比較下一級別的個(gè)數(shù)滔金。至于各級別的優(yōu)先級例如以下:

!important > 內(nèi)聯(lián) > ID > 類 > 標(biāo)簽 | 偽類 | 屬性選擇 > 偽對象 > 通配符 > 繼承

選擇器的特殊性由選擇器本身的組件確定色解,特殊性值表述為 5 個(gè)部分,如:

0餐茵,0科阎,1,0忿族,1

(1)锣笨、對于選擇器中給定的各個(gè) !important 屬性值,加 1道批,0错英,0,0屹徘,0 走趋。

(2)、對于選擇器中給定的各個(gè) ID 屬性值噪伊,加 0簿煌,0,1鉴吹,0姨伟,0 。

(3)豆励、對于選擇器中給定的各個(gè)類屬性值夺荒、屬性選擇器或偽類,加 0良蒸,0技扼,0,1嫩痰,0 剿吻。

(4)、對于選擇器中給定的各個(gè)元素和偽元素串纺,加 0丽旅,0,0纺棺,0榄笙,1 。偽元素是否具有特殊性祷蝌?在這方面 CSS2 有些自相矛盾茅撞,不過 CSS2.1 很清楚的指出,偽元素具有特殊性巨朦,而且特殊性為 0乡翅,0,0罪郊,0蠕蚜,1,同元素特殊性相同悔橄。

(4)靶累、結(jié)合符(+ > [] ^= $= 等等特殊符號)和通配符(*)對特殊性沒有任何貢獻(xiàn),此外通配符的特殊性為 0癣疟,0挣柬,0,0睛挚,0邪蛔。全是 0 有什么意義呢?當(dāng)然有意義扎狱!子元素繼承祖先元素的樣式根本沒有特殊性侧到,因此當(dāng)出現(xiàn)這種情況后勃教,通配符選擇器定義的樣式聲明也要優(yōu)先于子元素繼承來的樣式聲明。因?yàn)榫退闾厥庑允?0匠抗,也比沒有特殊性可言要強(qiáng)故源。

為了說明這一點(diǎn),讓我們說明一些選擇器及其計(jì)算后的權(quán)重?cái)?shù)值:

而當(dāng)優(yōu)先級與多個(gè) CSS 聲明中任意一個(gè)聲明的優(yōu)先級相等的時(shí)候汞贸,CSS 中最后的那個(gè)聲明將會被應(yīng)用到元素上绳军。

在下面的示例中,div 將具有藍(lán)色背景矢腻。

div {
  background: red;
}

div {
  background: blue;
}

現(xiàn)在 CSS 將生成以下數(shù)據(jù)結(jié)構(gòu)门驾,在本文中,我們將繼續(xù)在此基礎(chǔ)上進(jìn)行構(gòu)建多柑。

來源

CSS 也有來源奶是,但它們的用途不同:

CSS 信息可以從各種來源提供,這些來源可以是 用戶(user) 和 作者(author) 及 用戶代理/瀏覽器(user agent)顷蟆,優(yōu)先級如下:

用戶樣式

瀏覽器還允許用戶設(shè)置網(wǎng)頁的樣式诫隅,例如,我們用 IE 瀏覽網(wǎng)站的時(shí)候帐偎,都可以通過瀏覽器查看菜單下的樣式或者文字大小子菜單來設(shè)置網(wǎng)頁實(shí)際的顯示效果逐纬。

作者樣式

網(wǎng)頁創(chuàng)建者建立的樣式表,一般會 css 文件出現(xiàn)或者是在頁面頭部里定義的 style削樊,也就是網(wǎng)站源代碼的一部分豁生。例如,大家看百度和谷歌的頁面就不一樣漫贞,這就是作者樣式不一樣的結(jié)果甸箱。

用戶代理/瀏覽器樣式

也就是瀏覽器自身設(shè)置用來顯示網(wǎng)站的樣式,不同的瀏覽器可能有不同的樣式表迅脐,例如 IE 和 Firefox 的就不一樣芍殖,所以大家分別使用這兩種瀏覽器訪問同一個(gè)網(wǎng)站的時(shí)候,看到實(shí)際效果可能就不同谴蔑。

通常情況下豌骏,作者樣式具有最高的重要性,其次是用戶樣式隐锭,最后才是瀏覽器樣式窃躲,但是如果出現(xiàn)了 !important 標(biāo)記的話,那么規(guī)則會被改變钦睡,通過 !important 可以提高某種樣式的重要性蒂窒,讓它的優(yōu)先級高于其他沒有加該聲明的所有樣式。

讓我們進(jìn)一步擴(kuò)展我們的數(shù)據(jù)集,看看當(dāng)用戶將瀏覽器的字體大小設(shè)置為最小 2em 時(shí)會發(fā)生什么:

做級聯(lián)

當(dāng)瀏覽器擁有一個(gè)完整的數(shù)據(jù)結(jié)構(gòu)洒琢,包含來自所有源的所有聲明時(shí)秧秉,它將按照規(guī)范對它們進(jìn)行排序。首先纬凤,它將按來源排序福贞,然后按特性(specificity)排序撩嚼,最后按文檔順序排序停士。

從上圖可知,類名為 .fancy-button優(yōu)先級最高(表中越上面優(yōu)先級越高)完丽。例如恋技,從上表中,人會注意到用戶的瀏覽器首選項(xiàng)設(shè)置優(yōu)先 于 Web 開發(fā)人員的設(shè)置樣式÷咦澹現(xiàn)在蜻底,瀏覽器找到與選擇器匹配的所有 DOM 元素,并將得到的計(jì)算樣式掛載到匹配的元素聘鳞,在本例中 div 為類名為 .fancy-button

如果您希望了解更多關(guān)于級聯(lián)的工作原理薄辅,請查看官方規(guī)范

CSS 對象模型

雖然到目前為止我們已經(jīng)做了很多抠璃,但還沒有完成≌境現(xiàn)在我們需要更新 CSS 對象模型(CSSOM)。 CSSOM 位于document.stylesheets 中搏嗡,我們需要對其進(jìn)行更新窿春,以便讓它知道我們目前為止已經(jīng)解析和計(jì)算的所有內(nèi)容。

Web 開發(fā)人員可能在沒有意識到的情況下使用這些信息采盒。例如旧乞,當(dāng)調(diào)用 getComputedStyle() 時(shí),如果需要磅氨,運(yùn)行上面指出的相同過程

布局

現(xiàn)在我們已經(jīng)應(yīng)用了一個(gè)具有樣式的 DOM 樹尺栖,然后開始構(gòu)建一個(gè)用于可視化目的的樹了。這棵樹出現(xiàn)在所有現(xiàn)代引擎中烦租,被稱為盒子樹(box tree)延赌。為了構(gòu)造這棵樹,我們遍歷 DOM 樹并創(chuàng)建零個(gè)或多個(gè) CSS 盒子左权,每個(gè)盒子都有一個(gè) margin皮胡、borderpaddingcontent 赏迟。

在本節(jié)中屡贺,我們將討論以下 CSS 布局概念:

  • 格式化上下文(FC):有許多類型的格式化上下文,其中大多數(shù) Web 開發(fā)人員通過更改 display 元素的值來調(diào)用。一些最常見的格式化上下文是塊(塊格式化上下文或BFC)甩栈,flex泻仙,grid,table-cells 和 inline量没。其他一些 CSS 也可以強(qiáng)制使用新的格式化上下文玉转,例如 position: absolutefloat 或使用 multi-colum殴蹄。
  • 包含塊:這是用于解析樣式的祖先塊究抓。
  • 內(nèi)聯(lián)方向:這是文本布局的方向,由元素的書寫模式?jīng)Q定袭灯。 在拉丁語言中刺下,這是水平軸,在 CJK 語言中稽荧,這是垂直軸橘茉。
  • 塊方向:此行為與內(nèi)聯(lián)方向完全相同,但與內(nèi)聯(lián)軸垂直姨丈。因此畅卓,對于基于拉丁語的語言,這是垂直軸蟋恬,而在 CJK 語言中翁潘,這是水平軸。

解析 Auto

請記住筋现,在計(jì)算階段唐础,維度值可以是三個(gè)值之一:auto、百分?jǐn)?shù)或像素矾飞。布局的目的是在Box Tree中調(diào)整所有盒子的大小和位置一膨,使它們?yōu)槔L制做好準(zhǔn)備。

下面示例可以更容易地理解Box Tree是如何構(gòu)建的洒沦。為了便于理解豹绪,這里不顯示單獨(dú)的 CSS 框,只顯示主盒(principal box)申眼。讓我們看看一個(gè)基本的 “Hello world” 布局使用以下代碼:

<body>
    <p>Hello world</p>
    <style>
        body {
            width: 50px;
        }
    </style>
</body>

瀏覽器從 body 元素開始瞒津,生成它的主盒(principal box),它的寬度為50px括尸,默認(rèn)高度為auto巷蚪。

現(xiàn)在移動到 p 標(biāo)簽并生成其主盒(principal box),并且由于 p 標(biāo)簽?zāi)J(rèn)有邊距(margin)濒翻,這將影響正文的高度屁柏,如下所示:

現(xiàn)在瀏覽器移動到 “Hello world” 文本啦膜,這是 DOM 中的文本節(jié)點(diǎn)。因此淌喻,我們在布局中生成一個(gè) 行內(nèi)盒(line box) 僧家。請注意,文本溢出了正文裸删,我們將在下一步處理這個(gè)問題八拱。

因?yàn)榧由稀皐orld”長度后實(shí)際長度比較設(shè)置大并且我們沒有設(shè)置 overflow 屬性,所以引擎會向其父級報(bào)告它在布局文本時(shí)停止的位置涯塔。

由于父級已收到其子級無法完成所有內(nèi)容布局的指令肌稻,因此它會克隆包含所有樣式的 行內(nèi)盒(line box),并傳遞該框的信息以完成布局伤塌。

布局完成后灯萍,瀏覽器會返回 box tree轧铁,解析尚未解決的所有基于 auto 或基于百分比的值每聪。 在圖中,可以看到正文和段落現(xiàn)在包含所有 “Hello world”齿风,因?yàn)樗?height 設(shè)置為 auto药薯。

代碼部署后可能存在的 BUG 沒法實(shí)時(shí)知道,事后為了解決這些 BUG救斑,花了大量的時(shí)間進(jìn)行 log 調(diào)試童本,這邊順便給大家推薦一個(gè)好用的 BUG 監(jiān)控工具 Fundebug

處理浮動 float

現(xiàn)在讓布局變得更復(fù)雜一點(diǎn)脸候。我們將使用一個(gè)普通布局穷娱,其中有一個(gè)按鈕,內(nèi)容為 “Share It”运沦,并將其浮動到一段文本的左側(cè)泵额。浮動本身被認(rèn)為是“shrink-to-fit” 上下文。之所以將其稱為“shrink-to-fit”携添,是因?yàn)槿绻叽缡亲詣拥募廾ぃ瑒t該框?qū)@其內(nèi)容進(jìn)行收縮。

浮動盒子是與這種布局類型匹配的盒子的一種類型烈掠,但是還有許多其他的盒子羞秤,例如絕對定位盒子(包括 position: fixed)和基于自動調(diào)整大小的表格單元格,如下代碼:

<article>
    <button>SHARE IT</button>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
        pellentesq
    </p>
</article>
<style>
    article {
        min-width: 400px;
        max-width: 800px;
        background: rgb(191, 191, 191);
        padding: 5px;
    }

    button {
        float: left;
        background: rgb(210, 32, 79);
        padding: 3px 10px;
        border: 2px solid black;
        margin: 5px;
    }

    p {
        margin: 0;
    }
</style>

該過程開始時(shí)遵循與“Hello world”示例相同的模式左敌,因此我將跳到我們開始處理浮動按鈕的位置瘾蛋。

由于浮動創(chuàng)建了一個(gè)新的塊格式化上下文(BFC),并且是一個(gè) shrink-to-fit 上下文矫限,因此瀏覽器執(zhí)行一種稱為內(nèi)容度量的特定布局類型哺哼。

在這種模式下京革,它看起來與其他布局相同,但有一個(gè)重要的區(qū)別幸斥,即它是在無限空間中完成的匹摇。在此階段,瀏覽器所做的就是以 BFC 的最大和最小寬度布局 BFC 樹甲葬。

在本例中廊勃,它使用文本布局一個(gè)按鈕,因此其最窄的大小(包括所有其他 CSS 框)將是最長單詞的大小经窖。在最寬的地方坡垫,它將是一行的所有文本,加上 CSS Box画侣。注意:這里按鈕的顏色不是文字的顏色冰悠。這只是為了說明問題。

現(xiàn)在我們知道最小寬度是 86px配乱,最大寬度是 115px溉卓,我們將此信息傳遞回父類的 box,讓它決定寬度并適當(dāng)?shù)胤胖冒粹o搬泥。在這個(gè)場景中桑寨,有足夠的空間來適應(yīng)浮動的最大大小,這就是按鈕的布局方式忿檩。

為了確保瀏覽器遵循標(biāo)準(zhǔn)尉尾,并且內(nèi)容圍繞浮動,瀏覽器更改了 article 的 BFC 的幾何形狀燥透。這個(gè)幾何圖形被傳遞給段落沙咏,以便在段落布局期間使用。

從這里開始班套,瀏覽器遵循與第一個(gè)示例相同的布局過程——但是它確保任何內(nèi)聯(lián)內(nèi)容的內(nèi)聯(lián)和塊的起始位置都位于浮動所占用的約束空間之外肢藐。

當(dāng)瀏覽器繼續(xù)沿著樹向下移動并克隆節(jié)點(diǎn)時(shí),它將越過約束空間的塊位置孽尽。這允許最后一行文本(以及它之前的一行)以內(nèi)聯(lián)方向開始于 content box 的開頭窖壕。然后瀏覽器返回到樹中,根據(jù)需要解析 auto 和百分?jǐn)?shù)杉女。

了解片段(UNDERSTANDING FRAGMENTATION

關(guān)于布局如何工作的最后一個(gè)方面是碎片化瞻讽。 如果你曾經(jīng)打印過網(wǎng)頁或使用過 CSS 多列,那么你已經(jīng)利用了碎片熏挎。 碎片化是將內(nèi)容分開以使其適合不同幾何形狀的邏輯速勇。 讓我們來看看同一個(gè)例子,利用 CSS 多列情況:

<body>
    <div>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nibh
            orci, tincidunt eget enim et, pellentesque condimentum risus. Aenean
            sollicitudin risus velit, quis tempor leo malesuada vel. Donec
            consequat aliquet mauris. Vestibulum ante ipsum primis in faucibus
        </p>
    </div>
    <style>
        body {
            columns: 2;
            column-fill: auto;
            height: 300px;
        }
    </style>
</body>

一旦瀏覽器到達(dá) multicol 格式化上下文盒子坎拐,它就會看到它有一組設(shè)定的列烦磁。

它遵循以前類似的克隆模型养匈,并創(chuàng)建了一個(gè)具有正確維度的碎片處理程序,以滿足作者對其列的要求都伪。

然后瀏覽器按照與之前相同的模式盡可能多地布局行呕乎,然后瀏覽器創(chuàng)建另一個(gè)碎片管理器,并繼續(xù)完成布局陨晶。

繪畫(Painting)

來回顧一下我們現(xiàn)在的情況猬仁,我們?nèi)〕鏊械?CSS 內(nèi)容,對其進(jìn)行解析先誉,將其級聯(lián)到 DOM 樹中湿刽,并完成布局。但是我們還沒有對布圖應(yīng)用顏色褐耳、邊框诈闺、陰影和類似的設(shè)計(jì)處理——處理這些過程被稱為繪畫

繪畫基本上是由 CSS 標(biāo)準(zhǔn)化的铃芦,簡單地說雅镊,你可以按照以下順序繪畫:

  • background;
  • border;
  • and content.

更多繪畫的順序可查看 CSS 2.2 Appendix E

因此杨帽,如果我們從前面的“SHARE IT”按鈕開始漓穿,并遵循這個(gè)過程,它繪制過程大致如下:

完成后注盈,它將轉(zhuǎn)換為位圖,最終每個(gè)布局元素(甚至文本)都成為引擎中的圖像叙赚。

關(guān)于 Z-INDEX

現(xiàn)在老客,我們大多數(shù)的網(wǎng)站都不是由單一的元素組成的。此外震叮,我們經(jīng)常希望某些元素出現(xiàn)在其他元素之上胧砰。為了實(shí)現(xiàn)這一點(diǎn),我們可以利用 z-index 的特性將一個(gè)元素疊加到另一個(gè)元素上苇瓣。

這可能感覺就像我們在設(shè)計(jì)軟件中使用圖層一樣尉间,但是唯一存在的圖層是在瀏覽器的合成器中』髯铮看起來好像我們在使用 z-index 創(chuàng)建新層哲嘲,但實(shí)際上并不是這樣,那么到底是怎么樣呢?

我們要做的是創(chuàng)建一個(gè)新的堆棧上下文媳禁。創(chuàng)建一個(gè)新的堆疊上下文可以有效地改變你繪制元素的順序眠副。讓我們來看一個(gè)例子:

<body>
    <div id="one">
        Item 1
    </div>
    <div id="two">
        Item 2
    </div>
    <style>
        body {
            background: lightgray;
        }
        div {
            width: 300px;
            height: 300px;
            position: absolute;
            background: white;
            z-index: 2;
        }
        #two {
            background: green;
            z-index: 1;
        }
    </style>
</body>

如果沒有使用 z-index,上面的文檔將按照文檔順序繪制竣稽,這將把 “Item 2” 置于 “Item 1” 之上囱怕。但由于 z-index 的影響霍弹,繪畫順序發(fā)生了變化。讓我們逐步完成每個(gè)階段娃弓,類似于我們之前完成布局的方式典格。

瀏覽器以根框開頭,我們在后臺畫畫台丛。

然后瀏覽器按照文檔順序遍歷較低層次的堆棧上下文(在本例中是“Item 2”)钝计,并開始按照上面的規(guī)則繪制該元素。

然后它遍歷到下一個(gè)最高的堆棧上下文(在本例中是“Item 1”)齐佳,并按照 CSS 2.2 中定義的順序繪制它私恬。

z-index 不影響顏色,只影響哪些元素對用戶可見炼吴,因此也不影響哪些文本和顏色可見本鸣。

組成(COMPOSITION)

在這個(gè)階段,我們至少有一個(gè)位圖從繪畫傳遞到合成硅蹦。合成程序的工作是創(chuàng)建一個(gè)或多個(gè)層荣德,并將位圖呈現(xiàn)到屏幕上供最終用戶查看。

此時(shí)一個(gè)合理的問題是童芹,“為什么任何站點(diǎn)都需要不止一個(gè)位圖或合成層?”涮瞻,根據(jù)我們目前看到的例子,我們真的不會這么做假褪。我們來看一個(gè)稍微復(fù)雜一點(diǎn)的例子署咽。假設(shè)在一個(gè)假設(shè)的世界中,Office 團(tuán)隊(duì)想讓 Clippy 重新上線生音,他們想通過 CS S 轉(zhuǎn)換讓 Clippy 跳動來吸引人們對他的注意宁否。

動畫 Clippy 的代碼可以是這樣的:

<div class="clippy"></div>
<style>
    .clippy {
        width: 100px;
        height: 100px;
        animation: pulse 1s infinite;
        background: url(clippy.svg);
    }

    @keyframes pulse {
        from {
            transform: scale(1, 1);
        }
        to {
            transform: scale(2, 2);
        }
    }
</style>

當(dāng)瀏覽器讀取 web 開發(fā)人員希望在無限循環(huán)中為 Clippy 添加動畫時(shí),它有兩個(gè)選項(xiàng):

  • 它可以返回到動畫的每一幀的重繪階段缀遍,并生成一個(gè)新的位圖以返回合成器慕匠。
  • 或者它可以生成兩個(gè)不同的位圖,并允許合成程序僅在應(yīng)用了該動畫的層上執(zhí)行動畫本身域醇。

在大多數(shù)情況下台谊,瀏覽器將選擇選項(xiàng) 2 并生成以下內(nèi)容(我有意簡化了 Word Online 為此示例生成的圖層數(shù)量):

然后,它將重新組合剪輯位圖在正確的位置譬挚,并處理脈動動畫锅铅。這對于性能來說是一個(gè)很好的優(yōu)勢,因?yàn)樵谠S多引擎中殴瘦,合成程序是在它自己的線程上的狠角,這樣就可以解除主線程的阻塞。如果瀏覽器選擇上面的選項(xiàng) 1蚪腋,它將不得不阻塞每一幀以完成相同的結(jié)果丰歌,這將對最終用戶的性能和響應(yīng)能力產(chǎn)生負(fù)面影響姨蟋。

創(chuàng)造互動的視覺

正如我們剛剛了解到的,我們使用了所有的樣式和 DOM立帖,并生成了一個(gè)呈現(xiàn)給最終用戶的圖像眼溶。那么瀏覽器如何創(chuàng)建交互性的假象呢?嗯,我相信你現(xiàn)在已經(jīng)學(xué)過了晓勇,所以讓我們看一個(gè)例子堂飞,用我們的 “SHARE IT” 按鈕作為類比:

button {
    float: left;
    background: rgb(210, 32, 79);
    padding: 3px 10px;
    border: 2px solid black;
}

button:hover {
    background: teal;
    color: black;
}

我們在這里添加的是一個(gè)偽類,它告訴瀏覽器在用戶懸停在按鈕上時(shí)更改按鈕的背景和文本顏色绑咱。這就引出了一個(gè)問題绰筛,瀏覽器如何處理這個(gè)問題?

瀏覽器不斷跟蹤各種輸入,當(dāng)這些輸入正在移動時(shí)描融,它會經(jīng)歷稱為命中測試的過程铝噩。 對于此示例,該過程如下所示:

  1. 用戶將鼠標(biāo)移到按鈕上窿克。
  2. 瀏覽器觸發(fā)鼠標(biāo)已移動的事件骏庸,并進(jìn)入命中測試算法,該算法本質(zhì)上是問“鼠標(biāo)正在觸摸哪個(gè) box”
  3. 該算法返回鏈接到我們的 “SHARE IT” 按鈕年叮。
  4. 瀏覽器會問這個(gè)問題:“既然有鼠標(biāo)在你上方盤旋具被,我應(yīng)該做什么?”。
  5. 它快速運(yùn)行此框及其子框的樣式/級聯(lián)只损,并確定:hover 在聲明塊內(nèi)部有一個(gè)僅使用繪制樣式調(diào)整的偽類一姿。
  6. 它將這些樣式掛起 DOM 元素(正如我們在級聯(lián)階段所學(xué)到的),在這種情況下是按鈕改执。
  7. 它跳過布局啸蜜,直接繪制一個(gè)新的位圖。
  8. 新的位圖被傳遞給合成程序辈挂,然后傳遞給用戶。

總結(jié)

希望這部分對你關(guān)于 css 解析過程多多少少有點(diǎn)幫助裹粤,共進(jìn)步终蒂!

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序遥诉、微信小游戲拇泣、支付寶小程序、React Native矮锈、Node.js和Java線上應(yīng)用實(shí)時(shí)BUG監(jiān)控霉翔。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了10億+錯(cuò)誤事件,付費(fèi)客戶有Google复斥、360偶妖、金山軟件管钳、百姓網(wǎng)等眾多品牌企業(yè)歼培。歡迎大家免費(fèi)試用靡狞!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末我衬,一起剝皮案震驚了整個(gè)濱河市鲤遥,隨后出現(xiàn)的幾起案子谚中,更是在濱河造成了極大的恐慌渴杆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪塔,死亡現(xiàn)場離奇詭異磁奖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)某筐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門比搭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人来吩,你說我怎么就攤上這事敢辩。” “怎么了弟疆?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵戚长,是天一觀的道長。 經(jīng)常有香客問我怠苔,道長同廉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任柑司,我火速辦了婚禮迫肖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘攒驰。我一直安慰自己蟆湖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布玻粪。 她就那樣靜靜地躺著隅津,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劲室。 梳的紋絲不亂的頭發(fā)上伦仍,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機(jī)與錄音很洋,去河邊找鬼充蓝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谓苟。 我是一名探鬼主播官脓,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娜谊!你這毒婦竟也來了确买?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤纱皆,失蹤者是張志新(化名)和其女友劉穎湾趾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體派草,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搀缠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了近迁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艺普。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鉴竭,靈堂內(nèi)的尸體忽然破棺而出歧譬,到底是詐尸還是另有隱情,我是刑警寧澤搏存,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布瑰步,位于F島的核電站,受9級特大地震影響璧眠,放射性物質(zhì)發(fā)生泄漏缩焦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一责静、第九天 我趴在偏房一處隱蔽的房頂上張望袁滥。 院中可真熱鬧,春花似錦灾螃、人聲如沸题翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽藐握。三九已至,卻和暖如春垃喊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袜炕。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工本谜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人偎窘。 一個(gè)月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓乌助,卻偏偏與公主長得像溜在,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子他托,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容