一、静态流与position
CSS中的position属性用于将元素从普通的文档流中脱离出来,使其可以通过top、right、bottom和left属性来定位。在理解position之前,我们需要了解什么是静态流。
本质上,文档中的每个元素都可以看做是由块级元素和行内元素构成的。当一个元素在文档中被放置时,它会按照特定的规则沿着文档流流动。这个规则被称为“静态流”,也叫“普通流”或“自然流”。
普通流的主要特点是元素会一个接一个地放置,每个元素占据一行或一行的一部分。块元素会在页面中自动换行,行内元素则会在同一行内放置。
而当一个元素被应用了position: absolute;、position: fixed;、position: relative;或position: sticky;属性时,它就会从普通流中脱离出来,不再跟其他元素遵循普通流的规则排布。
下面是一个简单的示例:
/* HTML */ <div class="container"> <div class="box box-1"></div> <div class="box box-2"></div> </div> /* CSS */ .container { width: 500px; height: 500px; } .box { width: 100px; height: 100px; } .box-1 { background-color: red; } .box-2 { background-color: blue; }
默认情况下,box-1和box-2元素会按照普通流的规则排布在容器中:
/* 等价于position: static; */ .box { position: relative; }
如果我们将box-1元素设置为position: absolute;,则它就会从普通流中脱离出来,不再占据空间。box-2元素会自动顶上去:
.box-1 { position: absolute; }
二、position属性详解
1. position: static;
这是默认值,即元素会按照普通流的规则排布。如果你没有显式设置position属性,则元素的position值为static。
2. position: relative;
元素的位置会相对于它原来应该在的位置进行定位。也就是说,它在文档流中的位置不会改变,不会影响其他元素的位置。
相对定位会创建一个新的定位上下文。这个定位上下文会影响元素内部的绝对定位子元素的位置。后面我们会讲到绝对定位。
下面是一个示例,我们将box-1元素向右移动了20px:
.box-1 { position: relative; left: 20px; }
3. position: absolute;
这种定位方式会使元素脱离出文档流,完全不占据原来的位置,也不会对其他元素造成任何影响。
当一个元素设置为position: absolute;时,它会相对于最近的有定位的祖先元素进行定位(注意是有定位的祖先元素,后面会详细讲到)。如果没有定位的祖先元素,那么它的位置会相对于最初的包含块(即浏览器窗口)进行定位。
下面是一个示例,我们将box-1元素相对于container的左上角定位,并且将其z-index设置为1,使其在box-2元素的上层:
.box-1 { position: absolute; top: 0; left: 0; z-index: 1; }
4. position: fixed;
fixed定位与absolute定位类似,都是相对于最初的包含块(即浏览器窗口)进行定位。不过,它的定位与视窗有关,而不是与文档流有关。
它的特点是无论用户如何滚动页面,元素都会保持相对不动的位置。fixed定位常用来为页面悬浮的导航条、广告条等元素固定在页面上方。
下面是一个示例,我们将box-1元素设置为fixed定位,在视口的右下角定位:
.box-1 { position: fixed; bottom: 0; right: 0; }
5. position: sticky;
粘性定位是一种混合了相对定位和固定定位的定位方式。元素会在跨越特定阈值前为相对定位,然后在接下来的滚动中为固定定位。
它的特点是能够在滚动到特定位置时将元素固定在页面上,不过一旦它们脱离了它们的位置,它们就会重新成为相对定位的元素。
下面是一个示例,我们将box-1元素设置为sticky定位,在滚动到顶部时将其固定在页面上:
.box-1 { position: sticky; top: 0; }
三、定位上下文
所谓“定位上下文”,就是一个对定位元素周围的区域进行定义和管理的区域。
每个元素都会自己创建一个定位上下文。当元素被设置为position: static(默认值)或position: relative时,它们会成为自己的定位上下文。而当元素被设置为position: absolute、position: fixed或position: sticky时,它们会相对于最近的有定位的祖先元素进行定位。
下面我们来看一个示例,box-1元素被设置为relative定位,同时它的子元素box-1-1元素被设置为absolute定位。因为box-1-1元素是box-1元素的子元素,所以它的“最近的有定位的祖先元素”就是box-1元素。
/* HTML */ <div class="container"> <div class="box box-1"> <div class="box box-1-1"></div> </div> </div> /* CSS */ .box-1 { position: relative; } .box-1-1 { position: absolute; top: 0; }
我们发现,box-1-1元素的位置是相对于box-1元素定位的,而不是相对于container定位的。
四、小结
通过本文的介绍可以看出,position属性是CSS中非常有用也十分灵活的属性,它可以让我们实现各种有趣的效果。对于不同的定位方式,我们需要理解它们的定位特点;而对于定位上下文,我们需要了解有关祖先元素的概念。