三栏布局是目前网站建设的主流布局,同时也是面试中必考的一个点,不管是PC端仍是移动端三栏布局都是很是重要的一个CSS知识点,关于三栏布局的方案说的最烂的莫过于圣杯布局了,其主要的核心思想其实就只有一条:实现两栏固定,中间自适应,保证页面的布局不受窗口大小的变化而紊乱。本文总结了五种实现三栏布局的方法,包括主流的圣杯布局、双飞翼布局,也包含了一些我的遐想的非主流布局,供同窗们学习和参考。css
圣杯布局的思想是将页面纵向分为三个部分,即 header、container、footer,而后又将 container 定为三栏布局。在这里主要讲解其中的 container 布局。html
首先在 container 里面有三栏,分别是 left、middle、right,注意这里 middle 须要放在最前面,保证能够获得优先渲染:面试
1 <div class="grail-container"> 2 <div class="grail-middle"> 3 Grail main 4 </div> 5 <div class="grail-left"> 6 Grail left 7 </div> 8 <div class="grail-right"> 9 Grail right 10 </div> 11 </div>
对于 container ,设置一个属性 overflow: hidden; 让其造成一个 BFC ,而后使其三栏浮动,并使用相对定位:wordpress
1 .grail-container { 2 overflow: hidden; 3 } 4 .grail-container>div { 5 position: relative; 6 float: left; 7 height: 100%; 8 }
这时执行如下的步骤:布局
① 置 middle 的 width: 100%,给 left 和 right 定宽度,这里假设都是 width: 200px;post
② 这时 left 被挤到下面去了,因此咱们要把它拉回来,设置 margin-left: -100%;性能
③ 还有一个 right 没有拉回来,一样,设置 margin-left: 200px;,这里的长度等于 right 自身的长度学习
④ 这时 middle 的两边被 left 和 right 给覆盖了,因而咱们要把两边怼回来,设置 container padding: 0 200px 0 200px;flex
⑤ middle 怼回来了,但是 left 和 right 也跟着回来,因此如今咱们要把 left 和 right 给怼回去,分别设置 left left: -200px;,right right: -200px;(这就是以前为何要用相对定位)网站
1 .grail-container { 2 overflow: hidden; 3 padding: 0 200px; 4 } 5 .grail-container>div { 6 position: relative; 7 float: left; 8 height: 100%; 9 } 10 .grail-middle { 11 width: 100%; 12 background-color: blue; 13 } 14 .grail-left { 15 width: 200px; 16 background-color: green; 17 margin-left: -100%; 18 left: -200px; 19 } 20 .grail-right { 21 width: 200px; 22 background-color: brown; 23 margin-left: -200px; 24 right: -200px; 25 }
圣杯布局就完成了,不信拖拖看,是否是中间就自适应了?不过它有一个弊端,就是当拖到很小的时候,布局会乱,因而咱们有了下面的布局:双飞翼布局。
双飞翼布局使于淘宝,是淘宝团队提出来的一种实现三栏布局的方案,其和圣杯布局是同门兄弟,一样将页面分为 header、container、footer ,不过在 container 里面有所区别。圣杯布局的缺陷在于内容区被 container 的 padding 夹在里面,使得页面宽度太小时会出现布局紊乱,这时候双飞翼布局就不使用 padding 来将内容区夹在里面,而是给内容区添加一个 main ,设置 margin 将页面主动的撑开,其 DOM 结构与圣杯相似,区别在于在 middle 中多了一个 main:
1 <div class="double-wing-container"> 2 <div class="double-wing-middle"> 3 <div class="double-wing-main"> 4 Double wing main. 5 </div> 6 </div> 7 <div class="double-wing-left"> 8 Double wing left. 9 </div> 10 <div class="double-wing-right"> 11 Double wing right 12 </div> 13 </div>
1 .double-wing-container { 2 overflow: hidden; 3 } 4 .double-wing-container>div { 5 position: relative; 6 float: left; 7 height: 100%; 8 }
这时执行与圣杯布局相似的步骤:
① 置 middle 的 width: 100%,给 left 和 right 定宽度,这里假设都是 width: 200px;
② 这时 left 被挤到下面去了,因此咱们要把它拉回来,设置 margin-left: -100%;
③ 还有一个 right 没有拉回来,一样,设置 margin-left: 200px;,这里的长度等于 right 自身的长度
注意这里开始就有区别了:
④ 使用 main 把内容区撑开,设置 margin: 0 200px 0 200px;,同时设置 overflow: hidden; 使其造成一个 BFC
1 .double-wing-container { 2 overflow: hidden; 3 } 4 .double-wing-container>div { 5 position: relative; 6 float: left; 7 height: 100%; 8 } 9 .double-wing-middle { 10 width: 100%; 11 background-color: gray; 12 } 13 .double-wing-left { 14 width: 200px; 15 background-color: orange; 16 margin-left: -100%; 17 } 18 .double-wing-right { 19 width: 200px; 20 background-color: red; 21 margin-left: -200px; 22 } 23 .double-wing-main { 24 height: 100%; 25 margin: 0 200px; 26 background-color: pink; 27 overflow: hidden; 28 }
如今再试试,是否是比圣杯布局稍微好一点,在窗口宽度太小时不会出现排版混乱?其核心就是把内容部分从 middle 迁移到了 main。
以上两种布局方案已经适用于绝大部分场景,若是你只是想找一个三栏布局的解决方案,那么到此就够了。不过,若是你想要的不仅是这些,if you wanna more,那么就一块儿来聊一聊下面的布局方案。
首先呢,咱们的两大三栏布局都有一个固定的模式,那就是两栏固定,中间自适应,但是你有没有想过,咱们来实现一个三栏自适应的布局?那么大名鼎鼎的 Flex 布局就登场了,Flex 布局不光能够实现两栏固定,中间自适应,也能够实现三栏自适应,甚至随意固定,随意自适应。
Flex 布局可谓 CSS3 提供一个布局神奇,将 CSS2 中的许多难点一网打尽。关于 Flex 布局的语法,这里就不作讨论了,若是有不熟悉的同窗能够先看看阮老师的文章:Flex 布局教程:语法篇 这篇文章讲解的十分通俗易懂。在这里咱们先照样子实现一个三栏布局, 两栏固定,中间自适应。
首先,DOM 结构也是同样的:
1 <div class="flex-container"> 2 <div class="flex-middle"> 3 Flex main 4 </div> 5 <div class="flex-left"> 6 Flex left 7 </div> 8 <div class="flex-right"> 9 Flex right 10 </div> 11 </div>
而后执行如下步骤:
① 设置 container 布局方式 display: flex;
② 这时候设置 middle width: 100%; ,同时给两栏定宽,这里假设都是 width: 200px;
③ 既然是两栏固定,那么就不让两栏收缩,给 left 和 right 设置 flex-shrink: 0;
④ 因为 DOM 结构和咱们实际的顺序不同,这时咱们来排个序 left order: 1;,middle order: 2;,right order: 3;
1 .flex-container { 2 display: flex; 3 } 4 .flex-container>div { 5 height: 100%; 6 } 7 .flex-left { 8 width: 200px; 9 background-color: yellow; 10 order: 1; 11 flex-shrink: 0; 12 } 13 .flex-middle { 14 width: 100%; 15 background-color: gray; 16 order: 2; 17 } 18 .flex-right { 19 width: 200px; 20 background-color: red; 21 order: 3; 22 flex-shrink: 0; 23 }
OK啦,如今拖动试一试。能够看出 flex 布局具备更强的适应性,在窗口宽度太小的时候不会形成页面布局混乱。经过设置内容的伸缩,能够实现任意栏的固定和自适应,同时也能够实现三栏自适应,经过设置 flex 内容的 flex-shrink 和 flex-grow 能够实现自定义的适应性布局。接下来,我们聊一聊一些我的的遐想,偏非主流的三栏布局。
绝对定位其强大之处在于它的定位性能很是的优秀,这里咱们就能够用绝对定位的自动伸缩性来实现一个三栏布局。
DOM 结构依然不变:
1 <div class="absolute-container"> 2 <div class="absolute-middle"> 3 Absolute main 4 </div> 5 <div class="absolute-left"> 6 Absolute left 7 </div> 8 <div class="absolute-right"> 9 Absolute right 10 </div> 11 </div>
注意咱们须要将 container 的 postion: relative; ,由于绝对定位元素的参照物为第一个 postion 不为 static 的祖先元素,同时须要使 left 向左浮动,right 向右浮动,同时使 middle 绝对定位,并把左右两边撑开:
1 .absolute-container { 2 position: relative; 3 overflow: hidden; 4 } 5 .absolute-container>div { 6 height: 100%; 7 } 8 .absolute-left { 9 float: left; 10 width: 200px; 11 background-color: blue; 12 } 13 .absolute-middle { 14 position: absolute; 15 left: 200px; 16 right: 200px; 17 top: 0; 18 bottom: 0; 19 background-color: pink; 20 } 21 .absolute-right { 22 float: right; 23 width: 200px; 24 background-color: brown; 25 }
注意绝对定位元素的高度须要设置 top: 0 和 bottom: 0 来使其高度撑开。如今试一试是否是一样也实现了三栏布局,不过这种布局方案有一个致命的缺点,就是中间的内容区彻底依赖于两栏的高度,若是两栏的高度不够,那么中间内容区的高度也会随着压缩,因此这种方案在不少场景下并不适合。下面咱们来聊一个较强一点的非主流三栏布局。
在前三种三栏布局方案中,咱们三栏的高度取决于各自的内容区,也就是说若是中间内容多,两边内容少的状况下,页面的高度取决于内容区,同时两栏的高度不会增长,这是当今绝大多数的网站所采用的主流布局。第四种方案中的致命缺陷为中间内容区的高度取决于两栏的最高点。如今咱们讨论一种非主流的三栏布局方案,表格布局,使其三栏高度统一,这种布局方案主要是利用了表格布局的伸缩性。首先 DOM 结构有所改变,middle 不能放在最前面了:
1 <div class="table-cell-container"> 2 <div class="table-cell-left"> 3 Table cell left 4 </div> 5 <div class="table-cell-middle"> 6 Table cell main 7 </div> 8 <div class="table-cell-right"> 9 Table cell right 10 </div> 11 </div>
这时执行如下步骤:
① 将 left、middle、right 都设置为表格单元 display: table-cell;
② 给 left 和 right 定宽,这里假设 width: 200px;,同时设置 middle width: 100%;
③ 这时候因为 middle 把两栏都给挤到两边去了,因此这时候咱们要把两栏给挤回来,设置 min-width: 200px;
1 .table-cell-container { 2 position: relative; 3 overflow: hidden; 4 } 5 .table-cell-container>div { 6 height: 100%; 7 display: table-cell; 8 } 9 .table-cell-left { 10 width: 200px; 11 min-width: 200px; 12 background-color: red; 13 } 14 .table-cell-middle { 15 margin: 0 200px; 16 width: 100%; 17 background-color: brown; 18 } 19 .table-cell-right { 20 min-width: 200px; 21 width: 200px; 22 background-color: yellow; 23 }
OK ,如今试一试是否是一样的是一个三栏布局,并且这种布局方案中的三栏高度是统一的,可是其缺陷就是 middle 不可以像其余三栏布局那样放在最前面获得最早渲染。
三栏布局的方式其实有不少,不过只要掌握了其核心思想就能够实现自定义的三栏布局。圣杯布局运用的很普遍,不过其致命的缺点就是 middle 区域占用空间过宽时会把两栏给挤下去,也就是当窗口 size 太小时,而双飞翼布局正是弥补了这一缺点。若是项目不考虑低版本 IE 的兼容性的话,建议仍是使用 Flex 布局,simple and powerful,若是你想试试新鲜,也能够尝尝表格布局,你能够在下面随意拖动观察不一样布局方案的区别:
[1] 张鑫旭 . CSS深刻理解流体特征和BFC特性下多栏自适应布局
[2] 阮一峰 . Flex 布局教程:语法篇
[3] 张鑫旭 . 我熟知的三种三栏网页宽度自适应布局方法