欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
圣杯 & 双飞翼
 
说到「双飞翼」就不得不提及「圣杯」,两者均为三栏布局的优化解决方案如下图
 
常规情况下,我们的布局框架使用以下写法,从上到下,从左到右。
 
<header>header</header>
 
<section>
 
    <aside>left</aside>
 
    <section>main</section>
 
    <aside>right</aside>
 
</section>
 
<footer>footer</footer>
 
问题倒是没什么问题,然而,如果我们希望中部 main 部分优先显示的话,是可以做布局优化的。
 
因为浏览器渲染引擎在构建和渲染渲染树是异步的(谁先构建好谁先显示),那么将<section>main</section>部分提前即可优先渲染。
 
<header>header</header>
 
<section>
 
    <section>main</section>
 
    <aside>left</aside>
 
    <aside>right</aside>
 
</section>
 
<footer>footer</footer>
 
于是乎,国外的前辈就提出了「圣杯」布局,目的就是通过 css 的方式配合上面的 DOM 结构,优化 DOM 渲染。
 
我们来简要地了解一下「圣杯」布局,这不是重点。
 
demo :https://codepen.io/zwwill/pen/OBYXEa
 
<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 部分时就会发生布局混乱。
 
于是,淘宝软对针对「圣杯」的缺点做了优化,并提出「双飞翼」布局。
 
双飞翼布局
 
demo :https://codepen.io/zwwill/pen/oaRLao
 
<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 的大小高低如何,「双飞翼」布局都能正常显示,嗯——确实很优秀。
 
锤子和钉子
 
综上所见,「双飞翼」布局更胜一筹。但是,这是一个「锤子和钉子」的问题,我们应该拿着钉子找锤子,而不是拿着锤子找钉子,因为,当你有了最大的锤子,看到什么都是钉子。
 
唉——,我又在装逼了。 \(——︶——)/
 
说白了,就是,对症下药,没有最好的方案,只有最适合的。关于三栏布局,我帮大家列出一个对照表,以便大家快速选择。

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63390.shtml