忽然有一天,脑之里不知怎地蹦出一个词,「双飞翼」,这是好久之前的淘宝提出的一种三栏布局优化方案,然而,时间久了已经不记得(换句话说是不理解)为啥要提出这个布局了,昨天在 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...