position:absolute绝对定位解读
摘要
用四段代码解释absolute的定位问题,进而从概念的角度切实解决html布局问题。
一、背景
常常遇到这样一些问题,很容易混淆。“浏览器屏幕”,html,body谁的范围大?如果一个html文档中没有relative元素,那么该absolute元素是相对于哪里进行定位的?左上角?浏览器?html?body?等等类似的问题,只要涉及到定位就总要花一些时间去调试。本文的目的在于当遇到问题时,能够以文中阐述的观点作为依据,快速定位和解决问题。
二、概念及原理
1、web页面最外层的约束为body,就是浏览器面板能看到的部分。
2、body即可理解为文档流,从上到下,从左向右。
3、文档流超过了浏览器面板(可视区域),就会出现滚动条。
4、absolute的定制,就会将元素脱离文档流,不占据文档流,元素将不出现在文档流中,当浏览器渲染时,不会出现滚动条。
5、在文档流“流动”时,浏览器屏幕(范围),会在文档流中截出一块区域。可以简记为“第一屏”。
6、当没有定制relative时,absolute(元素无论大小)即以此定位。
三、现象及解析
body文档流并非就是元素内容所占据的空间,它就像一段河流,元素是在其上的物体。这是为了解释当元素内容少于一屏幕时,body的边界线在哪里,答案是仍然是一个屏幕扣出的一圈边界线。
1、元素小于屏幕高度
在上述原理的基础上,可以很好的解释如下几种现象。
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta name = "keyword" content = "liao">
<meta name = "description" content = "lllll">
<title>^ <> ^</title>
<style>
body{
margin:0;
}
.c0{
background-color:red;
height:300px;
}
.c0 .cell{
background-color:blue;
position:absolute;
bottom:10px;
right:10px;
}
</style>
</head>
<body>
<div class="c0">aaa
<div class="cell">bbb</div>
</div>
</body>
</html>
小蓝盒子处于屏幕的右下角。证明在元素内容少于一屏幕时,absolute盒子按照body的屏幕边界线摆放。
2、元素大于屏幕高度
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta name = "keyword" content = "liao">
<meta name = "description" content = "lllll">
<title>^ <> ^</title>
<style>
body{
margin:0;
}
.c0{
background-color:red;
height:3000px;
}
.c0 .cell{
background-color:blue;
position:absolute;
bottom:10px;
right:10px;
}
</style>
</head>
<body>
<div class="c0">aaa
<div class="cell">bbb</div>
</div>
</body>
</html>
这次尝试可以用前面原理合理的解释。即absolute盒子按照body的屏幕边界线摆放。因为滚动条移动时,框出的边界线向上移动了,所以小蓝盒子也随之移动。
3、哪里是absolute的参考线
用下面的例子再次证明哪里是absolute的参考线。
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta name = "keyword" content = "liao">
<meta name = "description" content = "lllll">
<title>^ <> ^</title>
<style>
body{
margin:0;
}
.pghead{
background-color:blue; height:50px;
color:white;
} .pgbody .menu{
position:absolute;
background-color:yellow;
left:0; width:180px;
color:white ;
} .pgbody .rtbody{
position:absolute;
background-color:pink;
top:50px;
bottom:20px; left:185px;
right:0;
color:black;
}
</style>
</head>
<body>
<div class="pghead">HHH
</div>
<div class="pgbody">
<div class="menu">
<h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h>
</div>
<div class="rtbody">
<h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1>
</div>
</div>
</body>
</html>
范例中,因为文字属于特殊的元素,当设定盒子absolute,bottom为10px时,原来被文字撑起的盒子只能到第一屏的边界线向上10px的位置,所以文字超出了盒子的范围,也超出了浏览器屏幕的范围,于是出现滚动条。而并不是像一些观点认为背景色会布满整个文档流,一直到距离最底部10px的位置。
下面的例子,使用了overflow:auto,并且absolute盒子,四面都定制了到body的边距。正是因为absolute以第一次浏览器框出body的边界线为基准,才能呈现出多于浏览器屏幕的内容辅助滚动条在一屏幕内显示的效果。
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta name = "keyword" content = "liao">
<meta name = "description" content = "lllll">
<title>^ <> ^</title>
<style>
body{
margin:0;
}
.pghead{
background-color:blue; height:50px;
color:white;
} .pgbody .menu{
position:absolute;
background-color:yellow;
left:0; width:180px;
color:white ;
} .pgbody .rtbody{
position:absolute;
background-color:pink;
top:50px;
bottom:20px;
overflow:auto;
left:185px;
right:0;
color:black;
}
</style>
</head>
<body>
<div class="pghead">HHH
</div>
<div class="pgbody">
<div class="menu">
<h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h>
</div>
<div class="rtbody">
<h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1>
</div>
</div>
</body>
</html>
4、图片的基准线
图片的基准线依然是上文说到的第一次浏览器框出body的边界线。请看下面的例子。
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta name = "keyword" content = "liao">
<meta name = "description" content = "lllll">
<title>^ <> ^</title>
<style>
body{
margin:0;
} .c0{
background-color:blue;
position:absolute;
bottom:10px;
right:10px;
}
</style>
</head>
<body>
<div class="c0">
<img src="zhuomian.jpg" style = "width:3000px;height:3000px;">
<div class="cell">bbb</div>
</div>
</body>
</html>
四、小结
本次验证基于几种常见的网页元素如不同大小的盒子,图片等。最终得出absolute以body的最开始的浏览器边界线为基准的结论。
总结两种验证方法。方法一:1)先将常见的元素列出,2)将各种元素常见的状态列出,然后一一做实验验证。3)最后得出归一化的共性的结论。
方法二:1)先根据一到两个现象猜测出基本原理,2)然后根据原理推想出其他元素的结果,若符合预期则说明猜想的原理正确,3)最后归纳得出结论。