1. CSS定位属性: position
1.1 定义及常见的属性值
1.1.1 定义:
position 属性指定了元素的定位类型。
1.1.2 常见的属性值:
position 属性的五个值:
- static 静态定位
- relative 相对定位
- fixed 固定定位
- absolute 绝对定位
- sticky 粘性定位
1.2 static 定位
HTML 元素的默认值,即没有定位,遵循正常的文档流对象。
静态定位的元素不会受到 top, bottom, left, right影响。
实例
div.static {
position: static;
border: 3px solid #73AD21;
}
1.3 relative 定位
相对定位元素的定位是相对其正常位置。
实例
h2.pos_left {
position:relative;
left:-20px;
}
h2.pos_right {
position:relative;
left:20px;
}
移动相对定位元素,但它原本所占的空间不会改变。
相对定位元素经常被用来作为绝对定位元素的容器块。
1.4 fixed 定位
元素的位置相对于浏览器窗口是固定位置。
即使窗口是滚动的它也不会移动:
实例
p.pos_fixed {
position:fixed;
top:30px;
right:5px;
}
Fixed定位使元素的位置与文档流无关,因此不占据空间。
Fixed定位的元素和其他元素重叠。
1.5 absolute 定位
绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于:
实例
h2 {
position:absolute;
left:100px;
top:150px;
}
absolute 定位使元素的位置与文档流无关,因此不占据空间。
absolute 定位的元素和其他元素重叠。
1.6 sticky 定位
- sticky 英文字面意思是粘,粘贴,所以可以把它称之为粘性定位。
- position: sticky; 基于用户的滚动位置来定位。
- 粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。
- 它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。
- 元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
注意: Internet Explorer, Edge 15 及更早 IE 版本不支持 sticky 定位。 Safari 需要使用 -webkit- prefix (查看以下实例)。
实例
div.sticky {
position: -webkit-sticky; / Safari /
position: sticky;
top: 0;
background-color: green;
border: 2px solid #4CAF50;
}
1.7 重叠的元素
- 元素的定位与文档流无关,所以它们可以覆盖页面上的其它元素
- z-index属性指定了一个元素的堆叠顺序(哪个元素应该放在前面,或后面)
- 一个元素可以有正数或负数的堆叠顺序:
实例
div {
position:absolute;
left:0px;
top:0px;
z-index:-1;
}
具有更高堆叠顺序的元素总是在较低的堆叠顺序元素的前面。
注意: 如果两个定位元素重叠,没有指定z - index,最后定位在HTML代码中的元素将被显示在最前面。
1.8 position 难点分析
1.8.1 绝对定位vs相对定位
绝对定位好像把不同元素安排到了一栋楼的不同楼层(除首层,文本流放在首层),它们之间互不影响;相对定位元素在首层,与文本流一起存放,它们之间互相影响。
被设置了绝对定位的元素,在文档流中是不占据空间的,如果某元素设置了绝对定位,那么它在文档流中的位置会被删除,它浮了起来,其实设置了相对定位也会让元素浮起来,但它们的不同点在于,相对定位不会删除它本身在文档流中占据的空间,其他元素不可以占据该空间,而绝对定位则会删除掉该元素在文档流中的位置,使其完全从文档流中抽了出来,其他元素可以占据其空间,可以通过z-index来设置它们的堆叠顺序 。
2 BFC
BFC(Block Formatting Context),块级格式化上下文,它规定了内部的块级元素的布局方式,默认情况下只有根元素(即body)一个块级上下文。
2.1 BFC布局规则
- 内部的块级元素会在垂直方向,一个接一个地放置;
- 块级元素垂直方向的距离由margin决定。属于同一个BFC的两个相邻的块级元素会发生margin合并,不属于同一个BFC的两个相邻的块级元素不会发生margin合并;
- 每个元素的margin box的左边,与包含border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
- BFC的区域不会与float box重叠;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素;外面的元素也不会影响到容器里面的子元素;
- 计算BFC的高度时,浮动元素也参与计算。
2.2 创建一个BFC
首先我们要知道怎样创建BFC。一个BFC可以被显式触发,只需满足以下条件之一:
- float的值不为none;
- overflow的值不为visible;
- position的值为fixed / absolute;
- display的值为table-cell / table-caption / inline-block / flex / inline-flex。
2.3 BFC的应用
2.3.1 BFC中的盒子对齐
[图片上传失败...(image-1a0381-1617756617306)]
div {
height: 20px;
}
.container {
position: absolute; /* 创建一个BFC环境*/
height: auto;
background-color: #eee;
}
.box1 {
width: 400px;
background-color: red;
}
.box2 {
width: 300px;
background-color: green;
}
.box3 {
width: 100px;
background-color: yellow;
float: left;
}
.box4 {
width: 200px;
height: 30px;
background-color: purple;
}
2.3.2 外边距折叠
在常规文档流中,两个兄弟盒子之间的垂直距离是由他们的外边距所决定的,但不是他们的两个外边距之和,而是以较大的为准。
[图片上传失败...(image-4a53a2-1617756617306)]
.container {
overflow: hidden;
width: 100px;
height: 100px;
background-color: red;
}
.box1 {
height: 20px;
margin: 10px 0;
background-color: green;
}
.box2 {
height: 20px;
margin: 20px 0;
background-color: green;
}
这里我门可以看到,第一个子盒子有上边距(不会发生margin穿透的问题);两个子盒子的垂直距离为20px而不是30px,因为垂直外边距会折叠,间距以较大的为准。
那么有没有方法让垂直外边距不折叠呢?答案是:有。特性的第5条就说了:bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素,同样外面的元素不会影响到BFC内的元素。所以就让box1或box2再处于另一个BFC中就行了。
[图片上传失败...(image-9fdeab-1617756617306)]
.container {
overflow: hidden;
width: 100px;
height: 100px;
background-color: red;
}
.wrapper {
overflow: hidden;
}
.box1 {
height: 20px;
margin: 10px 0;
background-color: green;
}
.box2 {
height: 20px;
margin: 20px 0;
background-color: green;
}
2.3.3 不被浮动元素覆盖
以常见的两栏布局为例。
左边固定宽度,右边不设宽,因此右边的宽度自适应,随浏览器窗口大小的变化而变化。
[图片上传失败...(image-b8933e-1617756617306)]
.column:nth-of-type(1) {
float: left;
width: 200px;
height: 300px;
margin-right: 10px;
background-color: red;
}
.column:nth-of-type(2) {
overflow: hidden;/*创建bfc */
height: 300px;
background-color: purple;
}
还有三栏布局。
左右两边固定宽度,中间不设宽,因此中间的宽度自适应,随浏览器的大小变化而变化。[图片上传失败...(image-b204af-1617756617306)]
.column:nth-of-type(1),
.column:nth-of-type(2) {
float: left;
width: 100px;
height: 300px;
background-color: green;
}
.column:nth-of-type(2) {
float: right;
}
.column:nth-of-type(3) {
overflow: hidden; /*创建bfc*/
height: 300px;
background-color: red;
}
2.3.4 用来防止字体环绕
众所周知,浮动的盒子会遮盖下面的盒子,但是下面盒子里的文字是不会被遮盖的,文字反而还会环绕浮动的盒子。这也是一个比较有趣的特性。
[图片上传失败...(image-4b02d0-1617756617306)][图片上传失败...(image-9bfbba-1617756617306)]
你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
环绕
.left {
float: left;
width: 100px;
height: 100px;
background-color: yellow;
}
p {
background-color: green;
/* overflow: hidden; */
}
利用bfc防止环绕
.left {
float: left;
width: 100px;
height: 100px;
background-color: yellow;
}
p {
background-color: green;
overflow: hidden;
}
2.3.5 清除浮动
浮动的元素会脱离普通文档流,来看下下面一个例子:
[图片上传失败...(image-13940f-1617756617306)]
由于容器内元素浮动脱离文档流,导致容器只剩下2px边距高度,我们这时候可以采用BFC:
[图片上传失败...(image-fc7d18-1617756617306)]
2.3.6 阻止元素被浮动元素覆盖
先看一个文字环绕效果:
我是一个左浮动的元素
我是一个没有设置浮动,
也没有触发 BFC 元素, width: 200px; height:200px; background: #eee;
[图片上传失败...(image-98ee4e-1617756617306)]
这时候其实第二个元素有部分被浮动元素所覆盖,(但是文本信息不会被浮动元素所覆盖) 如果想避免元素被覆盖,可触第二个元素的 BFC 特性,
在第二个元素中加入 overflow: hidden,就会变成:
[图片上传失败...(image-634470-1617756617306)]