圣杯布局、双飞翼
圣杯布局、双飞翼布局是经典的三栏式布局,都是两边宽度固定,中间宽度自适应。在HTML结构上中间栏在最前面保证了最先渲染,两种布局的实现方法前半部分相同,后半部分的实现各有利弊,下面会简单介绍两者的区别。
源码
圣杯布局
- 两边固定、中间自适应
- 中间最先渲染
- 三列等高布局
根据如上面的需求很快写下如下html结构
1 <header>我是头部</header> 2 <main class="clearFloat"> 3 <div class="middle">middle 4 <p>middlemiddle</p> <p>middlemiddle</p> 5 <p>middlemiddle</p> 6 <p>middlemiddle</p> 7 <p>middlemiddle</p> 8 </div> 9 <div class="left">left</div> 10 <div class="right">right</div> 11 </main> 12 <footer>我是底部</footer>
css 思路
- 布局:有头,有尾,有内容,middle要放在main的最前部分,然后是left,reight。
- 浮动让三个div在一行,出现高度塌陷,clearFloat 清浮动。
- middle 宽度设为100%占满空间,三个div按照float 依次排列。
- left 要放到main的左边,float 是依次排列,位置不够换行显示,所以需要设置margin-left: -100%,因为margin的百分比是相对与父元素,所以需要整整一行的宽度。
- right 要放到main的右边,同理需要设置margin-right的值为负的right的宽。
- middle 的内容被left、right存在重叠未完全显示,所以我们需要设置父容器main 的padding,即可以理解为中间栏给左右两边的留位置出来。
- 上面middle的内容已经可以正常显示出内容,但是left 还是跟middle 存在重叠,left没有到最左边,所以用定位向左移动left的宽度。
1 * { 2 padding: 0; 3 margin: 0; 4 } 5 body { 6 box-sizing: border-box; 7 } 8 9 header,footer { 10 font-size:14px; 11 height: 50px; 12 line-height:50px; 13 background-color:#ccc; 14 text-align:center; 15 } 16 main { 17 padding: 0 150px 20px 200px; 18 overflow: hidden; 19 } 20 main > div { 21 float: left; 22 text-align:center; 23 padding-top:20px; 24 padding-bottom: 10000px; // 实现等高 25 margin-bottom: -10000px;// 实现等高 26 } 27 .clearFloat:after{ 28 content: ""; 29 display: block; 30 clear: both; 31 visibility: hidden; 32 height: 0; 33 } 34 .clearFloat{ 35 zoom: 1; 36 } 37 .middle { 38 width: 100%; 39 background-color:#0e99cd; 40 } 41 .left { 42 width: 200px; 43 background:#72cdef; 44 margin-left: -100%; // 第一行且靠左 45 position: relative; // 给left推到左边 46 left: -200px; 47 } 48 .right { 49 width: 150px; 50 background:#72cdef; 51 margin-right:-150px; // 靠右 52 }
问题
正常情况下是没有问题,但是特殊情况下就会有问题,如果将浏览器无线放大时,如图,当main部分的宽小于left部分时就会发生布局混乱。当中间的宽度小与左边的宽度时布局会错乱
双飞翼布局
圣杯布局和双飞翼布局前一半相同,三个盒子都是float浮动,以形成三栏布局。不同在于解决 中间自适应的盒子内容不被左右盒子遮挡问题思路不一样。
html 结构如下:
1 <header>我是双飞翼头部</header> 2 <main class="clearFloat"> 3 <div class="middle">middle 4 <section class="middle-wrap"> 5 <p>middlemiddle</p> 6 <p>middlemiddle</p> 7 <p>middlemiddle</p> 8 <p>middlemiddle</p> 9 </section> 10 </div> 11 <div class="left">left</div> 12 <div class="right">right</div> 13 </main> 14 <footer>我是双飞翼底部</footer>
在middle 里面加了一层盒子,并且设置了这层盒子的外边距
1 * { 2 padding: 0; 3 margin: 0; 4 } 5 body { 6 box-sizing: border-box; 7 } 8 9 header,footer { 10 font-size:14px; 11 height: 50px; 12 line-height:50px; 13 background-color:#ccc; 14 text-align:center; 15 } 16 main { 17 overflow: hidden; 18 position:relative; 19 } 20 main > div { 21 float: left; 22 text-align:center; 23 padding-top:20px; 24 padding-bottom: 10000px; // 实现等高 25 margin-bottom: -10000px;// 实现等高 26 } 27 .clearFloat:after{ 28 content: ""; 29 display: block; 30 clear: both; 31 visibility: hidden; 32 height: 0; 33 } 34 .clearFloat{ 35 zoom: 1; 36 } 37 .middle { 38 width: 100%; 39 background-color:#0e99cd; 40 } 41 // 自身远离左右两边 42 .middle-wrap { 43 margin: 0 150px 0 200px; 44 } 45 .left { 46 width: 200px; 47 background:#72cdef; 48 margin-left: -100%; // 推到第一行且靠左 49 } 50 .right { 51 width: 150px; 52 background:#72cdef; 53 margin-left:-150px; // 靠右 54 }
区别
处理中间盒子被遮挡思路不一样
圣杯布局是为三个元素的父元素加上padding属性,为左右两边腾开位置,左边两边通过定位来确定位置
双飞翼布局是在加一层盒子,设置这层盒子的左右外边距,左右两边通过负的margin来定位
其他三列布局或者多列布局
flex、gird 等都是不错的解决方案
- left要放到main的左边,设置
margin-left: -100%
,因为margin
的百分比是相对与父元素的,所以需要整整一行的宽度才能补偿这个margin的值,所以left就能到main的左边。