三分钟搞懂CSS定位
聊一聊CSS定位
CSS定位是CSS中比较基础的一部分,前端必须要掌握。本文重点是position的属性和sticky。
CSS定位即允许元素可以出现在相对正常位置外的其它位置,实现对元素位置控制的效果。
CSS定位基本分为三种定位:普通文档流、浮动和绝对定位。
普通文档流
普通文档流即按照HTML的定义顺序完成排布,块级元素就从上往下排列,行内元素就从左到右依次排序。
浮动
浮动即给元素设置float属性,设置float的属性会脱离文档流,则该元素不会占用文档流中的空间,其它在文档流中的元素排布就会无视该元素,脱离文档流的元素也不能撑起父元素的高度。
但float脱离文档流又不太完全,附近元素附件元素内的文本还是会为浮动元素让出位置,例:
普通文档流中有两个块级元素,块1
和块2
,我们设置块1
为浮动元素:
结果发现块1
脱离文档流,导致块1
和块2
合并到一起,但块2
的文字部分还是为块1
让出了位置,围绕在块1
周边
定位position
本文重点介绍position属性,该属性用来指定一个元素的位置,该属性主要取值为:
- static
- relative
- absolute
- fixed
- sticky
static
static是position默认值,即表示元素是使用普通的文档流进行排布
relative
relative表示相对定位,该属性与absolute和fixed使用上有相似之处,都是相对某个基点定位,所以我们搞清楚这三个属性对应的基点会很容易区分。
relative相对布局的对象是在普通文档流中(即position: static)中的位置进行偏移,即基点是元素的默认位置,并配合left、top、right、bottom属性进行位置设置。
relative布局的元素并未脱离文档流,其它普通流元素在排布时会当它是普通元素,且会认为它还在原来的位置上。
absolute
absolute表示绝对定位,相对于父元素进行定位,即基点为父元素。
且absolute的基点不能是static定位元素,否则基点就会变成网页根元素html。
定义absolute属性的元素会在文档流中完全删除。
看一下示例:
例子中容器container包含三个块,将块2
设置为absolute定位的元素后,可以看到块2
并没有相对父元素container作为基点,而是使用根作为了基点,就是因为父元素container的position属性为默认static。
那么我们给父元素设置一下position属性:
可以看到块2
选择父元素container作为基点进行定位。
fixed
fixed属性表示元素相对视窗定位,即基点为视窗,且fixed属性设置的元素也会脱离文档流。
fixed属性设置的元素不会随着页面滚动条的滚动而变化,像是被固定在窗口上,我们经常见到返回顶部按钮等都是使用fixed定位的。
fixed的使用方法与absolute和relative相同,都是通过left、right、top、bottom进行定位。
sticky
sticky属性是粘性定位,是一个很有意思的属性,该属性定义的元素的基点会发生变化,粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。
看一个简单的例子:
例子中外层容器container为一个固定宽高的滚动块级元素,其中包含了三个子元素块,块1
、块2
和块3
(绿色块被覆盖)。其中只有块2
是sticky定位的元素,并且top为0:
.block2{
position: sticky;
top: 0;
}
可以看到当滚动条在最上面时,块2
就是按照普通流的排布方式进行排布,此时块2
的基点为本身位置。当父级元素container滚动条拉到最下时,可以看到块2
并没有被拉到不可见区域,且块2
覆盖了块3
,此时块2
的基点变成了父级元素container。
sticky属性生效的规则是必须配置位置偏移,即配置left、right、top、bottom四个阈值其中之一才可以生效,否则等同于relative。
具体规则是:
在祖先的滚动元素未滚动到阈值之前,sticky属性元素根据正常文档流进行定位,并且left、right、top、bottom四个属性实际是未生效的,此时基点就是当前元素在文档流中的位置,与relative基点一样。
当滚动的祖先元素滚动到sticky元素设置的阈值之后,sticky变成类似固定定位,且基点变成了滚动祖先元素的位置,就出现了该元素会固定在祖先元素上的现象。并且无论基点是什么都不会影响其它元素的位置,即sticky元素并未脱离文档流
。
一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow 是 hidden, scroll, auto, 或 overlay时),即便这个祖先不是最近的真实可滚动祖先。也就是说sticky元素生效的条件是:最近的可以滚动的祖先元素
,滚动到元素设置的阈值(由left、right、top、bottom四个阈值至少一个组成),才能触发效果。
从这里也就提到了网上经常提到关于sticky的问题,为什么设置的sticky元素未生效,我们看一个例子:
(还是之前那几个块,丑是丑了点,胜在简单)
还是之前那个container容器,其中块2
是sticky布局的元素,当container元素的滚动条向下拉打到块2
设置的阈值(top: 0)时,块2
会固定在元素container上。
但当我们将窗口高度缩小,滑动窗口的滚动条试图满足块2
的阈值时:
发现块2
并没有像fixed布局一样固定在视窗上,那就是因为sticky元素的基点是距离最近的滚动元素,在例子中就是块2
的父元素container,即使父元素没有实际的滚动高度,基点也是container,这样就出现了"不生效"的情况。
所以sticky的元素不一定会固定在视窗上,如果想要实现类似fixed一样固定在视窗上的效果,那么最简单就是需要sticky元素的最近滚动祖先元素是根节点,即设置所有sticky的祖先元素都是不可滚动元素。
总结
- float
脱离文档流,但附近元素附件元素内的文本还是会为浮动元素让出位置 - position: relative
不脱离文档流,基点为元素是在普通文档流中(即position: static)中的位置 - position: fixed
脱离文档流,基点为视窗 - position: absolute
脱离文档流,基点为不为static定位的父元素。 - position: sticky
不脱离文档流,在滚动的祖先元素未达到元素定义的阈值时基点为元素在文档流中的位置。当滚动的祖先元素滚动达到元素定义的阈值时,基点为最近的滚动祖先元素。
本文地址:https://blog.csdn.net/xcg132566/article/details/107374688
上一篇: c语言-switch