三栏布局
问题:假设容器的高度默认100px,请写出三栏布局,其中左栏、右栏的宽度各为300px,中间的宽度自适应。
方法
浮动
左侧设置左浮动,右侧设置右浮动即可,中间会自动地自适应。
绝对定位
左侧设置为绝对定位, left:0px。右侧设置为绝对定位, right:0px。中间设置为绝对定位,left 和right 都为300px,即可。中间的宽度会自适应。
使用article标签作为容器,包裹左、中、右三个部分。
Flexbox布局
flex:1即为flex-grow:1,经常用作自适应布局,将父容器设置display:flex,侧边栏大小固定后,将内容区flex:1,内容区则会自动放大占满剩余空间。
表格布局 table
设置整个容器的宽度为100%,设置三个部分均为表格,然后左边的单元格为 300px,右边的单元格为 300px,即可。中间的单元格会自适应。
网格布局 grid
设置容器为网格布局display: grid,宽度为100% 设置网格为三列,并设置每列的宽度grid-template-columns: 300px auto 300px。
效果
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面布局</title>
<style>
html *{
padding: 0;
margin: 0;
}
.layout article div{
height: 100px;
}
.layout{
margin-top: 20px;
}
/* 1.浮动 */
/* .layout.float表示交集选择器,空格表示后代选择器 */
.layout.float .left{
float: left;
width: 300px;
background: red;
}
.layout.float .right{
float: right;
width: 300px;
background: blue;
}
.layout.float .center{
background: green;
}
/* 2.绝对定位 */
.layout.absolute{
margin-top: 100px;
}
.layout.absolute .left{
position: absolute;
left: 0;
width: 300px;
background: red;
}
/* 【重要】中间的区域,左侧定位300px,右侧定位为300px,即可完成。宽度会自适应 */
.layout.absolute .center{
position: absolute;
left: 300px;
right: 300px;
background: green;
}
.layout.absolute .right{
position: absolute;
right: 0;
width: 300px;
background: blue;
}
/* 3.flex */
/* 绝对布局导致脱离文档流,因此上边距300px是从方法一中还在文档流的元素开始算 */
.layout.flex{
margin-top: 230px;
}
.layout.flex .left-center-right{
display: flex;
}
.layout.flex .left {
width: 300px;
background: red;
}
.layout.flex .center {
flex: 1;
background: green;
}
.layout.flex .right {
width: 300px;
background: blue;
}
/* 4.表格 */
/* 重要:设置容器为表格布局,宽度为100% */
.layout.table .left-center-right{
width: 100%;
display: table;
}
/* 重要:设置三个模块为表格里的单元*/
.layout.table .left-center-right div{
display: table-cell;
}
.layout.table .left{
width: 300px;
background: red;
}
.layout.table .center {
background: green;
}
.layout.table .right {
width: 300px;
background: blue;
}
/* 5.网格 */
/* 重要:设置容器为网格布局,宽度为100% */
/* 设置网格为三列,并设置每列的宽度。即可。 */
.layout.grid .left-center-right{
display: grid;
width: 100%;
/* grid-template-rows: 100px; */
grid-template-columns: 300px auto 300px;
}
.layout.grid .left {
background: red;
}
.layout.grid .center {
background: green;
}
.layout.grid .right {
background: blue;
}
</style>
</head>
<body>
<!-- 方法一:浮动 -->
<!--
元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,
所以元素下边的还在文档流中的元素会自动向上移动
-->
<!-- 输入 section.layout.float,即可生成 -->
<section class="layout float">
<!-- 用article标签包裹左、中、右三个部分 -->
<article class="left-center-right">
<div class="left">
left
</div>
<div class="right">
right
</div>
<div class="center">
<h1>浮动</h1>
center
</div>
</article>
<!-- 方法二:绝对定位 -->
</section>
<section class="layout absolute">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>绝对定位</h1>
center
</div>
<div class="right">
right
</div>
</article>
</section>
<!-- 方法三:flex -->
<section class="layout flex">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="center">
<h1>flex布局</h1>
我是 center
</div>
<div class="right">
我是 right
</div>
</article>
</section>
<!-- 方法四、表格 -->
<section class="layout table">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>表格布局</h1>
center
</div>
<div class="right">
right
</div>
</article>
</section>
<!-- 方法五、网格 -->
<section class="layout grid">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>网格布局</h1>
center
</div>
<div class="right">
right
</div>
</article>
</section>
</body>
</html>
延伸
五种方法的对比
- 五种方法的优缺点
- 考虑中间模块的高度问题
- 兼容性问题:实际开发中,哪个最实用?
方法1:浮动:
- 优点:兼容性较好。
- 缺点:浮动是脱离文档流的,如果处理不好,会带来很多问题。有些时候需要清除浮动,需要很好的处理浮动周边元素的关系。
方法:2:绝对定位
- 优点:快捷。
- 缺点:布局脱离文档流,意味着下面的子元素也要脱离文档流,导致这个方案的有效性是比较差的。
方法3:flex 布局
- 优点:比较完美的解决了浮动和绝对定位的问题。在移动端比较常用。
- 缺点:兼容性比较差,不兼容IE8及以下的版本。因为这个是CSS3中新增的display的属性值。
方法4:表格布局
- 优点:表格布局在很多场景中很实用,兼容性非常好。因为IE8不支持 flex,此时可以尝试表格布局。
- 缺点:因为三个部分都当成了单元格来对待,此时,如果中间的部分变高了,其会部分也会被迫调整高度(即使其余部分单独设置了高度)。但是,在很多场景下,我们并不需要两侧的高度增高。
方法5:网格布局
- CSS3中引入的布局,很好用。代码量简化了很多。
如果题目中去掉高度已知
问题:题目中,如果去掉高度已知,我们往中间的模块里塞很多内容,让中间的模块撑开。会发生什么变化?
页面布局的变通
三栏布局
- 左右宽度固定,中间自适应
- 上下高度固定,中间自适应
两栏布局
- 左宽度固定,右自适应
- 右宽度固定,左自适应
- 上宽度固定,下自适应
- 下宽度固定,上自适应