用position:relative和float实现不定宽块级元素的居中

前言

首先是个前端中非常基础小白的话题,已经很清楚这个方法的前端大牛轻喷。我现在学习前端,对学习过程中进行的思考会作记录,希望能帮到有需要的人。

关于不定宽块级元素

块级元素我们很清楚,默认占据一行的元素,比如divul就是很典型的块级元素。对于定宽的块级元素居中,通过设置相应的marginauto即可,比如对宽度为500px的div元素:

div {
    width: 500px;
    margin: 20px auto;
}

这样,该定宽元素就可以居中了。
问题在于不定宽,也就是我们没有设置宽度,是不能通过以上方法来实现居中的。因为,不定宽的块级元素,其整个内容(即border + padding + width)就需要占据一整行,也就无法再通过margin:auto来实现居中,因为auto了之后,margin也是0。

关于position:relative和float

position:relative可以让元素相对于原来自身的位置进行偏移,通过设置topleft就可以进行偏移。
为了方便说明,我们先来写两个div元素:

<body>
<div id="parent">
    <div id="child">I am a child</div>
</div>
</body>

在设置topleft时还可以设置为百分比,这个百分比就是其父元素宽度的百分比,例如对一个不定宽的块级元素div#child进行以下设置,就可以让其往前移动div#parent宽度的50%,在我们的例子里,div#parentbody同宽。

div#child {
    position: relative;
    left: 50%;
}

注意这并不是居中!
居中是指其内容的中点正好位于页面的中点,而以上只是将其左边界移到了父元素容器的中点。

于是乎,如果div#parent进行50%的偏移,然后再让div#child反向进行50%偏移,是不是就可以实现居中了呢?

其实不然,因为对该元素进行反向50%,即left:-50%;偏移的时候,偏移的距离是父元素的宽度的一半,如果父元素刚好和body也就是页面的宽度一致,那相当于都是偏移页面宽度的一半,一正一反,刚好抵消。而如果父元素有自己的宽度,那就更加不好预测了。

所以问题的关键是确定元素偏移的距离问题。
现在div#parent已经被移动到页面的中点,我们期望的是:div#child设置了left:-50%之后,其偏移距离应该是自身内容的宽度的一半

注意:我们说元素的内容,说的是元素内可见的内容,比如这里div#child的『I am a child』,如果有不严谨的地方,请各位指出哈

那么怎么实现呢?

让我们理一下关系:
1. div#child的偏移距离是div#parent的宽度
2. div#child的偏移距离应该是其自身内容的宽度

所以只要div#parent的宽度和div#child内容的宽度一致不就行了?怎么做到呢?

这时我们可以用float

浮动对于盒子模型元素的效果就是从文档流中移出来,这时高度和宽度也随之塌缩到其所包含的子元素的宽度,比如做如下设置

div#parent {
    float: left;
}

div#parent的宽度就变成div#child的宽度

此外我们还会发现,body的高度变为0,因为其不再包含div#parent了,也就不包含任何元素。

这样就达到我们的目的了,总的来说,实现div#child居中,只要进行如下设置

div#parent {
    float: left;
    position: relative;
    left: 50%;
}
div#child {
    position: relative;
    left: -50%
}

多说几句

其实设置父元素的宽度与子元素相同,还有一种方法,那就是设置display:inline-block,可以用来代替float:left

div#parent {
    display:inline-block;
    position:relative;
    left:50%;
}
div#child {
    position:relative;
    left:-50%;
}

但是我发现,同样是以行内元素形式排列的display:inline却不能实现居中,观察元素宽度发现,设置了display:inline后的div#parent宽度是子元素的宽度,但不是子元素内容的宽度,那么子元素的宽度是多少?没错就是等于body的宽度,这是从上往下继承的。

然而如果我把div#child也设置成display:inline,此时父子元素的宽度都是子元素的内容的宽度了,仍然不能居中,仿佛此时div#child设置的left:-50%不是针对div#parent

看到这句疑惑以及结合inline元素的宽高特性,大家应该就可以理解了,要知道,如果我们去设置行内元素的宽高,是不会起作用的,所以让子元素去参照父元素的宽高偏移50%也是不会起作用的,因此子元素会继续向上寻找,找到一个块级元素,或者一个inline-block的元素,并以其宽高为百分比基准。而在本例中,那就是body

这是我个人得出的结论,没有经过官方证实,但我觉得可以说明问题

所以,为父元素设置display:inline是不能实现居中的,而应该用display:inline-block

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值