忽然有一天,腦之裏不知怎地蹦出一個詞,「雙飛翼」,這是好久之前的淘寶提出的一種三欄佈局優化方案,然而,時間久了已經不記得(換句話說是不理解)爲啥要提出這個佈局了,昨天在 SF 上發起了一個提問,但良久未有人答覆,幸得@王能全是誰 提醒,終於回想起「雙飛翼」的完整意義了。謹以此文同你們分享這段心路歷程。javascript
說到「雙飛翼」就不得不說起「聖盃」,二者均爲三欄佈局的優化解決方案以下圖css
常規狀況下,咱們的佈局框架使用如下寫法,從上到下,從左到右。html
<header>header</header> <section> <aside>left</aside> <section>main</section> <aside>right</aside> </section> <footer>footer</footer>
問題卻是沒什麼問題,然而,若是咱們但願中部 main 部分優先顯示的話,是能夠作佈局優化的。前端
由於瀏覽器渲染引擎在構建和渲染渲染樹是異步的(誰先構建好誰先顯示),那麼將<section>main</section>
部分提早便可優先渲染。java
<header>header</header> <section> <section>main</section> <aside>left</aside> <aside>right</aside> </section> <footer>footer</footer>
因而乎,國外的前輩就提出了「聖盃」佈局,目的就是經過 css 的方式配合上面的 DOM 結構,優化 DOM 渲染。git
咱們來簡要地瞭解一下「聖盃」佈局,這不是重點。github
demo :https://jsfiddle.net/zwwill/p...segmentfault
<template> <header>header</header> <section class="wrapper"> <section class="col main">main</section> <aside class="col left">left</aside> <aside class="col right">right</aside> </section> <footer>footer</footer> </template> <style> /* 如下爲簡碼,僅保留關鍵部分 */ header,footer {height: 50px;} .wrapper {padding: 0 100px 0 100px; overflow:hidden;} .col {position: relative; float: left;} .main {width: 100%;height: 200px;} .left {width: 100px; height: 200px; margin-left: -100%;left: -100px;} .right {width: 100px; height: 200px; margin-left: -100px; right: -100px;} </style>
使用了 relative 相對定位
、float
(須要請浮動,此處使用 overflow:hidden;
方法)和 負值 margin
,將 left 和 right 部分「安裝」到 wrapper
的兩側,顧名「聖盃」。具體的思路我就再也不作贅述了,網上處處都是解釋。瀏覽器
固然,正常狀況下是沒有問題的,可是特殊狀況下就會暴露此方案的弊端,若是將瀏覽器無線變窄,「聖盃」將會「破碎」掉。如圖,當 main
部分的寬小於 left
部分時就會發生布局混亂。性能優化
因而,淘寶軟對針對「聖盃」的缺點作了優化,並提出「雙飛翼」佈局。
一樣的咱們來看簡碼
<template> <header>header</header> <section class="wrapper"> <section class="col main"> <section class="main-wrap">main</section> </section> <aside class="col left">left</aside> <aside class="col right">right</aside> </section> <footer>footer</footer> </template> <style> /* 如下爲簡碼,僅保留關鍵部分 */ header,footer {height: 50px;} .wrapper {padding: 0; overflow:hidden;} .col {float: left;} .main {width: 100%;} .main-wrap {margin: 0 100px 0 100px;height: 200px;} .left {width: 100px; height: 200px; margin-left: -100%;} .right {width: 100px; height: 200px; margin-left: -100px;} </style>
一樣使用了 float
和 負值 margin
,不一樣的是,並無使用 relative 相對定位
而是增長了 dom 結構,增長了一個層級。確實解決了聖盃佈局的缺陷。
雙飛翼佈局表面上看是很優秀,可是細細想來,爲何要多加一層 dom 樹節點,這豈不是增長了 css 樣式規則表和 dom 樹合併成佈局樹的計算量嗎?
細想一想,咱們可使用絕對佈局,將左右側邊欄定位到到兩側啊?好像也不會出現聖盃佈局的毛病?
<template> <header>header</header> <section class="wrapper"> <section class="col main">main</section> <aside class="col left">left</aside> <aside class="col right">right</aside> </section> <footer>footer</footer> </template> <style> /* 如下爲簡碼,僅保留關鍵部分 */ header,footer { height: 50px;} .wrapper { position: relative;} .main { height: 200px; margin:0 100px;} .left, .right{ width: 100px; height: 200px; position: absolute; top: 0;} .left{ left: 0;} .right{ right: 0;} </style>
沒有使用 float
(不用請浮動)也沒有 負值 margin
,僅僅使用了 absolute 絕對定位
,好像更優秀呢?
可是細細想一想,單純的絕對定位有一個問題,「高度不可控」,咱們假設,若是 left
部分的高度高於 main
,是否是 left
沒有能力撐起整個 wrapper
?
「四不四」~~!
那麼咱們再來看看雙飛翼和聖盃的狀況
都是下圖。
「應戳死聽」~~!
那這麼看來,全部的方案都或多或少存在一些問題。綜合來看,無論 left
, main
, right
的大小高低如何,「雙飛翼」佈局都能正常顯示,嗯~~確實很優秀。
綜上所見,「雙飛翼」佈局更勝一籌。可是,這是一個「錘子和釘子」的問題,咱們應該拿着釘子找錘子,而不是拿着錘子找釘子,由於,當你有了最大的錘子,看到什麼都是釘子。
唉~,我又在裝逼了。 ( ̄︶ ̄)/
說白了,就是,對症下藥,沒有最好的方案,只有最適合的。關於三欄佈局,我幫你們列出一個對照表,以便你們快速選擇。
優勢 | 缺點 | |
---|---|---|
聖盃 | 結構簡單,無多餘 dom 層 | 中間部分寬度小於左側時佈局混亂 |
絕對定位 | 結構簡單,且無需清理浮動 | 兩側高度沒法支撐總高度 |
雙飛翼 | 支持各類寬高變化,通用性強 | dom 結構多餘層,增長渲染樹生成的計算量 |
以上爲我的理解,若有不對或可補充之處,還請指點。
另外關於 CSS 佈局方案,和前端性能優化部分,移駕一下文章
多行多列類佈局方案總結
前端性能優化總結
轉載請標明出處
做者:木羽 zwwill
首發地址:https://github.com/zwwill/blo...