闲时要有吃紧的心思,忙时要有悠闲的趣味。
前言
对于前端来说,布局是必须掌握的,一个好的布局可以让页面看起来更美观。提到布局,那就不得不说CSS三栏布局。
三栏布局一般多指左右两栏宽度固定,中间栏宽度自适应的布局。在能实现效果的情况下,尽可能的中间栏内容优先渲染。面试的时候经常被问到,在这里总结一下
正文
我们不妨假定这样一个布局:高度已知((设高度为200px)),其中左栏、右栏宽度各为300px,中间自适应,可以通过几种方法来实现?以及各自的优缺点是什么?
常见的布局方式: float布局、Position定位、table布局、弹性(flex)布局、网格(grid)布局
方便起见,先写一些公用的样式:
<!-- 公共样式 -->
<style>
.clear_fix:after {
content: '';
display: flex;
clear: both;
}
.left,
.middle,
.right {
height: 200px;
}
.left {
background-color: red;
width: 300px;
}
.middle {
background-color: green;
}
.right {
background-color: yellow;
width: 300px;
}
</style>
复制代码
一、Float布局
方案
左右中三列,左列左浮动,右列右浮动,中间列设置左右margin
原理
float
属性定义元素在哪个方向浮动,它最初的设计的初衷是为了解决文字环绕的问题 ,即给一个图片设置float
属性之后会使文字环绕在图片周围显示。
float
之所以可以实现文字环绕,是因为设置float
属性的元素可以脱离文档流,使父元素高度塌陷。
如果浮动非替换元素,则要指定一个明确的宽度;否则,它们会尽可能地窄。
话不多说上代码:
<!-- float解决方案 -->
<main class="content_float main_content clear_fix">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
</div>
<div class="middle">
<p>middle</p>
<h1>float解决方案</h1>
</div>
</main>
<style>
.content_float {
min-width: 700px;
}
.content_float .left {
float: left;
}
.content_float .middle {
margin-left: 300px;
margin-right: 300px;
}
.content_float .right {
float: right;
}
</style>
复制代码
注意事项
-
父元素设置最小宽度
如果父元素的宽度小于两侧子元素固定宽度的和(600px),右侧元素就会被挤到下面去,所以我们需要设置最小宽度。
-
中间元素设置margin-left、和margin-right
如果动手写这个代码的小伙伴会发现不设置这两个属性效果在中间元素内容比较少的时候效果是正常的,但是如果如果中间元素的子元素内容特别多的时候会挤到左右元素的下面去
-
清除浮动
由于我们使用了
float,
所以为了不影响其他元素的显示这里需要为父元素添加clear_fix
的类名用来清除浮动(具体代码见公共样式)。
二、Position布局
方案
左中右三列(无顺序),根据定位属性去直接设置各个子元素位置
原理
position
可以设置元素定位类型,其属性有5种 :
inherit: 继承父元素的position属性值
static: 默认值,没有定位
fixed: 生成绝对定位的元素,相对于浏览器窗口进行定位(不管屏幕内容怎么滑动,其位置不会改变)
relative:生成相对定位,相对于其正常位置进行定位
absolute:生成绝对定位的元素,相当于static定位以外的第一个父元素进行定位。
复制代码
根据以上内容我们可以看出我们需要选择给 左 中 右 都使用 absolute 绝对定位,由于absolute 是相当于static定位以外的第一个父元素进行定位,所以我们要给其父元素添加 position:relative属性, 这样这三个子元素可以相对于父元素进行绝对定位。
话不多说上代码:
<!-- posstion解决方案 -->
<main class="content_posstion main_content">
<div class="left">
<p>left</p>
</div>
<div class="middle">
<p>middle</p>
<h1>position解决方案</h1>
</div>
<div class="right">
<p>right</p>
</div>
</main>
<style>
.content_posstion {
position: relative;
}
.content_posstion .left {
position: absolute;
left: 0;
}
.content_posstion .right {
position: absolute;
right: 0;
}
.content_posstion .middle {
position: absolute;
left: 300px;
right: 300px;
}
</style>
复制代码
三、Table布局
方案
左中右三列,父元素display: table;子元素display: table-cell;居中子元素不设宽度
原理
table
是一种常见的布局方式,他可以将整个页面按照表格的方式设置为多行多列,但是由于书写table标签比较麻烦尤其是涉及到table内嵌table的时候,所以CSS给我们提供了display: table的方式可以让我们方便的使用table布局, 设置子元素为列的属性display:table-cell
话不多说上代码:
<!-- table解决方案 -->
<main class="content_table main_content">
<div class="left">
<p>left</p>
</div>
<div class="middle">
<p>middle</p>
<h1>table解决方案</h1>
</div>
<div class="right">
<p>right</p>
</div>
</main>
<style>
.content_table {
width: 100%;
display: table;
}
.content_table>div {
display: table-cell;
}
</style>
复制代码
四、Flex布局
方案
左中右三列,父元素display: flex;居中子元素flex: 1;
原理
flex布局是W3C提出了一种新的方案,可以简便、完整、响应式地实现各种页面布局。
当给元素设置display:flex,则该元素就是一个flex容器,其子元素就是容器成员,称之为flex项目,每个项目默认按照从左到右方式排列。
详情可参考阮一峰老师的——Flex 布局教程
话不多说上代码:
<!-- flex解决方案 -->
<main class="content_flex main_content">
<div class="left">
<p>left</p>
</div>
<div class="middle">
<p>middle</p>
<h1>flex解决方案</h1>
</div>
<div class="right">
<p>right</p>
</div>
</main>
<style>
.content_flex {
display: flex;
}
.content_flex .middle {
flex: 1;
}
</style>
复制代码
注意事项
五、Grid布局
概要
方案
左中右三列,父元素display: grid;利用网格实现
原理
网格布局(Grid)是最强大的 CSS 布局方案。
网格它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。
将属性display
值设为grid
或inline-grid
, 就创建了一个网格容器,所有容器直接子结点自动成为网格项目。
gird提供了gird-template-columns
、grid-template-rows
属性让我们设置行和列的高、宽,只需要四行CSS代码就可以实现三栏布局,是不是感觉到了gird的强大之处呢
详情可参考阮一峰老师的——CSS Grid 网格布局教程
话不多说上代码:
<!-- grid解决方案 -->
<main class="content_grid main_content">
<div class="left">
<p>left</p>
</div>
<div class="middle">
<p>middle</p>
<h1>grid解决方案</h1>
</div>
<div class="right">
<p>right</p>
</div>
</main>
<style>
.content_grid {
width: 100%;
display: grid;
grid-template-rows: 100px;
grid-template-columns: 300px auto 300px;
}
</style>
复制代码
总结
以上提供了5种实现三栏布局的方式那么他们的优缺点呢?我们做张表格对比一下
布局方案 | 优点 | 缺点 |
---|---|---|
Float布局 | 比较简单,兼容性也比较好 | 浮动元素脱离文档流,使用的时候只需要注意一定要清除浮动。 |
Position布局 | 快捷,设置很方便 | 元素脱离了文档流,后代元素也脱离了文档流,高度未知的时候,会有问题,有效性和可使用性比较差 |
Table布局 | 使用起来方便,兼容性也不存在问题 | ①无法设置栏边距;②对seo不友好;③当其中一个单元格高度超出的时候,两侧的单元格也是会跟着一起变高的 |
Flex布局 | 比较完美 | 存在IE上兼容性问题,只能支持到IE9以上 |
Grid布局 | 最强大和最简单 | 兼容性不好 |
通过介绍五种布局的优缺点,在实际开发中最优选择哪种布局?相信大家心中会有自己的答案。
我觉得flex
和grid
布局就可以搞定实际开发中的布局,假设浏览器都支持这两个模块,你将选择grid还是flexbox来给页面布局?
flexbox是一维布局,他只能在一条直线上放置你的内容区块;而grid是一个二维布局。前面也简单说到,你可以根据你的设计需求,将内容区块放置到任何你想要放的地方。此外,如果要兼容低版本的IE(比如IE8+),可以考虑table布局。
最后问大家一个问题,如果中间部分被内容高度撑开,需要左右栏也撑开,这五种布局哪些布局还可以用?
答案:flex布局和table布局
- 参考文献:
后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址
文档协议
db 的文档库 由 db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。