一、起因:
有学弟学妹问到我如何让浮动(脱离文档流)的元素竖直居中,因为他发现当元素浮动之后margin:auto便不再起作用了。在为他解答之后,想把解决的过程和方法记录下来。
二、示例代码:
<!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>Document</title>
<style>
/* eliminate default style */
* {
/* init margin */
margin: 0;
/* init padding */
padding: 0;
}
/* outerDiv Style */
.topDiv {
height: 200px;
background-color: #BAE1FC;
}
.bottomDiv {
height: 200px;
background-color: #92B1D2;
}
/* innerDiv Style 使用 > 子类选择器赋值 */
/* topDiv中的中间元素为浮动后元素 */
.topDiv>.centerElem {
/* 意思为:给了类名为topDiv下的centerElem类名的元素设置样式,
不影响非topDiv下名为centerElem的元素 */
width: 100px;
height: 100px;
background-color: #B291CA;
float: left;
/* 使元素居中,但在浮动元素(脱离文档流后的元素)、
以及未设置宽度的块级元素中不生效 */
margin: auto;
}
/* bottomDiv中的中间元素为未浮动元素 */
.bottomDiv>.centerElem {
/* 意思为:给了类名为bottomDiv下的centerElem类名的元素设置样式,
不影响非bottomDiv下名为centerElem的元素 */
width: 100px;
height: 100px;
background-color: #B291CA;
/* 使元素居中,但在浮动元素(脱离文档流后的元素)、
以及未设置宽度的块级元素中不生效 */
margin: auto;
}
</style>
</head>
<body>
<!-- topDiv 顶部背景板 -->
<div class="topDiv">
<!-- 将被设为居中的中间元素 -->
<div class="centerElem"></div>
</div>
<!-- bottomDiv 底部背景板 -->
<div class="bottomDiv">
<!-- 将被设为居中的中间元素 -->
<div class="centerElem"></div>
</div>
</body>
</html>
- 目前的页面效果图:
三、margin:auto失效的原因:
在第二点中可以比较清楚的看到topDiv中的centerElem元素并没有在topDiv中水平居中,是因为margin:auto效果没有生效。具体的margin底层原理大家可以参考这篇文章,那么什么原因会导致margin:auto失效呢?
- 当元素脱离文档流之后,如给元素加上float、position中的absolute等样式。
- 元素为行内元素。
- 元素为块级元素但没有设置宽度。
四、如何让浮动的元素水平居中:
本点我们要分两种情况来讨论 :
- 知道浮动元素的宽高
- 不知道浮动元素的宽高
每种方法都是基于上文中最初的版本进行修改。
方法一、嵌套法(只适用于知道宽高的情况)
顾名思义,嵌套法就是在浮动元素的外面嵌套上一层父容器,俗话说的好一层不行就再套一层,这句话不止在后端写接口的时候适用,在前端页面编写的时候也适用。接下来附上改动的代码,其他地方与前文初始代码一致。
<style>
/* 因为在centerElem的外边套了一层nestedDiv,因此要修改字选择器代码 */
/* 如果使用 .topDiv .centerElem 后代选择器可忽略此步 */
.nestedDiv>.centerElem {
/* 意思为:给了类名为topDiv下的centerElem类名的元素设置样式,
不影响非topDiv下名为centerElem的元素 */
width: 100px;
height: 100px;
background-color: #B291CA;
float: left;
/* 使元素居中,但在浮动元素(脱离文档流后的元素)、
以及未设置宽度的块级元素中不生效 */
margin: auto;
}
/* nestedDiv Style */
.nestedDiv {
width: 100px;
height: 100px;
margin: auto;
}
</style>
<!-- topDiv 顶部背景板 -->
<div class="topDiv">
<!-- 嵌套层Div -->
<div class="nestedDiv">
<!-- 将被设为居中的中间元素 -->
<div class="centerElem"></div>
</div>
</div>
方法二、通过定位来解决(两种情况都可用也比较使用)
在这种方法中我们可以使用绝对定位(absolute)代替float实现效果。
<style>
.topDiv {
height: 200px;
background-color: #BAE1FC;
/* 为父容器设置一个相对定位 */
position: relative;
}
.topDiv>.centerElem {
/* 意思为:给了类名为topDiv下的centerElem类名的元素设置样式,
不影响非topDiv下名为centerElem的元素 */
/*不设置也不会影响元素居中 */
width: 100px;
/*不设置也不会影响元素居中 */
height: 100px;
background-color: #B291CA;
/* 使用定位 */
position: absolute;
/* 如果只设置left:50%,便只是元素的左侧处于居中位置,
并不是我们想要的元素中央处于页面中间的效果
*/
left: 50%;
/* 因此使用translateX使得元素基于本身宽度向左平移50%,
也就是将元素中间移动到页面中线上,得到我们想要的居中效果 */
transform: translateX(-50%);
}
</style>
方法三、flex布局
这个方法相对来说比较容易理解,只要有学习过flex布局相关知识的兄弟都可以轻松理解。
<style>
.topDiv {
height: 200px;
background-color: #BAE1FC;
/* 将display属性修改为flex */
display: flex;
/* 设置水平(主轴)方向的对齐方式 */
/* 设置对齐方式为居中排列 */
justify-content: center;
}
.topDiv>.centerElem {
/* 意思为:给了类名为topDiv下的centerElem类名的元素设置样式,
不影响非topDiv下名为centerElem的元素 */
width: 100px;
height: 100px;
background-color: #B291CA;
/* 将浮动和margin属性都去除 */
}
</style>
五、总结
以上便是本次向大家分享的三种比较常用的使浮动(脱离文档流)元素水平居中的方法。