标准流
什么是标准流
- 从左到右、从上到下按顺序摆放好
- 默认情况下,互相之间不存在层叠现象
设置 margin padding 也能实现层叠,但是会影响别的元素,所以不方便。
所以诞生了定位 position。
什么是定位
定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为:
- 例如放在另一个元素的上面;
- 或者始终保持在浏览器视窗内的同一位置;
position 属性
利用 position 可以对元素进行定位,常用取值有5个:
◼ 默认值:
- static:默认值, 静态定位
◼ 使用下面的值, 可以让元素变成 定位元素(positioned element)
- relative:相对定位
- absolute:绝对定位
- fixed:固定定位
- sticky:粘性定位
静态定位 - static
position 属性的默认值
- 元素按照 normal flow 布局
- left 、right、top、bottom没有任何作用
相对定位 - relative
特点:
- 元素按照 normal flow 布局,不脱标
- 可以通过 left、right、top、bottom 进行定位
- 定位参照对象是元素自己原来的位置
- left、right、top、bottom用来设置元素的具体位置,对元素的作用如下图所示
- 相对定位的应用场景
- 在不影响其他元素位置的前提下,对当前元素位置进行微调
图片居中
图片中间的重要内容保持页面居中的案例:
当页面盒子缩小,裁剪了背景。要做的核心就是图片的中点和页面的中线重合,这样就能保证图片中间的重要内容不会裁剪掉。
保持中线重合思路:
- 图片像左移动一半图片宽度,也就是让图片中线和 div 最左边的边线重合。
- 再让图片向右移动 div 一半的宽度,两条中线就重合了。
具体怎么移?
- 向左移就靠相对定位
left = 负值
,宽度的一半- 获取图片的宽度,可以手动计算写死,但显然不够好
- 向左移动一半还可以通过
transform: translate(-50%);
- translate 的百分比相对的是自己,所以 50% 就拿到了图片的一般宽度。
- 向右移动,则要靠
margin-left: 50%;
- 向右移可以通过 padding 也可以通过 margin,padding 不够好,因为 padding 不好拿到 div 的宽度
- 而使用 margin,margin 的百分比相对的就是父元素的宽高,所以百分之 50 就轻易拿到了 div 的宽度。
div img {
position: relative;
/* left: -100px; */
transform: translate(-50%);
margin-left: 50%;
}
这种图片定位的方式有点麻烦,最便捷的还是背景图的定位 background-position
固定定位 - fixed
特点:
- 元素脱离 normal flow(脱离标准流、脱标)
- 可以通过left、right、top、bottom进行定位
- 定位参照对象是视口(viewport)
- 当画布滚动时,固定不动
画布 和 视口
视口(Viewport)
- 文档的可视区域
- 如右图红框所示
画布(Canvas)
- 用于渲染文档的区域
- 文档内容超出视口范围,可以通过滚动查看
- 如右图黑框所示
宽高对比
- 画布 >= 视口
绝定定位 - absolute
特点:
- 元素脱离normal flow(脱离标准流、脱标)
- 可以通过left、right、top、bottom进行定位
- 定位参照对象是最邻近的定位祖先元素
- 如果找不到这样的祖先元素,参照对象是视口
什么是定位元素(positioned element)?
- position 值不为 static 的元素,也就是 position 值为 relative、absolute、fixed 的元素
其中 position 值为 absolute 或者 fixed 的元素也称为绝对定位元素(absolutely positioned element)
子绝父相
绝对定位元素的特点
- 可以随意设置宽高
- 宽高默认由内容决定
- 不再受标准流的约束
- 不再严格按照从上到下、从左到右排布
- 不再严格区分块级(block)、行内级(inline),行内块级(inline-block)的很多特性都会消失
- 不再给父元素汇报宽高数据
- 脱标元素内部默认还是按照标准流布局
绝对定位元素居中定位
margin: 0 auto; 为什么能居中?
我们知道块级元素默认是占满父元素的一行,假设一行为 1000px,如果设置 div width 为 100px,那么剩下的 900px 就会被外边距 margin 填满。
此时如果给 div 的左右 margin 都设为 auto,则浏览器就会平均分剩下的空间,这就让 div 居中了。
垂直方向不能这么居中,是因为元素没有自动撑满父元素高度的特点,所以无法利用浏览器的 auto 特性实现垂直居中。
绝对定位元素的居中
现在绝对定位元素,元素的外界可不止只有 margin 了,还有 left、right、top、bottom 这些。
当父元素宽度为 1000px,绝对定位元素 width 为 100px。这次剩下的 900px 可不会被分配给 margin-right 了,而是分配给 right。
那能不能 left 和 right 为 auto,让浏览器来自动平均分剩下的 900px 呢?
答案是浏览器不会针对 left,right 这些方向定位有平均分的效果。
既然浏览器只会平均分 margin,那我们岂不是可以把所有的外边距给 margin ,手动形成普通 div 的效果,以达到居中的目的?
答案是肯定的。left,right 为 0,再让 margin:0 auto,剩下的 900px 就被浏览器分配给左右外边距并平均分了。
同样的垂直方向将 top,bottom 为 0,再让 margin:auto,就能实现垂直居中。
绝对定位元素能垂直居中也是因为它相对父元素的定位全是我们手动指定,有种权利下方的感觉。所以能 auto 垂直居中。
总结一下:
绝对定位元素的外界大小 = margin + left/right/top/bottom ,所以可以将方位的距离全置为 0,让 margin 占满所有外边距,再利用 auto 的特点,就实现了元素的垂直,水平的居中。
注意:居中盒子需要有大小,要设置 width 或 height。
绝对定位元素获取父元素的宽高
绝对定位元素的父元素一般是相对定位。
父元素的宽高 = 绝对定位元素盒子大小 + 外界大小
所以设置 left: 0、right: 0、top: 0、bottom: 0、margin:0,也就是绝对定位元素外界为 0,绝对定位元素就会把父盒子撑满。
注意:不写出 left 这些方位为 0 的话,外界大小默认不是 0,是 auto,所以要明确指出外界为 0,left: 0 要写出来。
粘性定位 - sticky
场景:导航栏。页面向下滚动,导航栏也向上走,但是碰到页面顶部后就停在顶部,不继续向上走而消失了。
注意:别忘了设置阈值,比如 top: 30px; 就是离顶部 30px 就粘住。
粘性定位相对的阈值是在相对谁?比如 top: 30px,top相对的是谁?
相对的是最近的滚动视口。比如粘性定位的导航盒子在一个父盒子中,父盒子的内容能滚动,那 top 相对的就是这个滚动盒子的视口。
auto到底是什么?
auto -> 意味着交给浏览器你来出来
◼ width 默认就是 auto,不是 100%,属性默认值一般都是 auto。
width: auto 代表什么?
- 行内非替换元素 -> width: 包裹内容,就是内容的宽度
- 块级元素 ->width: 包含这个元素的块的宽度,也就是占满父元素一行。
- 绝对定位元素 -> width: 包裹内容