如何在兼容所有浏览器的前提下,实现一个不定宽度的容器被分为左中右三列,左右两列定宽100px,中间列自适应剩余宽度,且三列之间间距为10px,效果如下:
对于这类型的布局,网上有很多有名的方案:圣杯布局[1]和双飞翼布局[2]。
实现
不过我有自己实现的方式,只需要float
和margin
即可,方案如下:
CSS初步设置:
/*CSS Reset*/
.container {height:50px; color: #fff;}
.container *{margin:0;padding:0;}
.container div {height: 100%;}
/*初始设置*/
.left, .right{width: 100px;}
.left{background-color: #f33;}
.right{background-color: #3aa;}
.center{background-color: #e3c;}
HTML结构:
<div class="container">
<div class="left">
<div>左侧定宽</div>
</div>
<div class="right">
<div>右侧定宽</div>
</div>
<!-- 注意float的特性,文档顺序中的前面的float元素会覆盖在后面的元素的容器之上,
因此居中部分一定要放在文档中的其他两个的最后面 -->
<div class="center">
<div>中间自适应</div>
</div>
</div>
实现多列布局的CSS部分:
/*方案实现*/
.left {float:left;}
.right {float:right;}
.center {margin: 0 110px;}
这个布局只要注意把不浮动的居中部分的HTML元素.center
放在另外两个浮动的元素.left
.right
的文档结构的后面即可。
这样实现的原理在于,浮动元素会对不浮动的非父级元素是外框相容,而里面的内容相斥的特原理。
所以在文档中前面两个浮动元素会“吃掉”紧接着的.center
的部分“边框”(包括padding
border
margin
),为了防止需要展现的内容被“吃掉”,只需要给中间的内容设置一个margin: 0 110px;
(已将三列的间距计算在内)即可。
当然也可以将.center
设置padding: 0 110px;
,这时候设置背景色的就是.center
的子元素了。
另外,上面HTML结构的.left
.right
.center
的子元素框<div>...</div>
也不一定需要。
bonus
附上其他同学的使用圣杯布局实现的方式:
body,div{ margin: 0; padding: 0; }
.main_content,.left,.right{height: 200px;}
.main_content{background-color: #cf6;}
.left{background-color: #6cf;width: 100px;}
.right{background-color: #fc6;width: 100px;}
.main{ width: 100%; float: left; }
.main_content{ margin: 0 110px; }
.left{ margin-left: -100%; float: left; }
.right{ margin-left: -100px; float: left; }
<div class="main">
<div class="main_content">Main</div>
</div>
<div class="left">Left</div>
<div class="right">Right</div>
根据网上的文章,这段代码并非那么“正统”,而且圣杯布局因兼容性考虑需要给body
设置最小宽度min-width
。
-----割-----
今天,哦,应该是昨天了,看其他同学引用的其他同学的代码,看不懂啊,然后一步一步注释看效果,最后的收获就加深了对position:relative
、position:absolute
、float
、margin
的理解:设置relative
的元素可以使用位移属性(top
right
bottom
left
以前也知道但是没怎么用不熟练);margin
和位移属性可以同时/叠加使用;通过容器设置float
以及子元素设置absolute
使得容器高度为0(未设置固定高度,默认为auto
),可以让容器后面的元素“上移”到子元素同行而不会被“往下推”。
不废话上代码:
/*CSS Reset*/
.container *{margin:0;padding:0;}
/*初始设置*/
.left, .right{width: 100px;}
.left{background-color: #f33;}
.right{background-color: #3aa;}
.center{background-color: #e3c;}
<div class="container">
<div class="left">左侧定宽</div>
<div class="center-fix">
<div class="center">中间自适应</div>
</div>
<div class="right">右侧定宽</div>
</div>
.left{
position: relative;/*主要提升层级,是防止被.center-flex覆盖了,但实际上并不需要*/
float:left;
}
.right{
float:right;/* #5 由于.center-fix高度为0,所以会被排到跟其他两列一行中 */
}
.center-fix{
float: left;/* #1 浮动跟随.left */
margin-left:-100px;/* #3 将.center-fix的宽延伸到.left区域 */
width: 100%;/* #4 拉满屏幕宽度 */
position: relative;/* #5 作为.center绝对定位的参照物,可以不设置 */
}
.center{
margin-left:100px;/* #2 相对.center设置margin-left */
position: absolute;/* #5 .center-fix高度为0,隐藏 */
right: 110px;/* #6 拉伸到右边,距离包含了.right的宽度和与.right的间距,设为0会遮盖.right */
left: 10px;/* #7 拉伸到左边,距离只包含了与.left的间距,由于#2设置了margin-left,所以不会覆盖.left,而是left和margin-left同时起作用。 */
}
以上
欢迎交流。