前言
这里所要介绍的布局知识主要是在解决三列布局模式而出现的几种布局解法,其中包含了经典的圣杯布局,双飞翼布局,绝对定位的布局方式,还包含2009年W3C所提出的Flex布局方式和以CSS3所带来的calc计算函数来解决三列布局的方式。
本文会通过实例的方式讲解,带你了解为什么没有一种一劳永逸的方法解决三列布局的问题,看看分别在使用这些方式时分别都遇到了哪些的问题,通过分析解决,让你明白这几种方式的各自的优缺点与适用场景。
一、三列布局是什么
指共有三列,但是左右两列是宽度固定,中间一列宽度根据屏幕宽度自适应的布局方式,这是一种比较常见的布局方式,很多网站首页均采用这种方式布局,比如像下面比较熟悉的菜鸟教程官网。
二、三列布局解决方法
1. 圣杯布局
圣杯布局,一个经典的三列布局解决方法,至于为什么 叫这个名字,我理解是布局完成后像个圣杯,接下来一步一步实现一下圣杯布局。
① 完成基础效果
<body> <header class="header">头部header> <div class="content"> <div class="main">主要内容div> <div class="left">左侧栏div> <div class="right">右侧栏div> div> <footer class="footer">底部footer>body>
/*css文件*/ header { height: 400px; width: 100%; background: #FFD34E; }footer { height: 100px; width: 100%; background: rgb(210, 209, 208); }.main { width: 100%; height: 300px; background: rgb(80, 97, 192); }.left { width: 200px; height: 300px; }.right { width: 200px; height: 300px; background: rgb(131, 124, 104); }
②. 将左侧栏,右侧栏移到与内容栏同样高度,这里先利用float浮动元素。
.main { float: left; width: 100%; height: 300px; background: rgb(80, 97, 192);} .left { float: left; width: 200px; height: 300px; background: rgb(131, 124, 104);} .right { float: left; width: 200px; height: 300px; background: rgb(131, 124, 104);}
注意浮动完成之后,footer元素被盖在内容块下面了。
③. 利用margin-left的负值将左侧栏,右侧栏和内容栏移到同一高度。将左侧栏margin-left赋值为-100%;然后将右侧栏margin-left赋值为负的自身宽度。
.main { float: left; width: 100%; height: 300px; background: rgb(80, 97, 192);} .left { float: left; width: 200px; height: 300px; margin-left: -100%; background: rgb(131, 124, 104);} .right { float: left; width: 200px; height: 300px; margin-left: -200px; background: rgb(131, 124, 104);}
注意:这里的左右侧栏都是附在内容栏上的,内容栏被压在下面。
④. 将底部footer区域利用clear属性清除content内的浮动元素透出来。
footer { height: 100px; width: 100%; clear: both; background: rgb(193, 152, 111);}
⑤. 将内容栏被左右压在底下的部分,通过content添加padding属性透出来。
.content { padding: 0 200px;}
这个时候真整个 content的内容都被padding缩放了,怎么办呢?
⑥. 左右侧边栏利用position: relative,移出内容区域。
.left { float: left; width: 200px; height: 300px; margin-left: -100%; background: rgb(131, 124, 104); position: relative; left: -200px;}.right { float: left; width: 200px; height: 300px; margin-left: -200px; position: relative; left: 200px; background: rgb(131, 124, 104);}
整个布局就完成了,你可以左右拉伸屏幕,内容区域为自动缩放,符合咱们 开始时的需求。
圣杯布局的问题:当缩放到一定程度,会发现整个页面结构将会变乱。
当然利用min-width可以解决这个问题,因为min-width是后续css3中所出现的内容,在当时min-width还没有的情况下,圣杯布局就存在这个问题。然而这个问题可以解决吗?接下来进入双飞翼布局。
2. 圣杯双飞翼布局
双飞翼布局是圣杯布局演化而来的,且是旨在要解决圣杯布局所遇到的问题,即缩小到一定程度后页面布局依旧正常,因为代码和圣杯基本一致,只是结构略有差异,这里不一步一步拆解。
html><html> <body> <header class="header">头部header> <div class="content"> <div class="main"> <div class="center">主要内容div> div> <div class="left">左侧栏div> <div class="right">右侧栏div> div> <footer class="footer">底部footer> body>html>
从上面的DOM结构来看,双飞翼布局与圣杯布局最大的不同点便是在此,双飞翼布局中,将中间栏放在一个div内部包裹起来了,多了一层DOM结构。
下面看看样式。
<style>header { height: 400px; width: 100%; background: #FFD34E;}footer { height: 100px; width: 100%; clear: both; background: rgb(210, 209, 208);}.main { float: left; width: 100%; height: 300px; background: rgb(80, 97, 192);}.main .center { height: 300px; margin: 0 200px; background: rgb(60, 66, 101);}.left { float: left; width: 200px; height: 300px; margin-left: -100%; background: rgb(131, 124, 104);}.right { float: left; width: 200px; height: 300px; margin-left: -200px; background: rgb(131, 124, 104);}style>
从上面双飞翼的布局来看,css中没有了position定位布局的内容了,感觉简明而清晰了。
双飞翼布局的问题:相比于圣杯布局多了一层DOM结构,导致页面渲染性能下降。
3. 绝对定位布局
如果作为一个初学者,让我解决这个问题,我一定会选择绝对定位布局,因为绝对定位布局是最简单最容易理解的一种三列布局解决方式。
思路非常简单,列为以下几步。
①. 将内容区域给margin值,居中且留出左右侧边栏的宽度。
②. 将外层content添加position:relative属性。
③. 将左右侧边栏设置绝对定位属性,position: absoluate,进行布局在与内容栏同高的位置。
④. 分别设置left:0与right:0 属性,保持内容块与左右侧栏有顺序且不重合排列。
<html> <body> <header class="header">头部header> <div class="content"> <div class="main">主要内容div> <div class="left">左侧栏div> <div class="right">右侧栏div> div> <footer class="footer">底部footer> body>html>
css相关内容也非常容易理解,基本都是常用的定位相关内容。
<style>header { height: 400px; width: 100%; background: #FFD34E;}footer { height: 100px; width: 100%; background: rgb(210, 209, 208);}.content { position: relative;}.main { height: 300px; margin: 0 200px; background: rgb(80, 97, 192);}.left { position: absolute; top: 0; left: 0; width: 200px; height: 400px; background: rgb(131, 124, 104);}.right { position: absolute; top: 0; right: 0; width: 200px; height: 300px; background: rgb(131, 124, 104);}style>
上面的布局代码虽然非常容易理解,但是它却有一个致命的问题。
定位布局的问题:因为左右侧的高度是绝对定位脱离文档流的,此时footer区域只会在内容区块下,而不是由内容块和左右侧栏三块区域的高度而决定,所以在某些场景下是不能满足需求的,如呈现出下面的效果。
4. Flex布局
flex布局是2009年W3C所提出的一种新的布局方式,在目前是非常好用且常见的布局方式,我感觉能解决页面上百分之90的布局问题,但是因为出来的比较晚,会有部分浏览器兼容性的问题。
<html> <body> <header class="header">头部header> <div class="content"> <div class="left">左侧栏div> <div class="main">主要内容div> <div class="right">右侧栏div> div> <footer class="footer">底部footer> body>html><style>header { height: 400px; width: 100%; background: #FFD34E;}footer { height: 100px; width: 100%; clear: both; background: rgb(210, 209, 208);}.content { display: flex;}.main { width: 100%; height: 300px; background: rgb(80, 97, 192);}.left { width: 200px; height: 300px; background: rgb(131, 124, 104);}.right { width: 200px; height: 300px; background: rgb(131, 124, 104);}style>
代码完全是简约而又大方,而且没有上面三种布局所产生的问题,真是三列布局必备良品。
flex布局的问题:唯一能说的问题就是兼容性问题了。
flex布局解决三栏布局无疑绝对是最方便的,如果现在我遇到三列布局的问题,毋庸置疑我会选择flex布局来解决,尽管有一些低版本浏览器的兼容性,9012年的今天请放心使用。
5. CSS3的calc函数
思路非常容易理解,就是中间三块区域加float浮动起来,从左到右依次按顺序排列,因为左右两侧宽度已知,而中间块宽度需要自适应,所以只要在屏幕宽度变化的时候,通过css3的方法实时计算出中间内容块自适应的宽度即可,非常符合人们的思维习惯。
<html> <body> <header class="header">头部header> <div class="content"> <div class="left">左侧栏div> <div class="main">主要内容div> <div class="right">右侧栏div> div> <footer class="footer">底部footer> body>html><style>header { height: 60px; width: 100%; background: #FFD34E;}footer { height: 100px; width: 100%; background: rgb(210, 209, 208);}.content { overflow: hidden;}.main { float: left; width: calc(100% - 400px);}.left { float: left; width: 200px; height: 500px; background: rgb(131, 124, 104);}.right { float: left; width: 200px; height: 500px; background: rgb(131, 124, 104);}style>
calc是css3支持的css计算函数,它能动态的计算出一个值,打破传统css概念,让你的css也能做计算。
使用用法:calc(表达式)
calc() 的使用注意点:
运算符前后都需要保留一个空格,例如:width: calc(100% - 400px);
任何长度值都可以使用calc()函数进行计算;
calc()函数支持 "+", "-", "*", "/" 运算;
calc()函数使用标准的数学运算优先级规则;
css3计算属性布局的问题:也是兼容性问题了,从下面可以看出来很多浏览器还是不支持的。
三、总结
上面就是经典的三列布局相关的知识,虽然圣杯布局和双飞翼布局在现在很少被用到,但是作为一个前端开发者,还是要了解这些经典的布局相关知识,从而在面试出现的时候能够从容应对。
实际上,在9012年的今天,其实在目前开发中百分之九十的布局都是可以通过flex布局来解决的,只要你没有IE低版本的用户需求,掌握Flex布局是非常重要的。
最后所介绍的css3计算属性解决三列布局是一种比较贴近数学思想的角度出发,从计算的方式来解决自适应下的宽度变化,但是兼容性还是较差,所以作为实际解决方案还是不妥,就当是了解CSS3新世界的敲门砖吧。