用三种不同的方式实现的元素水平垂直居中效果,inline-block实现的效果和position绝对定位实现的效果在高度上有差别。postion实现和flex实现效果也是有细微差别的,设置padding:0,margin:0消除了差别,但是inline-block效果和position效果不明白是怎么出现的。。。谁来救一下强迫症患者吖
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>task</title>
<style>
* {
padding: 0;
margin: 0;
}
/*父级元素充满屏幕*/
html, body {
width: 100%;
height: 100%;
}
.button {
border-style: none;
background-color: dodgerblue;
color: #fff;
padding: 10px;
/*cursor: pointer;*/
border-radius: 5px;
/*去掉按钮的选中框样式*/
outline: none;
}
.rectangle {
width: 400px;
height: 200px;
background-color: #ccc;
}
.circle {
background-color: #fc0;
width: 50px;
height: 50px;
}
#r1 {
position: absolute;
left: 50%;
top: 50%;
/* 水平居中也可以用CSS3中的translate,同样的 定高垂直居中也可以用负边距*/
margin-left: -200px;
/*不定高的垂直居中*/
transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
-webkit-transform: translate(0, -50%);
-o-transform: translate(0, -50%);
-moz-transform: translate(0, -50%);
}
#r2 {
position: relative;
}
#r3 {
display: inline-block;
vertical-align: middle;
position: relative;
}
#c1_1 {
position: absolute;
border-bottom-right-radius: 50px;
}
#c2_1 {
position: absolute;
right: 0;
bottom: 0;
border-top-left-radius: 50px;
}
.wrapper-flex {
display: flex;
justify-content: center;
align-items: center;
}
.wrapper-inline::after {
content: '';
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
}
.wrapper-inline {
text-align: center;
font-size: 0;
}
</style>
</head>
<body>
<div style="padding:10px;position:absolute;left: 50%;margin-left:-150px;width:300px;">
<button class="button">定位法</button>
<button class="button">flex法</button>
<button class="button">inline-block与伪元素法</button>
</div>
<!--子元素设置宽高100%,占满整个屏幕-->
<div id="main" style="width: 100%;height: 100%;">
<div id="r1" class="rectangle">
<div id="c1_1" class="circle"></div>
<div id="c2_1" class="circle"></div>
</div>
</div>
<script>
(function () {
var ops = document.getElementsByTagName("button"),
main = document.getElementById("main");
ops[0].addEventListener("click", function () {
main.className = "";
main.firstElementChild.setAttribute("id","r1");
});
ops[1].addEventListener("click", function () {
main.className = "wrapper-flex";
main.firstElementChild.setAttribute("id","r2");
});
ops[2].addEventListener("click", function () {
main.className = "wrapper-inline";
main.firstElementChild.setAttribute("id","r3");
});
})();
</script>
</body>
</html>
因为
position: absolute
定位时,坐标系参照外层首个确定了坐标系的元素。也就是:如果position: absolute
定位的元素的父元素的坐标系是确定的,那这个元素的定位坐标系和父元素相同,如果父元素坐标系不确定,则参照父元素的父元素,依次类推,如果所有的祖先元素坐标系都不确定,那么它将按照document
的坐标系。其次,
position: absolute
定位时,被定位的元素并不跟随HTML的布局流。如果垂直屏幕向外的方向看做是Z轴的话,position: absolute
定位时,被定位元素在z轴上有无穷大的偏移量,和HTML原本的布局流不在同一层面上,不会受到其他元素布局的影响。而
flex
和inline-block
则不同,由于这两种方法都是跟随HTML布局流的,所以HTML流中间的其他元素的布局会影响到这两种方法。然后来说一下你这个代码。由于你的
#r1
(也就是绝对定位方法),父元素是#main
,但是由于#main
的坐标系不定,所以#r1
实际上是以document
的坐标系为准的。然而浏览器中,默认的document
带有几像素的边距,所以以document
坐标系为准的#r1
就会有些许偏移。而padding: 0; margin: 0
则是去掉了document的边距,所以才会使三个显示一样的。而在你的代码里,
flex
和inline-block
这两种方法都是跟随HTML布局流的,所以定位都是按照布局中父元素#main
来进行的,因此绝对定位法和其他两种有差异。如果你给
#main
加上CSS:position: relative
,这样就使#r1
的父元素的坐标系定义了,这样即使不加padding: 0; margin: 0;
也可以使三个方法实现效果相同。