在页面布局中,定位(Positioning)是一种重要的布局技术,它允许我们精确地控制元素在页面上的位置。定位模式、是否脱标以及移动位置是理解定位的三个关键方面。
1 定位模式
定位模式决定了元素在文档中的定位方式,通过CSS的position
属性来设置。常见的定位模式包括:
-
静态定位(static):
- 是元素的默认定位方式,即元素按照正常的文档流进行布局。
- 不会发生脱标,也不具备通过
top
、right
、bottom
、left
属性进行移动的能力。
-
相对定位(relative):
- 元素首先按照正常文档流进行布局,然后相对于其正常位置进行偏移。
- 发生偏移后,元素仍然占据原来的空间(不脱标)。
- 可以通过
top
、right
、bottom
、left
属性进行移动。
-
绝对定位(absolute):
- 元素脱离正常文档流,相对于其最近的已定位(即非static定位)祖先元素进行定位。
- 如果没有这样的祖先元素,则相对于初始包含块(通常是视口)进行定位。
- 发生脱标,不再占据原来的空间。
- 同样可以通过
top
、right
、bottom
、left
属性进行移动。
-
固定定位(fixed):
- 元素脱离正常文档流,相对于浏览器窗口进行定位。
- 即使页面滚动,元素也会停留在固定的位置。
- 发生脱标,不再占据原来的空间。
- 使用
top
、right
、bottom
、left
属性进行定位。
是否脱标
- 不脱标:静态定位(static)和相对定位(relative)的元素不会脱离正常文档流,它们仍然占据原来的空间。
- 脱标:绝对定位(absolute)和固定定位(fixed)的元素会脱离正常文档流,不再占据原来的空间。
移动位置
- 对于不脱标的元素(static和relative),移动位置实际上是通过改变其在文档流中的相对位置来实现的,比如通过改变其
margin
或padding
值。 - 对于脱标的元素(absolute和fixed),则是通过
position
属性的top
、right
、bottom
、left
属性来直接指定其在页面上的绝对位置或相对于某个已定位祖先元素的位置。
表格展示
定位模式 | 是否脱标 | 移动位置方式 |
---|---|---|
静态定位(static) | 否 | 遵循正常文档流 |
相对定位(relative) | 否 | 相对于自身原始位置偏移(使用top 、right 、bottom 、left ) |
绝对定位(absolute) | 是 | 相对于最近的已定位祖先元素偏移(或相对于初始包含块),使用top 、right 、bottom 、left |
固定定位(fixed) | 是 | 相对于浏览器窗口定位,使用top 、right 、bottom 、left |
2 定位的组成
在CSS中,定位(Positioning)确实是一种将盒子(即HTML元素)放置在页面上的特定位置的技术,同时也是一种按照定位方式移动这些盒子的方法。
- 定位模式用于指定一个元素在文档中的定位方式。
- 边偏移则决定了该元素的最终位置。
CSS中定位模式(position
属性)的各个值及其语义展示:
值 | 语义 |
---|---|
static | 元素的默认定位方式。元素按照正常的文档流进行布局,不会被特别定位。top 、right 、bottom 、left 和 z-index 属性不会对其产生影响。 |
relative | 元素首先按照正常文档流进行布局,然后相对于其正常位置进行偏移。偏移量由top 、right 、bottom 、left 属性确定。元素仍然占据文档流中的空间。 |
absolute | 元素脱离文档流,相对于其最近的已定位(即position 不是static )祖先元素进行定位。如果没有这样的祖先元素,则相对于初始包含块(通常是视口)进行定位。偏移量由top 、right 、bottom 、left 属性确定。 |
fixed | 元素脱离文档流,相对于浏览器窗口(视口)进行定位。即使页面滚动,元素也会保持在固定的位置。偏移量由top 、right 、bottom 、left 属性确定。 |
sticky | 根据用户的滚动位置,元素在relative 和fixed 定位之间切换。它通常用于创建粘性头部或侧边栏等效果。元素首先按照正常文档流进行布局,然后当页面滚动到特定位置时,它会相对于其最近的滚动祖先(如果指定了)或视口进行定位,并保持在固定位置,直到页面滚动回原始位置。偏移量由top 、right 、bottom 、left 属性之一(取决于具体的布局需求)确定。 |
CSS定位中的边偏移属性及其简要说明:
边偏移属性 | 描述 |
---|---|
top | 定义元素的上外边距边界与其包含块上边界之间的偏移。对于absolute 和fixed 定位的元素,它指定了元素的上边缘与其定位上下文的上边缘之间的距离。对于relative 定位的元素,它指定了元素的上边缘相对于其正常位置的上移距离。 |
right | 定义元素的右外边距边界与其包含块右边界之间的偏移。其工作方式类似于top 属性,但方向是向右。 |
bottom | 定义元素的下外边距边界与其包含块下边界之间的偏移。对于absolute 和fixed 定位的元素,它指定了元素的下边缘与其定位上下文的下边缘之间的距离。对于relative 定位的元素,它指定了元素的下边缘相对于其正常位置的下移距离。 |
left | 定义元素的左外边距边界与其包含块左边界之间的偏移。其工作方式类似于top 属性,但方向是向左。 |
注意:
- 当使用
static
定位时,这些边偏移属性不会生效,因为static
定位的元素是按照正常的文档流进行布局的。 - 对于
absolute
和fixed
定位的元素,这些边偏移属性是相对于其定位上下文(通常是最近的已定位祖先元素或视口)进行计算的。 - 对于
relative
定位的元素,这些边偏移属性是相对于元素自身在文档流中的正常位置进行计算的。
对于absolute
和fixed
定位的元素,它们的边偏移属性(top
、right
、bottom
、left
)不是相对于static
定位的元素来计算的。static
定位是元素的默认定位方式,它表示元素会按照正常的文档流进行布局,不会被特别定位,因此它不能作为absolute
或fixed
定位元素的定位上下文。
-
对于
absolute
定位的元素,它的定位上下文是最近的已定位(即position
属性不是static
)祖先元素。如果没有这样的祖先元素,那么定位上下文就是初始包含块(通常是视口,即浏览器窗口的视图区域)。 -
对于
fixed
定位的元素,它的定位上下文始终是视口(viewport),即浏览器窗口的视图区域。这意味着fixed
定位的元素会相对于浏览器窗口进行定位,即使页面滚动,它也会保持在固定的位置。
3 相对定位
相对定位(relative
)是CSS中的一种定位方式,它允许元素首先按照正常文档流进行布局,然后相对于其正常位置进行偏移。这意味着元素仍然占据文档流中的空间,但它可以通过top
、right
、bottom
、left
属性来调整其最终位置。
- 保持原有位置:在文档流中,元素原本占据的空间不会被其他元素占据,即使它被移动了。
- 偏移:通过
top
、right
、bottom
、left
属性,元素可以相对于其原始位置进行偏移。 - 不影响其他元素:除了元素本身的位置会改变外,其他元素的布局不会受到影响。
相对定位(relative
)的元素确实是相对于自己原来的位置来移动的。在移动时,它的参照点(或者说基准点)就是它原本在文档流中的位置。这种移动不会改变元素在文档流中的占据空间,也就是说,它原本在标准流中的位置会继续被保留,并且后续的盒子(元素)仍然会以标准流的方式对待它,就像它没有被移动过一样。
相对定位的一个非常典型的应用就是作为绝对定位(absolute
)元素的定位上下文(即父元素)。当绝对定位元素没有设置position
属性为非static
的父元素时,它会相对于初始包含块(通常是视口)进行定位。 但是,如果我们想要让绝对定位元素相对于页面上的某个特定元素进行定位,就可以将该特定元素设置为相对定位。
假设我们有一个简单的HTML结构,如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>相对定位</title>
<style>
.box1 {
position: relative;
top: 100px;
left: 100px;
width: 200px;
height: 200px;
background-color: pink;
}
.box2 {
width: 200px;
height: 200px;
background-color: deeppink;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
</html>
4 绝对定位
绝对定位(absolute
)的元素在移动位置时,是相对于其最近的已定位(即position
属性不是static
)祖先元素来说的。这里所说的“已定位”祖先元素,指的是在文档树中向上查找时,遇到的第一个position
属性被设置为relative
、absolute
、fixed
或sticky
的元素。如果没有这样的祖先元素,那么绝对定位的元素将相对于初始包含块(initial containing block)进行定位,这通常是视口(viewport)或HTML文档的根元素(<html>
元素)。
因此,我们可以说绝对定位是一种“拼爹型”的定位方式,因为它依赖于其祖先元素的定位状态来确定自己的位置。
此外,还需要注意的是,绝对定位的元素会脱离文档流,也就是说,它们不再占据原本在文档流中的空间。这可能会导致文档流中的其他元素重新排列以填补空白。因此,在使用绝对定位时,需要仔细考虑其对文档布局的影响。
无父亲或者父亲无定位
父级有定位
5 子绝父相的由来
“子绝父相”这句话是CSS布局中一个非常重要的口诀,它简洁地概括了在使用绝对定位(absolute
)时的一种常见做法:当子元素需要采用绝对定位时,其父元素(或更准确的说是定位上下文)应该设置为相对定位(relative
)。
这种做法之所以重要且常用,原因有以下几点:
-
控制定位基准:通过将父元素设置为相对定位,我们可以确保子元素的绝对定位是相对于这个父元素进行的,而不是相对于初始包含块(如视口)。这使得我们能够更精确地控制子元素的位置,特别是在复杂的页面布局中。
-
避免布局混乱:如果父元素没有设置为相对定位(或其他非
static
定位),子元素的绝对定位可能会相对于视口或其他更远的祖先元素进行,这可能导致布局上的混乱和难以预测的结果。通过将父元素设置为相对定位,我们可以确保子元素的定位是可控和可预测的。 -
保持文档流:虽然绝对定位的元素会脱离文档流,但它们仍然会相对于某个已定位的祖先元素进行布局。这个祖先元素(即父元素)本身在文档流中的位置是保留的,这有助于保持页面布局的整体结构和可读性。
-
灵活性:通过将父元素设置为相对定位,我们可以更灵活地调整子元素的位置,而不需要改变HTML结构或添加额外的元素作为定位上下文。这简化了布局过程,并使得代码更加清晰和易于维护。
这就是“子绝父相”的由来:子元素使用绝对定位以实现精确的位置控制,而父元素则使用相对定位以限制子元素的移动范围并保留在文档流中的位置。
6 固定定位
固定定位(Fixed Positioning)是CSS中一种非常有用的定位方式,它允许你将元素固定在浏览器视窗(viewport)的某个特定位置,无论页面如何滚动,该元素的位置都保持不变。这种定位方式在多种场景下都非常有用,特别是在创建导航栏、返回顶部按钮、侧边栏菜单、浮动广告等元素时。
主要特点
- 固定于视窗:元素的位置是相对于浏览器窗口来定位的,而不是相对于其正常流中的父元素。
- 不随页面滚动:即使用户滚动页面,元素也会保持在视窗中的固定位置。
- 脱离文档流:和绝对定位一样,固定定位的元素会脱离文档流,不会占据原本的空间,这可能会影响到页面布局。
使用场景
- 导航栏:固定在页面顶部或底部的导航栏,方便用户随时访问各个页面或部分。
- 侧边栏:固定在页面左侧或右侧的侧边栏,用于显示导航菜单、用户信息或其他辅助功能。
- 返回顶部按钮:固定在页面右下角的按钮,方便用户快速回到页面顶部。
- 浮动广告:固定在页面某个角落的广告,以吸引用户的注意力。
- 聊天窗口:固定在页面底部的聊天窗口,用于实时通讯。
CSS 示例
.fixed-element {
position: fixed;
bottom: 20px; /* 距离浏览器窗口底部的距离 */
right: 20px; /* 距离浏览器窗口右侧的距离 */
width: 200px; /* 元素的宽度 */
height: 100px; /* 元素的高度 */
background-color: #f0f0f0; /* 背景颜色 */
}
注意事项
- 页面布局:由于固定定位的元素会脱离文档流,可能会影响到页面的整体布局,特别是在移动端或小屏幕设备上。
- 覆盖内容:固定定位的元素可能会覆盖页面上的其他内容,特别是当元素较大或位置设置不当时。
- 浏览器兼容性:大多数现代浏览器都支持固定定位,但在一些老旧的浏览器中可能存在兼容性问题。
- 可访问性:确保固定定位的元素不会妨碍到页面的主要内容,特别是对于那些使用屏幕阅读器等辅助技术的用户。
固定定位小技巧: 固定在版心右侧位置
一种非常聪明且简洁的方法,用于将固定定位的元素固定在版心(内容区域)的右侧。这种方法基于CSS的position: fixed;
属性,结合left
和margin-left
属性来实现。下面是如何实现这个效果的详细步骤:
- 版心宽度是已知的,比如
1200px
。
.fixed {
position: fixed;
/* 1. 走浏览器宽度的一半 */
left: 50%;
/* 2. 利用margin 走版心盒子宽度的一半距离 */
margin-left: 605px;
width: 50px;
height: 150px;
background-color: skyblue;
}
尺寸(高度和宽度)的处理方式
在CSS中,当元素被设置为绝对定位(position: absolute;)或固定定位(position: fixed;)时,它们会脱离正常的文档流,并且其尺寸(高度和宽度)的处理方式会发生变化,不再严格受限于它们原本是行内元素还是块级元素。
行内元素
对于行内元素(默认情况下,如<span>、<a>
等),它们通常不会占据整行,并且不能设置宽度和高度(因为它们的尺寸是基于内容的)。但是,当这些元素被设置为绝对定位或固定定位时,它们的行为会发生变化:
- 可以设置宽度和高度:一旦行内元素被设置为绝对定位或固定定位,就可以像块级元素一样直接设置其width和height属性。
- 不再遵循行内元素的默认布局规则:行内元素不再只占据内容所需的宽度,而是可以根据设置的width和height属性占据更多的空间。
块级元素
对于块级元素(默认情况下,如<div>、<p>
等),它们通常会占据整行,并且可以设置宽度和高度(尽管在某些情况下,如宽度设置为auto时,宽度会基于父元素的宽度自动调整)。当块级元素被设置为绝对定位或固定定位时:
- 仍然可以设置宽度和高度:块级元素在设置为绝对定位或固定定位后,仍然可以像之前一样设置width和height属性。
- 默认大小是内容的大小:如果块级元素在设置为绝对定位或固定定位后没有显式设置width和height属性,那么它们的默认大小将基于其内容的大小。这与它们在正常文档流中的行为相似,但关键的区别在于它们现在脱离了文档流,并且可以通过top、right、bottom、left属性来精确控制其位置。
总结来说,无论是行内元素还是块级元素,在设置为绝对定位或固定定位后,都可以直接设置其高度和宽度,而不再受限于它们原本的默认布局行为。然而,如果没有显式设置这些属性,块级元素的默认大小将基于其内容,而行内元素(在设置为定位后)则可以通过设置width和height来占据更多的空间。
7 定位叠放次序 z-index
z-index
是 CSS 中的一个属性,用于控制元素在页面上的堆叠顺序。当一个页面上的多个元素重叠时,z-index
属性决定了哪个元素应该位于顶部,哪个元素应该位于底部。
基本用法
z-index
只能应用于定位元素(即那些其position
属性被设置为relative
、absolute
、fixed
或sticky
的元素)。z-index
的值可以是正整数、负整数或0
。值越大,元素在堆叠顺序中越靠前(即越在上面)。- 默认情况下,元素的堆叠顺序是它们在文档流中出现的顺序,但设置了
z-index
后,这个顺序可以被改变。
示例
假设有两个绝对定位的元素,我们希望让其中一个元素位于另一个元素的上方:
<div class="box1">Box 1</div>
<div class="box2">Box 2</div>
<style>
.box1, .box2 {
position: absolute;
width: 100px;
height: 100px;
top: 50px;
left: 50px;
}
.box1 {
background-color: red;
z-index: 1; /* 堆叠顺序较低 */
}
.box2 {
background-color: blue;
left: 70px; /* 稍微向右移动以显示重叠效果 */
z-index: 2; /* 堆叠顺序较高,因此会覆盖在 box1 上 */
}
</style>
在这个例子中,.box2
有一个更高的 z-index
值(2
),因此它会显示在 .box1
(z-index
值为 1
)的上方。
注意事项
- 默认情况下,非定位元素(即
position
属性为static
的元素)的z-index
值为auto
,且这些元素不会创建新的堆叠上下文。这些元素的堆叠顺序由它们在文档流中出现的顺序决定。