前端学习笔记
【问题记录】
创建了一个body下的div子元素,当把该元素的定位模式设置为相对定位(relative)时,视口正中间显示失败。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
height: 100%;
}
.box1 {
position: relative; //当把该div定位模式设置为相对定位时,居中失败
left: 50%;
top: 50%; //未正确生效
width: 400px;
height: 400px;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="box1">
</div>
</body>
结果如下,盒子并未显示在视口正中间:
【问题分析】
给元素添加了定位后,使用高度百分比更改元素位置时,【重要】元素高度百分比需要向上遍历父标签直到找到一个定值高度才能起作用,如果中途有个height为auto或是没有设置height属性,那么高度百分比不起作用。
而在这段代码中,div没有其他非static定位模式(即设置了relative/absolute)的父级元素,所以该元素默认是相对于body进行定位,而body的默认高度是auto(问题在这里),所以这里给top设置百分比是无效的。
【解决方法】
方法1:top设置为具体的像素值,不要用百分比(这种方式就不演示了);
方法2:改变body的height值为整个视口高度,方法如下:
同时将body、html根元素的高度设置为100%,body的高度依赖于html的高度,设置html的height:100%,就可以获取浏览器的定高
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
height: 100%; //将html,body高度设置为100%
}
.box1 {
position: relative;
left: 50%;
top: 50%;
width: 400px;
height: 400px;
background-color: pink;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="box1">
</div>
</body>
结果如下,显示正常:
方法3:
直接将div元素的定位模式设置为绝对定位,也可以达到同样的效果。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1 {
position: absolute; //设置为绝对定位
left: 50%;
top: 50%;
width: 300px;
height: 300px;
background-color: pink;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="box1">
</div>
</body>
经过查询一些资料,对于以上几种方法实现原理的思路理解如下:
1、相对定位:参考的是直系父级元素进行定位。(不论父级是何种定位、默认的static也算)
那么在这个例子中,当box1设置采用相对定位时,它的直系父级就是body,而body的高度height默认值是auto,所以不做任何处理的情况下,top百分比就会失效。如果希望用相对定位达到理想效果的话,那么解决方法就是如方法2所述,将body和html的height值设置为100%。
2、绝对定位:参考的是距离其最近的非static祖先元素进行定位。
如果不存在这样的祖先元素,那么默认参考ICB(initial containing block,初始包含块) 【注意:这个概念很重要,看到相关的解释很少,但是在MDN开发技术文档中提到了。】 这一点也解释了为什么绝对定位在不设置body宽和高的情况下也可以实现相同的效果。
首先,ICB(初始包含块)范围:是从页面的顶端到浏览器的底端。我个人对于这个概念的通俗理解是:在不拖动滚动条情况下我们所看到的浏览器窗口,它是有具体尺寸的,也就是说初始包含块的高度和宽度都是有具体数值的。
所以在这个例子中,当box1采用绝对定位时,因为没有符合要求的非static祖先元素,所以其参考的是ICB初始包含块,而正如上面提到,初始包含块的高度和宽度都是有具体数值的,top百分比自然就可以生效了。
参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/position
欢迎大家一起讨论、共同进步!