javascript - inline-block和伪元素实现元素水平垂直居中和用position绝对定位实现元素水平居中,效果不同?

查看:78
本文介绍了javascript - inline-block和伪元素实现元素水平垂直居中和用position绝对定位实现元素水平居中,效果不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

用三种不同的方式实现的元素水平垂直居中效果,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原本的布局流不在同一层面上,不会受到其他元素布局的影响。

flexinline-block则不同,由于这两种方法都是跟随HTML布局流的,所以HTML流中间的其他元素的布局会影响到这两种方法。

然后来说一下你这个代码。由于你的#r1(也就是绝对定位方法),父元素是#main,但是由于#main的坐标系不定,所以#r1实际上是以document的坐标系为准的。然而浏览器中,默认的document带有几像素的边距,所以以document坐标系为准的#r1就会有些许偏移。而padding: 0; margin: 0则是去掉了document的边距,所以才会使三个显示一样的。
而在你的代码里,flexinline-block这两种方法都是跟随HTML布局流的,所以定位都是按照布局中父元素#main来进行的,因此绝对定位法和其他两种有差异。

如果你给#main加上CSS:position: relative,这样就使#r1的父元素的坐标系定义了,这样即使不加padding: 0; margin: 0;也可以使三个方法实现效果相同。

这篇关于javascript - inline-block和伪元素实现元素水平垂直居中和用position绝对定位实现元素水平居中,效果不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆