今天早上在阿当大侠的编写高质量前端代码群中与几位朋友一起探讨和学习了一种用div+css进行的三列(三栏)布局,而且是中间固定左右两边自适应宽度,听起来蛮有意思的。因为以前只是碰到过,左右两列固定而中间自适应的运用。于是思考一下马上敲起了键盘自己实战了一下,接着与大家一起测试,还是通过了各浏览器的考验,为了方便自己以后好查阅,也想让不知道的朋友一起学习一下这样的布局,特整理了一下代码,贴上来与大家一起分享和学习。
在讲这种布局之前,我还想和大家一起回想一下三列布局中的另一种,就是左右两列固定,中间自适应宽度。这种布局方法,网上问问G爸和度娘一定会有一大堆,但我还是要重复说说,方便自己今后查阅,记性太差,没办法。别的先不说了,就开始进入主题吧。对于两边固定中间一列自适应的布局方法,我最早使用的是绝对定位法。先看代码
<span><<span>div</span> <span>id</span>=<span>"left"</span>></span>左边栏<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"right"</span>></span>右边栏<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"main"</span>></span>主内容<span></<span>div</span>></span>
比如说,我左右两列都是220px,中间宽度自适应,那么我们使用绝对定位实现的方法是这样的
<span>html</span>,<span>body</span> <span>{
<span><span>margin</span>:<span><span>0</span>;</span></span>
<span><span>padding</span>:<span><span>0</span>;</span></span>
<span><span>height</span>:<span> <span>100</span>%;</span></span>
<span>}</span></span>
<span>#left</span>,
<span>#right</span> <span>{
<span><span>position</span>:<span> absolute;</span></span>
<span><span>top</span>:<span><span>0</span>;</span></span>
<span><span>width</span>:<span> <span>220</span>px;</span></span>
<span><span>height</span>:<span> <span>100</span>%;</span></span>
<span>}</span></span>
<span>#left</span> <span>{
<span><span>left</span>:<span><span>0</span>;</span></span>
<span>}</span></span>
<span>#right</span> <span>{
<span><span>right</span>:<span><span>0</span>;</span></span>
<span>}</span></span>
<span>#main</span> <span>{
<span><span>margin</span>:<span> <span>0</span> <span>230</span>px;</span></span>
<span><span>height</span>:<span> <span>100</span>%;</span></span>
<span>}</span></span>
这种方法是最简单,也是麻烦最多的,如果中间栏含有最小宽度限制,或是含有宽度的内部元素,当浏览器宽度小到一定程度,会发生层重叠的情况。我个人现在不在建议使用这种布局。
第二种方法采用的是浮动布局
这种方法和上面的绝对定位方法很相似,只不过这里采用的是浮动,而不是绝对定位,先来看其html代码
<span><<span>div</span> <span>id</span>=<span>"left"</span>></span>left <span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"right"</span>></span>right<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"main"</span>></span>mian<span></<span>div</span>></span>
这种方法我利用的就是浮动原理,左右定宽度分别进行左浮动和右浮动,此时主内容列(中间列没有定度)主会自动插入到左右两列的中间,最要注意的一点是,中间列一定要放在左右两列的后面,如上面的html代码所示,下面我们一起来看看其css样式是怎么实现的
<span>#left</span>,
<span>#right</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>width</span>:<span> <span>220</span>px;</span></span>
<span><span>height</span>:<span> <span>200</span>px;</span></span>
<span><span>background</span>:<span> blue;</span></span>
<span>}</span></span>
<span>#right</span><span>{
<span><span>float</span>:<span> right;</span></span>
<span>}</span></span>
<span>#main</span> <span>{
<span><span>margin</span>:<span> <span>0</span> <span>230</span>px;</span></span>
<span><span>background</span>:<span> red;</span></span>
<span><span>height</span>:<span> <span>200</span>px;</span></span>
<span>}</span></span>
是不是好简单一种方法呀,大家可以在本地机子上动手测试一下,效果如下所示:
第三种方法:负的margin
使用这种方法就稍微复杂了一些了,使用的是负的margin值,而且html标签也增加了,先来看其代码吧
<span><<span>div</span> <span>id</span>=<span>"main"</span>></span>
<span><<span>div</span> <span>id</span>=<span>"mainContainer"</span>></span>main content<span></<span>div</span>></span>
<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"left"</span>></span>
<span><<span>div</span> <span>id</span>=<span>"leftContainer"</span> <span>class</span>=<span>"inner"</span>></span>left content<span></<span>div</span>></span>
<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"right"</span>></span>
<span><<span>div</span> <span>id</span>=<span>"rightContainer"</span> <span>class</span>=<span>"inner"</span>></span>right<span></<span>div</span>></span>
<span></<span>div</span>></span>
从上面的Html代码中我们可以明显得看出,在main,left,right三个div内部我都增加了一个div,那么他们起了什么样的作用呢,大家从下在的CSS中可以明显的体会出来。
<span>#main</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>width</span>:<span> <span>100</span>%;</span></span>
<span>}</span></span>
<span>#mainContainer</span> <span>{
<span><span>margin</span>:<span> <span>0</span> <span>230</span>px;</span></span>
<span><span>height</span>:<span> <span>200</span>px;</span></span>
<span><span>background</span>:<span> green;</span></span>
<span>}</span></span>
<span>#left</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>margin-left</span>:<span> -<span>100</span>%;</span></span>
<span><span>width</span>:<span> <span>230</span>px
}</span></span></span>
<span>#right</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>margin-left</span>:<span> -<span>230</span>px;</span></span>
<span><span>width</span>:<span> <span>230</span>px;</span></span>
<span>}</span></span>
<span>#left</span> <span>.inner</span>,
<span>#right</span> <span>.inner</span> <span>{
<span><span>background</span>:<span> orange;</span></span>
<span><span>margin</span>:<span> <span>0</span> <span>10</span>px;</span></span>
<span><span>height</span>:<span> <span>200</span>px;</span></span>
<span>}</span></span>
简单的说一下其实现原理,这种方法布局,主要运用的是负的margin值。首先在div#main中我定了一个100%宽度并进行左浮动,并且主内容是放在其内层div#mainContainer中,并在这个主内容层中需要进行一个margin-left和margin-right设置,并且这两个值是很有讲究的,并不是可以随便设置的,这两个值需要等于左右两列的宽度。我们此处是230px。左栏和右栏都使用负的margin值加上左浮动来布局,左栏是左浮动并加了一个“margin-left:-100%”,这是因为div#left前面有一个div#main,并且其宽度为100%,这样一来在左栏定这个margin-left: -100%;刚好使左边栏定位到页面的最左边;而右栏也进行左浮动,但其定义的“margin-left”也是负值,并且等于其自身的宽度230px;最后在div#left,div#right中加上一个div.inner是为了更好的控制边栏与主内容列之间的间距。比如说此例的10px。大家可以看看其效果是不是和第二种方法一样。
上面啰嗦完了常见的布局方法,接着进我们一起来看另外一种三列布局中间固定宽度,两边自适应宽度。对于我来说,这是一种很少碰到的布局方法,不知道大家有何体会,那么下面我们一起来看这种布局方法的实现过程,同样先来看html代码:
<span><<span>div</span> <span>id</span>=<span>"left"</span>></span>
<span><<span>div</span> <span>class</span>=<span>"inner"</span>></span>this is left sidebar content<span></<span>div</span>></span>
<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"main"</span>></span>
<span><<span>div</span> <span>class</span>=<span>"inner"</span>></span>this is main content<span></<span>div</span>></span>
<span></<span>div</span>></span>
<span><<span>div</span> <span>id</span>=<span>"right"</span>></span>
<span><<span>div</span> <span>class</span>=<span>"inner"</span>></span>this is right siderbar content<span></<span>div</span>></span>
<span></<span>div</span>></span>
这种方法也是借助于负的margin来实现的,首先我们在中间列定好固定值,因为此值是不会在改变的,接着对其进行左浮动;那么关键地主是在左右边栏设置地方,这种方法是将其都进行50%的宽度设置,并加上中负的左边距,此负的左边距最理想的值是中间栏宽度的一半加上1px,比如说此例中是"540px/2+1"也就是说他们都有一个"margin-left: -271px",这样一来,左右边栏内容无法正常显示,那是因为对他们进行了负的左边距操作,现在只需要在左右边栏的内层div.inner将其拉回来,就OK了,大家可以看下在的代码:
<span>#left</span>,
<span>#right</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>margin</span>:<span> <span>0</span> <span>0</span> <span>0</span> -<span>271</span>px;</span></span>
<span><span>width</span>:<span> <span>50</span>%;</span></span>
<span>}</span></span>
<span>#main</span> <span>{
<span><span>width</span>:<span> <span>540</span>px;</span></span>
<span><span>float</span>:<span> left;</span></span>
<span><span>background</span>:<span> green;</span></span>
<span>}</span></span>
<span>.inner</span> <span>{
<span><span>padding</span>:<span> <span>20</span>px;</span></span>
<span>}</span></span>
<span>#left</span> <span>.inner</span>,
<span>#right</span> <span>.inner</span> <span>{
<span><span>margin</span>:<span> <span>0</span> <span>0</span> <span>0</span> <span>271</span>px;</span></span>
<span><span>background</span>:<span> orange;</span></span>
<span>}</span></span>
具体效果如下:
这种方法如果在ie下会存在布局混乱的bug,你可以将div#right和div#left中的width值稍作修改:
<span>#left</span>,
<span>#right</span> <span>{
<span><span>float</span>:<span> left;</span></span>
<span><span>margin</span>:<span> <span>0</span> <span>0</span> <span>0</span> -<span>271</span>px;</span></span>
<span><span>width</span>:<span> <span>50</span>%;</span></span>
<span>*<span>width</span>:<span> <span>49.9</span>%;</span></span>
<span>}</span></span>
这样一来,在ie下也就安全了。
实现这种效果的方法可能有很多,希望大家有更好的方法能一起分享一起学习。
2012年09月26日更新——CSS3 Flexbox
前面介绍了三种方法,实现L1F2L3布局效果,也就是第一列和第三列自适应宽度,中间一列固定宽度。今天在给大家推荐一种CSS3实现这种布局的方法,采用CSS3的Flexbox,这种方法 不足之处就是只能在部分浏览器中使用,详细的请看下面代码:
HTML结构
<span><<span>div</span> <span>class</span>=<span>"grid"</span>></span>
<span><<span>div</span> <span>class</span>=<span>"col fluid"</span>></span>
...
<span></<span>div</span>></span>
<span><<span>div</span> <span>class</span>=<span>"col fixed"</span>></span>
...
<span></<span>div</span>></span>
<span><<span>div</span> <span>class</span>=<span>"col fluid"</span>></span>
...
<span></<span>div</span>></span>
<span></<span>div</span>></span>
CSS代码
<span>.grid</span> <span>{
<span><span>display</span>:<span> -webkit-flex;</span></span>
<span><span>display</span>:<span> -moz-flex;</span></span>
<span><span>display</span>:<span> -o-flex;</span></span>
<span><span>display</span>:<span> -ms-flex;</span></span>
<span><span>display</span>:<span> flex;</span></span>
<span>}</span></span>
<span>.col</span> <span>{
<span><span>padding</span>:<span> <span>30</span>px;</span></span>
<span>}</span></span>
<span>.fluid</span> <span>{
<span><span>flex</span>:<span> <span>1</span>;</span></span>
<span>}</span></span>
<span>.fixed</span> <span>{
<span><span>width</span>:<span> <span>400</span>px;</span></span>
<span>}</span></span>
效果如下面的demo所示: