内容简介:CSS进阶——绝对定位元素的宽高是如何定义的
先抛两个小问题:
- 绝对定位相对于谁来定位?
大多数人都知道是相对于最近的position设置为relative/absolute/fixed的父元素来定位。那如果所有父元素的position都没有设置上面三个值,那又是相对谁来定位呢? - 包含块是什么?初始包含块又是什么?
元素A包含元素B,A设置position:relative,B设置position:absolute;left:0;top:0,这个left:0;top:0是相对于A元素的content-box、padding-box还是margin-box的左上角?
如果你还不是很有把握说出来答案,可以先思考一下或者实践一下,然后再阅读后面的内容。
绝对定位元素的特性
- 绝对定位元素完全脱离文档流,不会对后面兄弟元素的布局产生任何影响
- 其位置(或者说大小)是由
toprightbottomleft四个属性决定的 - 绝对定位元素的
margin不会和其他元素的margin折叠
上面说到绝对定位元素的大小是由 top right bottom left 四个属性决定的, 这四个属性是相对于绝对定位元素的 包含块 来定位的 。
包含块
-
绝对定位元素的包含块是由其最近的
position属性设置为relative、absolute或fixed的祖先元素,按照以下方式生成的:- 如果这个祖先元素是行内元素...此种情况请参考后续文章
- 否则,包含块是由祖先元素的
padding edge组成(即相对于祖先元素padding-box进行定位)
-
如果绝对定位元素的所有祖先元素的
position属性都没有设置relative、absolute或fixed,则其包含块为初始包含块。
初始包含块
根元素(在HTML文档中即 <html>元素 )所在的包含块即是初始包含块,对于浏览器来说:初始包含块的大小即是视口的大小,但是是以画布原点为锚点的。
浏览器的视口是固定在那不变的,但是一个文档可能会很长,可以上下滚动,视口中的内容会不断变化。初始包含块可以简单理解为第一个视口区域(这句话是我自己造的),上图:
页面滚动之后:
<!-- demo1 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初始包含块</title>
<style>
html {
margin: 10px;
padding: 10px;
border: 1px solid red;
}
body {
padding: 10px;
border: 1px solid blue;
}
.abs {
position: absolute;
/*left: 0;*/
/*bottom: 0;*/
padding: 5px;
background-color: #9089e4;
color: #fff;
}
</style>
</head>
<body>
<h3>绝对定位之初始包含块</h3>
<div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>初始包含块不是html,也不是body,而是指视口。</div>
<div>滚到底啦,没有更多内容啦~~~</div>
<div class="abs">我是绝对定位元素。</div>
</div>
</body>
</html>
函数边框代表html元素,蓝色边框代表body元素,由gif图可以进一步加深对初始包含块的理解:初始包含块并不是大多数人认为的html或body元素,这是个误区,要纠正!
绝对定位元素的大小
静态位置(static position)
一个元素的静态位置可以简单理解为这个元素在普通文档流中的位置,就是这个元素的 position 为 static , float 为 none 时,元素在文档中所处的位置。
- 静态位置的left值 :包含块的左边界到当前定位元素的左外边距(Left Margin)边界的距离
- 静态位置的right值 :包含块的右边界到当前定位元素的右外边距(Right Margin)边界的距离
<!-- demo2 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初始包含块</title>
<style>
body {
position: relative;
padding: 10px;
border: 1px solid blue;
}
.abs {
position: absolute;
margin-left: 5px;
padding: 5px;
background-color: #9089e4;
border: 1px solid orange;
color: #fff;
}
.abs2 {
position: absolute;
top: 50px;
left: 10px;
margin-left: 5px;
padding: 5px;
background-color: #9089e4;
color: #fff;
border: 1px solid orange;
}
</style>
</head>
<body>
<div class="abs">绝对定位元素1</div>
<div class="abs2">绝对定位元素2</div>
<div>body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素body的其他子元素</div>
</body>
</html>
从上面代码可以看出, .abs 和 .abs2 两个元素的 静态位置的left值 都为10px(即body的padding-left值),我们不设置 .abs 的left值,即默认auto,而 .abs2 的left设置为10px,会看到两个元素距离包含块左边的距离是一样的。
绝对定位元素的布局
计算公式(width表示内容宽度,即标准盒子模型):
'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block
left、width、right默认值是auto
margin-left、margin-right默认值是0
以水平方向(从左至右:ltr)为例说明一下绝对定位元素的位置(或大小)是如何定义的。起决定因素的有 left``right``width ,每个属性都可以设置或者不设置值,默认为auto,设置了值的在表格中用1表示,总共有2 * 2 * 2 = 8 种情况:
| Left | Width | Right | 布局 |
|---|---|---|---|
| auto | auto | auto | 把margin-left和margin-right为auto的设置为 0 ;把left设置为 静态位置的left值 ;宽度自适应:margin-right边缘最远到right为0的位置(如果margin-right为0,则取border-right边缘,如果border-right-width也为0,则取padding-right边缘,下同) |
| 1 | auto | auto | 把margin-left和margin-right为auto的设置为 0 ;宽度自适应:margin-right边缘最远到right为0的位置 |
| auto | auto | 1 | 把margin-left和margin-right为auto的设置为 0 ;宽度自适应:margin-left边缘最远到left为0的位置 |
| auto | 1 | auto | 把margin-left和margin-right为auto的设置为 0 ;把left设置为 静态位置的left值 ; |
| 1 | 1 | auto | 把margin-left和margin-right为auto的设置为 0 ;从左至右按照各属性值布局 |
| auto | 1 | 1 | 把margin-left和margin-right为auto的设置为 0 ;从右到左按照个属性值布局 |
| 1 | auto | 1 | 把margin-left和margin-right为auto的设置为 0 ;宽度自动拉伸 |
| 1 | 1 | 1 | ① 如果margin-left和margin-right都为auto,此时二者相等,则按照上述方程计算出对应的margin值;如果此时计算出来的margin值为负值,则设置margin-left为0,然后根据方程再计算出margin-right的值。 ② 如果margin-left、margin-right中有一个为auto,则按照方程计算出这个值; ③ 如果margin-left、margin-right都设置了值,且导致方程左右不相等,则忽略right值。 |
上面是以水平方向布局讲述了绝对定位元素的宽度是如何定义的,高度是类似的,就不再详细阐述了,想进一步了解细节的同学请参考 https://www.w3.org/TR/CSS22/visudet.html#abs-non-replaced-height
本文主要参考资料:
https://www.w3.org/TR/CSS22/visudet.html篇幅已经很长了,还有一部分知识点没讲到:
包含块部分:
-
绝对定位元素的包含块是由其最近的
position属性设置为relative、absolute或fixed的祖先元素,按照以下方式生成的:-
如果这个祖先元素是行内元素...(包含块是如何定义的?)
-
布局部分:
上述所讲的绝对定位元素的布局是针对 非可替换元素 ,如果是 可替换元素 ,布局又是怎样的?这些内容将在下一篇文章中做进一步阐述。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Selenium Webdriver元素定位的方式
- 如何在Angular中快速定位DOM元素
- Selenium自动化测试之学会元素定位
- Python2+Selenium入门03-元素定位
- relative 和 absolute 元素的百分比定位
- 这些appium常用元素定位技巧,你掌握了几种?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C++ Primer 中文版(第 5 版)
[美] Stanley B. Lippman、[美] Josée Lajoie、[美] Barbara E. Moo / 王刚、杨巨峰 / 电子工业出版社 / 2013-9-1 / CNY 128.00
这本久负盛名的 C++经典教程,时隔八年之久,终迎来史无前例的重大升级。除令全球无数程序员从中受益,甚至为之迷醉的——C++ 大师 Stanley B. Lippman 的丰富实践经验,C++标准委员会原负责人 Josée Lajoie 对C++标准的深入理解,以及C++ 先驱 Barbara E. Moo 在 C++教学方面的真知灼见外,更是基于全新的 C++11标准进行了全面而彻底的内容更新。......一起来看看 《C++ Primer 中文版(第 5 版)》 这本书的介绍吧!