圣杯布局和双飞翼布局的原理探究

297 阅读5分钟

浮动布局并不是再是流行的布局方式,不过基于浮动的经典布局还是经常出现在前端面试中,圣杯布局和双飞翼布局就是其中常考核的知识点。圣杯布局和双飞翼布局都是前端中三列设计布局方式,要求主要中间内容优先渲染,左右内容宽度固定,中间主要内容宽度自适应排布。圣杯布局和双飞翼布局都没有使用绝对定位,而是应用浮动、负外边距以及相对定位这几个核心知识点来实现。

圣杯布局

圣杯布局是让左右固定栏和中间自适应的主内容栏处于同一容器包裹中,容器(#container)设置padding-left、padding-right值,其中padding-left值与左侧栏(#left)的宽度值相等,padding-right值与右侧栏(#right)的宽度值相等,中间自适应栏的宽度设置为100%,让中间自适应栏的宽度与容器的内容盒宽度相等。通过定位设置让左侧栏(#left)在中间栏(# center)左侧恰好容纳容器padding-left的空间,右侧栏(# right)在中间栏(# center)右侧恰好容纳容器padding-right的空间。

圣杯布局的主要框架草图如下所示:

圣杯布局的HTML架构代码:

<``div id='header'>#header</``div``>

<``div id='container'>

<``div id='center'>#center</``div``>

<``div id='left'>#left</``div``>

<``div id='right'>#right</``div``>

</``div``>

<``div id='footer'>#footer</``div``>

圣杯布局的CSS代码:

* {

border-width``: 0``;

}

body {

min-width``: 350px``;

}

#header,

#footer {

height``: 100px``;

background``: #ccc``;

}

#container {

padding-left``: 200px``;

padding-right``: 150px``;

box-sizing:border-box;

min-width``:``550px``;

}

#``center {

float``: left``;

width``: 100%``;

background``: #f96d9f``;

}

#``left {

width``: 200px``;

float``: left``;

margin-left``: -100%``;

position``: relative``;

left``: -200px``;

background``: aqua``;

}

#``right {

width``: 150px``;

float``: left``;

margin-right``: -150px``;

background``: yellowgreen;

}

#``left``,

#``right``,

#``center {

min-height``: 100px``;

}

/* 外围样式 */

#header,

#footer,

#``center``,

#``left``,

#``right {

display``: flex;

justify-``content``: center``;

align-items: center``;

font-family``: 'Source Code Pro'``;

font-size``: 20px``;

}

#footer {

clear``: both``;

}

外围样式是为了文字美化居中而设置的代码,并非圣杯布局CSS代码主体部分。圣杯布局的代码的核心难点是如何不通过绝对定位来让文档流中后面的元素位于前面元素,这里运用了浮动、负外边距以及相对定位来实现。

这是左侧栏的核心代码:

#left {

width: 200px;

float: left;

margin-left: -100%;

position: relative;

left: -200px;

}

这里margin-left: -100%;由于负外边距-100%计算值是宿主元素内容盒模型的宽度,其宽度大于左侧栏宽度200px。所以浮动的左侧栏通过负外边距上浮到上层,以中间栏(#center)的右侧外边缘为基准线,向左侧移动相当于宿主元素内容盒模型宽度的距离,恰好位于中间栏(#center)的左侧,占据容器(#container)padding-left的位置。

#``right {

width``: 150px``;

float``: left``;

margin-right``: -150px``;

}

当左侧栏(#left)由于负外边距上移后,右侧栏(#right)由于左浮动位于容器(#container)的内侧左边缘。同样负外边距 margin-right: -150px; 设置令右侧栏(#right)上移,同样是以中间栏(#center)的右侧外边缘为基准线作为右侧栏(#right)的最左侧边接触。

这样通过对浮动元素左、右负边距的设置,令原本位于中间栏(#center)下方的浮动元素左侧栏(#left)、右侧栏(#right)上移是圣杯布局的理解难点。

圣杯布局的最小尺寸问题

圣杯布局是基于左侧栏(#left)负外边距 margin-left: -100%;设置来实现的,但是左侧栏上移有个前提条件,就是margin-left的负值与左侧栏(#left)自身的内容宽度相加后的值不大于上一行剩余空间,才可以实现左侧栏(#left)上移。这里中间栏(#center)完全占据上一行剩余空间,margin-left的负值与左侧栏(#left)自身的内容宽度相加后的值不大于0才可以上移,否则左侧栏(#left)仍然停留在第二行,就无法实现圣杯布局目的。所以中间栏(#center)的宽度需要不小于左侧栏(#left)宽度,才能满足圣杯布局的实现。

圣杯布局的最小尺寸计算:若左侧栏(#left)的宽度为X,右侧栏的宽度为Y,那么容器(#container)最小尺寸计算:2X+Y。

在上述实例中,圣杯布局最小尺寸为2x200+150=550px。所以容器(#container)需要设置最小尺寸min-width:550px;,同时这里550px是容器边框盒的尺寸,为了避免采用默认内容盒尺寸进行转换计算,就采用设置:box-sizing:border-box;。

#container {

padding-left``: 200px``;

padding-right``: 150px``;

box-sizing:border-box;

min-width``:``550px``;

}

双飞翼布局

双飞翼布局同样未采用绝对定位,它是在圣杯布局的基础上进行改进的布局形式。双飞翼布局布局中左侧栏(#left)、右侧栏(#right)、中间栏(#center)都是兄弟元素。通过中间栏(#center)的内部元素(# inner)设置左右外边距为左侧栏(#left)、右侧栏(#right)预留位置空间,其余通过负边距设置令浮动元素上移的设置原理相同。

双飞翼布局的结构示意图:

双飞翼布局HTML代码:

<div id=``'header'``>#header</div>

<div id=``'center'``>

<div id=``'inner'``>``center``</div>

</div>

<div id=``'left'``>#``left``</div>

<div id=``'right'``>#``right``</div>

<div id=``'footer'``>#footer</div>

双飞翼布局CSS代码:

* {

border-width``: 0``;

}

body {

min-width``: 350px``;

}

#header,

#footer {

height``: 100px``;

background``: #ccc``;

}

#container {

padding-left``: 200px``;

padding-right``: 150px``;

box-sizing: border-box;

min-width``: 550px``;

}

#``center {

float``: left``;

width``: 100%``;

background``: #f96d9f``;

}

#inner{

margin-left``:``200px``;

margin-right``:``150px``;

}

#``left {

width``: 200px``;

float``: left``;

margin-left``: -100%``;

background``: aqua``;

}

#``right {

width``: 150px``;

float``: left``;

margin-left``: -150px``;

background``: yellowgreen;

}

#``left``,

#``right``,

#``center {

min-height``: 100px``;

}

/* 外围样式 */

#header,

#footer,

#``center``,

#inner,

#``left``,

#``right {

display``: flex;

justify-``content``: center``;

align-items: center``;

font-family``: 'Source Code Pro'``;

font-size``: 20px``;

}

#footer {

clear``: both``;

}

双飞翼布局与圣杯布局相比,没有最小值限制,比其布局适应宽度范围更广泛。