我们知道,在css中,有很多属性都可以达到居中的效果,而作为一名前端开发者,垂直居中要比水平居中麻烦的多,这是历史遗留的问题。
最初的css针对的主要是web文档的布局,他对垂直方向的需求并没有那么的强烈,以至于并没有专门的设计来实现这一需求。
事实上在css领域,存在着三大经典问题,垂直居中,多列等高和宽度自适应。
我们逐一来看一下这这三大经典问题。
垂直居中
在讲垂直居中之前,我们顺带来说一下水平居中,如果是块级元素,可以在子元素中添加margin:0 auto
,如果是行内元素,可以直接添加一个text-align:center
这是最为经典的实现方式,当然还有其他的方式,也可以参考下面垂直居中的一些方式,我们重点来讲垂直居中,假设有这样两个元素:
<style>
.parent{
width: 100px;height: 100px;
background-color: aquamarine;
}
.child{
width: 100px;height: 10px;
background-color: red;
}
</style>
<div class="parent">
<div class="child"></div>
</div>
- 绝对定位和负边距
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
margin: -5px 0 0 0; /* 值得一提的是如果child的高度为10%,这里的负边距可以改为-5% */
}
- 绝对定位和transform
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
- 绝对定位和margin:auto
.parent{
position: relative;
}
.child{
position: absolute;
top: 0;bottom: 0;
margin: auto;
}
- 万能的伪元素
.child{
margin-top: -5px;
}
.parent::before{
content: '';
height: 50%;
display: block;
}
- 表格布局table
.parent{
display:table;
}
.child{
display:table-cell;
vertical-align: middle;
}
- 单行文本下的line-height
- 弹性布局(flex)弹性布局下的实现实际不止这么一种方式这里提一下,后面会单独开一章节讲弹性布局
.parent{
display: flex;
align-items: center;
}
多列等高
我们先来看一下这到底是一个什么问题:
<style>
.child{
width: 100px;
background-color: #2196F3;
display: inline-block;
}
</style>
<div class="parent">
<div class="child">内容内容内容内容内容内容内容内容内容内容</div>
<div class="child">内容</div>
<div class="child">内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容</div>
</div>
因为内容的不同这三列拥有各自的高度,怎么让他们一样高呢?
- 真等高:flex布局
这是最简单的一种方式,只需要给parent加一个属性display:flex
,因为弹性布局默认自带等高布局的特点。 - 真等高:利用table
table布局同样也具有等高的特性,这个也非常简单,给parent加一个属性display:table
,然后改变child的display为display:table-cell
。
3、假等高:利用子组件的内外边距(padding和margin)
.parent{
overflow: hidden;
}
.child{
display: inline-block;
padding-top: 9999px;
margin-top: -9999px;
}
/* 或者 */
.child{
padding-bottom: 9999px;
margin-bottom: -9999px;
float: left;
}
- 假等高:父容器渐变背景色
宽度自适应
最后一个问题就是在我们的多列布局中,最后一个div
宽度自适应的问题,我们来看解决方法:
<style>
.parent{
width: 200px;height: 100px;
}
.child1{
width: 100px;height: 100%;
background-color: #2196F3;
display: inline-block;
}
.child2{
height: 100%;
background-color: rgb(44, 228, 27);
display: inline-block;
}
</style>
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
flex-group:1
.parent{
display:flex;
}
.child2{
flex-group:1; /* 或者直接flex:1也是一样的效果 */
}
- 依旧是table,将parent设置
display:table
,然后将child1设置为display:table-cell
-
float
配合overflow:hidden
.child1{
float: left;
}
.child2{
background-color: rgb(44, 228, 27);
overflow:hidden;
}
child2会默认填满整个parent,然后因为overflow的关系隐藏在child1下的部分。
- 这里有一种特殊情况,如果子元素只有一个,需要定死一边的宽度,往另外一遍填满,还可以使用绝对定位加margin-left的方法
.parent{
position: absolute;
}
.child{
margin-left:100px;
}