首先来看症状:
按理说蓝色和红色div应该并排同行显示,但是很明显:两个元素重叠了
代码如下:
- <!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>AbsoluteFloatTest</title>
- <style>
- .wrapper {
- position: relative;
- width: 100%;
- height: 200px;
- overflow: hidden;
- }
-
- div {
- height: 100px;
- }
- .first {
- position: absolute;
- width: 100px;
- top: 0;
- background: blue;
-
- }
-
- .second {
- width: 150px;
- background: red;
-
- }
-
- .fl {
- float: left
- }
-
- </style>
- </head>
- <body>
- <div class="wrapper">
- <div class="first fl"></div>
- <div class="second fl"></div>
- </div>
-
- </body>
- </html>
再看一个例子:
同样也重叠了。
那么问题的原因到底是什么?
这里需要对absolute绝对定位有充分深度的了解。
absolute绝对定位有一个非常重要的特征: 它会使元素脱离正常文档流,并且不占据任何空间
换句话说:使用绝对定位的元素,因为释放了文档流,会导致它后面的元素,往前移动填充它所占据的空间,这就是为什么会出现前面元素重叠问题的原因
如果我们要解决这个问题,有以下两个办法:
1. 让后面的元素使用left调整位置
但是因为这个定位是相对于根元素的最左边,需要手动计算left偏移距离,而且会造成它后面的元素也会产生重叠的问题,那么后面的每个元素都需要设置left定位属性,而且是手动计算从最左边开始的left值。这个过程相当繁琐,失去了通过div浮动实现水平排列的便利优势。
2. 弃用absolute绝对定位,使用float或者flex来实现元素的水平排列。
所以一般情况下,不要轻易使用absolute绝对定位,因为它的坑实在是太大了, 它会使元素脱离正常文档流,并且不占据任何空间,使用绝对定位的元素,因为释放了文档流,会导致它后面的元素,往前移动填充它所占据的空间,从而造成元素重叠。
使用绝对定位的场景: 一般是需要子元素对父级元素做相对定位:
此时父级元素设置:position : relative
而子元素设置: position: absolute
而由于子元素使用了绝对定位,那么也就是释放了文档流,此时必须使用left/right/top/bottom等属性进行定位!
比如下面的例子: