CSS定位
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
保持位置!没问题吧?现在,我们来谈谈CSS定位。
帮助开发者设计网页项目布局的要素之一是定位,即元素在页面上的位置以及它们周围元素的走向。
CSS定位相当复杂,可能需要一段时间才能理解(就像我一样)。本文旨在用通俗易懂的方式解释它。我们会编写代码(这一点毋庸置疑),浏览器和开发者工具中的最终图像应该能帮助你更好地理解定位的整个概念。
CSS 中的定位包括:
- 静态定位
- 相对位置
- 绝对定位
- 固定定位
- 粘性定位
从上面的列表中你应该知道,相对定位和绝对定位是最常用的定位技术,当你在互联网上找到一篇讨论 CSS 定位的文章或博客文章时,它们大多会讨论这两种定位方式。
在继续之前,我想提一下,CSSposition属性用于设置元素在文档中的位置。
以下 HTML 和 CSS 代码将用于演示本文中的定位技术,请复制并保存为 .html.html和 .css.css扩展名,并确保 CSS 已链接到 HTML。
<div class="parent">
<div class="child"></div>
</div>
/* To be the best of my knowledge, i believe we've discussed
* all the properties in the CSS rules. The only property that
* you may find foreign is the background-color and the color
* format rgb(), we'll talk about them in the series, i think under
* CSS Colors.
*/
.parent {
margin-top: 32px;
margin-right: auto;
margin-left: auto;
margin-bottom: 32px;
background-color: rgb(200,200,200);
width: 500px;
height: 200px;
}
.child {
margin-top: 30px;
margin-right: 20px;
margin-bottom: 50px;
margin-left: 20px;
width: 100px;
height: 100px;
background-color: red;
}
静态定位
这是大多数元素的默认位置,它们不受偏移属性(如top、、right或bottom)的影响left。
在浏览器中加载您的 HTML,对红色框使用“检查元素”并导航到盒模型(我相信您现在应该能够做到这一点)。
你应该会得到类似下图的输出结果,我已经高亮显示了盒子的位置状态。
相对位置
在我们深入探讨CSS 中的相对定位之前,我们需要了解术语“相对”的含义。
根据Lexico 词典的解释,当我们使用“相对的”这个词时,它的意思是:
相对于其他事物而言,或者与另一事物成比例而言。
这个定义意义重大,它很好地诠释了CSS 中相对定位的工作原理。
相对定位是指将页面元素相对于其父元素进行定位的能力。这个定义可能比较基础,让我们来看看Mozilla 开发者网络对此有何解释(重点为笔者所加):
position相对定位元素是指计算值*为 的元素relative。`v_vertical_offset`top和 `v_horizobottomntal_offset` 属性指定相对于其正常位置的垂直偏移量; `v_horizontal_offset`left和 `v_horizo ntal_offset`right属性指定相对于其正常位置的水平偏移量。
这意味着:当您使用相对定位来定位元素时,元素将根据所使用的属性,从其正常位置垂直或水平移动。
请将 CSS 规则更新.child为以下内容:
.child {
/* Other properties remain the same */
left: 1.2em;
}
现在,该框会稍微向屏幕右侧移动,如果您查看盒模型,您会注意到浏览器添加了一些详细信息,表明您已经定位了该元素。
现在我们把这个框稍微向下移动一点,这可以通过使用属性来实现。在CSS 规则中,紧挨着该属性下方top添加以下代码:.childleft
.child {
/* Other properties remain the same */
top: 1.2em;
}
保存并刷新浏览器。导航至盒模型,然后单击上图中“ relative ”字样旁边的图标,这将显示元素在其新位置使用的xtop和 y值。left
现在我们把盒子移动到容器顶部。这可以通过bottom属性实现,我们可以添加 `overflow: top`right或 ` leftoverflow: top` 来表示它移动了。删除 `overflow: top`left和`overflow: top`top的值,然后添加以下内容:
.child {
/* Other properties remain the same */
right: 1.6em;
bottom: 1.4em;
}
刷新浏览器,然后点击盒子模型中“相对”旁边的图标,即可显示盒子的坐标。
请注意,如果您使用两个属性将元素沿一个方向(水平或垂直)移动,则只会应用其中一个值。
例如,如果您同时使用 `move`left和 ` rightmove` 属性移动元素,则只有 `move`left属性会生效。要查看实际效果,请删除rightbottom规则中的`move`和 `.child move` 属性,然后添加以下内容:
.child {
/* Other properties remain the same */
left: 2.5em;
right: 120.6em;
}
保存文件并刷新浏览器,您会发现只有left属性被应用,盒子会朝着正确的方向移动。
您可以通过点击盒模型中“相对”一词旁边的图标来确认这一点。
但是,浏览器会在盒模型right中显示您的属性值。
同样,如果您移动一个元素并设置了top`and`bottom属性值,则只有 ` topproperty` 属性会生效。如果您的 CSS 中同时声明了left`and`属性,请(暂时)删除它们,并将规则更新为以下内容:right.child
.child {
/* Other properties remain the same */
top: 1.2em;
bottom: 2.4em;
}
保存文件并刷新浏览器,你会发现方框稍微从顶部移动了一点。你可以点击方框模型中“相对”字样旁边的图标来确认这一点。
这告诉我们,为了有效地移动页面元素,我们应该结合垂直—水平方向移动元素的属性(top,bottom与right或left),而不是垂直—垂直(top,bottom)或水平—水平(left,right)。
在继续之前,我们应该先谈谈Mozilla 开发者网络 (Mozilla Developer Network) 中相对定位定义里引入的偏移量 (offset)。我之前已经解释过它,但考虑到它可能会让前面的演示和示例显得有些复杂,所以现在我们可以讨论一下,因为它在解释其他定位技术时会非常有用。
看看下图中的Box 模型position,你会注意到在Box模型属性中,它显示offset(蓝色背景)body,如果你将鼠标悬停在上,offset它会显示“所选元素的父元素偏移量”,在本例中,它是body元素。
将鼠标悬停在该body元素上,它将在网页上高亮显示。
这意味着该元素是相对于其父body元素而不是相对于其实际父元素(即div具有该类的元素)进行定位的.parent。
为什么?这是因为大多数元素都有默认的定位static,而偏移属性(例如top)right对已定位的元素无效static,如果您仔细观察,会发现我们的div元素的位置是固定的static。
所以,当我们对 `<div>` 元素执行相对定位时.child,浏览器会判断出该div元素具有静态定位,并默认使用 `<div> body` 元素。但是,如果文档中没有 `<div>` 元素会发生什么呢body?浏览器会添加 `<div>` 和 `<span>`body标签,定位仍然会默认使用添加的body元素。
body您可以通过在 HTML 代码中注释掉开始标签和结束标签来验证这一点。
我们可以通过确保元素.parent使用相对定位来解决整个问题。将以下代码添加到.parent类中:
.parent {
/* Other properties remain the same */
position: relative;
}
保存文件并刷新浏览器,您将在“盒模型属性”下看到更改。
现在有趣的部分来了,删除topbottomCSS 规则中的` and`属性.child,然后添加以下内容:
.child {
/* Other properties remain the same */
right: 5em;
}
保存并刷新浏览器后,你会发现该框将移出其父容器(div元素)。
如果您对这种效果满意,那就没问题。但如果您希望该框始终位于其父容器内,请将以下内容添加到…….parent
.parent{
/* Other properties remain the same */
overflow: auto;
}
帮助overflow控制子元素超出其父元素边界时会发生什么,在本例中我们将其设置为auto,它接受其他值,如scroll,visible和hidden。
保存文件并刷新浏览器,对红色方框使用“检查元素”功能,查看盒模型。点击“ relative ”字样旁边的图标,您应该会看到类似下图的输出结果。
现在,该框已包含在其父元素中。overflow当您希望子元素紧贴其父容器时,此功能非常有用。您将在讲解CSS 块格式上下文以及最终项目中看到它的实际应用。
相对定位就讲到这里,接下来我们学习绝对定位。
绝对定位
来自Mozilla 开发者网络(重点为笔者所加):
position绝对定位元素是指其计算值为absolute`false` 或 `false`的元素fixed。`$overflow: offset`top、`$rightoverflowbottom: offset` 和 `$overflow:leftoffset` 属性指定元素相对于其包含块边缘的偏移量。(包含块是指元素相对于其定位的祖先元素。)如果元素有边距,则边距会添加到偏移量中。
上面加粗的句子告诉我们,我们可以将元素精确地放置在其包含块中的任何位置。包含块可以是元素的父元素,也可以是网页本身。什么意思?
关键在于,绝对定位是相对于第一个相对定位或绝对定位的父元素进行的;如果父元素不是相对定位的,那么它将直接相对于页面本身进行定位。
现在的问题是:我们如何相对定位父元素?
你已经知道答案了!只需position: relative在父级 CSS 规则中添加即可。让我们开始编写代码吧。
我们将继续使用之前讲解中使用的 CSS 和 HTML 代码,但你需要进行一些清理和修改。请确保你的 CSS 和 HTML 代码与下面的代码片段一致。
<div class="parent">
<div class="child"></div>
</div>
.parent {
margin-top: 32px;
margin-right: auto;
margin-left: auto;
margin-bottom: 32px;
background-color: rgb(200,200,200);
width: 500px;
height: 400px;
position: relative; /* Note this */
}
.child {
width: 120px;
height: 120px;
background-color: #1560bd;
}
保存文件,并查看父元素的盒模型,即可确认其具有相对位置。
将以下内容添加到 CSS 规则中.child:
.child {
/* all other properties remain the same */
position: absolute; /* for absolute positioning */
}
保存文件并确认其在盒模型中具有绝对位置:
现在我们来修改一些内容。请将 CSS 规则更新.child如下:
.child {
/* all other properties remain the same */
top: 5em;
left: 15em;
}
这将使蓝色方框移动到其父元素的中心位置。
保存文件并刷新浏览器。查看盒模型,然后单击“绝对”字样旁边的图标,即可显示盒子的位置。
让我们把这个框移到另一个位置,从CSS 规则中删除 ` topand`left属性.child,然后添加以下内容:
.child {
/* all other properties remain the same */
bottom: 3em;
left: 2em;
}
保存并刷新浏览器,然后查看盒子的位置。
现在给你们布置一些练习。
使用偏移属性(left,,,)的组合,编写属性声明right,将盒子移动到下图所示的位置。bottomtop
练习1
练习2
练习3
你找到答案了吗?请在评论区分享你的答案。
固定位置
这种定位技术的名称就足以说明它的功能。它允许你将一个元素定位到网页上的固定位置。
它类似于绝对定位,区别在于元素的包含块是由视口 建立的初始包含块*。
这意味着,当你将元素的位置设置为固定值时fixed,其父容器是当前可用的浏览器窗口。你可能会问,为什么不是它的父元素呢?这就是固定定位的工作原理。让我们通过代码来了解一下。
要了解这种定位方式的实际效果,最好的方法之一是在一个父容器中放入足够的内容,以便我们可以滚动,我们会注意到固定元素不会随着父容器中的其他内容一起移动。
整理一下你的 HTML 和 CSS 文件,让它们与下面的代码保持一致,别忘了保存你的文件。
<div class="parent">
<div class="child"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
.parent {
width: 500px;
height: 400px;
margin: 2em auto;
background-color: #dddddd;
}
.child {
width: 100px;
height: 100px;
background-color: #1560bd;
}
刷新浏览器。输出结果应该与下图类似。
接下来,我们需要创建一个环境,允许我们滚动父元素的内容,我们可以使用overflow属性来实现这一点(我们在相对定位中讨论过overflow)。
该overflow属性接受诸如auto`<value>` hidden、scroll`<value>`、`<value> ` 之类的值visible。我们将使用的值是 `<value>` scroll。将以下内容添加到您的.parentCSS 规则中:
.parent {
/* All other properties remain the same */
overflow: scroll;
}
保存并刷新。您会注意到父容器中已添加了滚动条。
如果滚动页面,包括方框在内的所有内容都会移动。我们来改变这一点。将以下代码添加到.childCSS 规则中并保存文件。
.child {
/* All other properties remain the same */
position: fixed;
}
你会注意到有些文字现在位于蓝色方框后面,如果你滚动父元素,方框不会移动。
现在让我们给盒子留出一些空间。记住,它是 `<div>` 的子元素.parent,我们可以通过在 `<div>` 内部创建一个内部间距.parent来获得这个空间。你能猜到这个内部间距是什么吗?它就是内边距 (Padding )。
我们可以在父元素内部的任何位置创建内部间距。这里我们将在左侧创建这个间距。你应该能体会到我们需要使用的属性。该padding-left属性的值将使框拥有一定的空间,而不会干扰文本。
将以下内容添加到您的.parent类中并保存文件。
.parent {
/* All other properties remain the same */
padding-left: 150px;
}
浏览器中显示的图像:
现在,我们需要移动箱子。请将以下内容添加到…….child
.child {
/* All other properties remain the same */
top: 80px;
left: 10px;
}
保存。刷新浏览器,搞定!
刚才发生了什么?请记住:
当您将元素的位置设置为父容器时,
fixed父容器是浏览器窗口。
当你定位盒子时,就会发生这种情况,它的父对象现在是浏览器窗口或视口。
由于盒子当前的位置,我们之前为盒子创建的内部空间仍然为空。为了让盒子占据这部分空间,我们需要通过移除其margin属性,将父元素移动到浏览器边缘。
margin: 2em auto;从 <div> 中删除<div> .parent。保存并刷新浏览器。父元素将移动到屏幕左侧,蓝色方框将占据我们之前创建的空间。
当你滚动页面时,这个框不会移动,看起来好像是相对于页面边缘的.parent。但实际上,它是相对于浏览器窗口的。为了证明这一点,我们给这个html元素添加边框,并编写相应的.parentCSS 规则。你的 CSS 代码结构应该类似于下面的代码片段。
html {
border: 3px solid gold; /* add this */
padding: 1.2em; /* add this */
}
.parent {
/* all prperties remain the same*/
border: 5px solid #ea3c53; /* add this */
}
.child {
/* properties remain unchanged */
}
保存并刷新浏览器,查看盒模型,然后点击“固定”字样旁边的图标,您会在浏览器窗口中注意到盒子位置的坐标与窗口边缘相接,这是元素本身html,而不是其他元素。.parent
如果你想体验一下,可以对 ` .parentand`元素执行相对定位,然后保存文件。之后,按照常规步骤在盒模型.child中查看盒子的坐标,你会发现坐标线现在与 `and` 元素相交,而不是与 ` element` 元素相交。.parenthtml
粘性定位
黏黏的,黏黏的,黏黏的。我想光听名字就足以说明这种定位技巧的本质了。还需要解释吗?……好吧,那就解释一下。
Mozilla开发者网络解释道(重点为笔者所加):
粘性定位可以看作是相对定位和固定定位的混合体。粘性定位的元素在越过指定的阈值之前被视为相对定位,越过阈值后则被视为固定定位,直到到达其父元素的边界。
好了,我觉得这很简单明了,现在开始写代码吧。
我们将使用之前的HTML代码,并稍作修改。
<!-- Add this before <div class="child"></div> -->
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<!-- other content remains unchanged -->
以及新的CSS规则。
.parent {
width: 500px;
height: 400px;
margin: 2em auto;
background-color: #dddddd;
position: relative; /* relatively positioned the element */
}
.child {
width: 100px;
height: 100px;
background-color: #1560bd;
}
保存文件并刷新浏览器。
接下来,我们需要启用滚动功能.parent,以便可以看到应用粘性位置后的效果。
请更新.parent以下内容
.parent {
/* All other properties remains the same */
overflow: scroll; /* to enable scrolling */
}
保存文件并刷新浏览器。这样应该就可以在页面中滚动了.parent。
接下来,我们要制作.child粘性内容。将以下内容添加到您的.child:
.child {
/* All other properties remains the same */
position: sticky; /* make it sticky */
}
保存文件并刷新浏览器。滚动页面时,你会发现方框仍然会移出视野。
为什么会发生这种情况?MDN来帮忙:
您必须指定一个阈值,该阈值至少包含以下一项:
top、、、或,粘性定位才能按预期工作。否则,它将与相对定位无法区分。rightbottomleft
这告诉我们,给一个元素赋予定位属性后,position: sticky;必须指定一个相对定位属性才能offset使其生效,否则它的行为会和相对定位的元素一样。让我们来解决这个问题。
将以下内容添加到您的.childCSS 规则中:
.child {
/* All other properties remains the same */
top: 50px; /* this will move the box down the screen by 50px */
}
保存文件并刷新浏览器。如果您滚动浏览.parent,当滚动到蓝色方框时,它不会完全移出屏幕。它似乎会先从原来的位置弹出,然后固定住。
出于可访问性考虑,请确保使用 `<div>`absolute或 ` fixed<span>` 定位的元素在页面缩放以增大文本大小时不会遮挡其他内容。什么?这以及更多内容将在“Web 可访问性和可用性”一节中讨论。
需要注意的是,使用绝对定位或相对定位时,如果 `<div>` 元素的值不为空,则会创建一个堆叠上下文。但使用固定定位时,始终会创建一个新的堆叠上下文。z-indexauto
这句话可能会引出两个问题。它们是:
- 什么是堆叠上下文?
- 什么是
z-index?
这两个问题将在下一主题中解答。CSS z-index。
文章来源:https://dev.to/ziizium/css-positioning-34d8








