Positioning
先决条件: | HTML基础知识(了解 HTML简介)以及CSS的工作原理(了解 CSS简介 >。) |
---|---|
目的: | 了解CSS定位的工作原理。 |
文档流
定位是一个相当复杂的话题,所以在我们深入了解代码之前,让我们回顾一下布局理论,让我们了解它的工作原理。
首先,通过获取元素的内容,然后在其周围添加任何填充,边框和边框来布置单个元素框 - 这是框模型事 再次,我们前面看过。 默认情况下,块级元素的内容是其父元素的宽度的100%,并且与其内容一样高。 内联元素都是高的,因为它们的内容,以及它们的内容。 您不能对内联元素设置宽度或高度 - 它们只是位于块级元素的内容中。 如果要以这种方式控制内联元素的大小,您需要将其设置为类似于具有 display:block;
的块级元素。
这解释了个别元素,但是元素如何相互交互呢? 正常布局流(在布局介绍文章中提到)是元素放置在浏览器视口内的系统。 默认情况下,块级元素在视口中垂直布局 - 每个都将显示在最后一个下面的新行上,它们将被设置在其上的任何边距分隔。
内联元素的行为不同 - 它们不会出现在新行上; 相反,它们彼此位于相同的行和任何相邻(或包装)的文本内容,只要在父块级元素的宽度内有空间可以这样做。 如果没有空格,那么溢出的文本或元素将向下移动到新行。
如果两个相邻元素都设置了边距,并且两个边距接触,则两个边界中较大的一个保留,较小的一个消失,这被称为 / docs / Web / CSS / CSS_Box_Model / Mastering_margin_collapsing">利润崩溃,我们也遇到了这种情况。
让我们看一个简单的例子来解释这一切:
<h1>Basic document flow</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p>By default we span 100% of the width of our parent element, and our are as tall as our child content. Our total width and height is our content + padding + border width/height.</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; margin: 0 auto; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; }
我们将通过这篇文章重复这个例子多次,因为我们展示了我们可用的不同定位选项的效果。
我们希望您在本地计算机上遵循练习,如果可能,请获取 /positioning/0_basic-flow.html"class ="external"> 0_basic-flow.html
从我们的Github仓库( area / blob / master / css / css-layout / positioning / 0_basic-flow.html"class ="external">这里的源代码),并以此为起点。
介绍定位
定位的整个想法是允许我们覆盖上述的基本文档流行为,以产生有趣的效果。 如果你想稍微改变一个布局中的一些框的位置从他们的默认布局流动位置,给一个有点古怪,苦恼的感觉? 定位是您的工具。 或者,如果你想创建一个UI元素漂浮在页面的其他部分的顶部,和/或总是坐在浏览器窗口内的同一个地方,不管页面滚动多少? 定位使得这种布局工作成为可能。
有许多不同类型的定位,您可以对HTML元素生效。 要在元素上启用特定类型的定位,我们使用 position
属性。
静态定位
静态定位是每个元素获取的默认值 - 它只是意味着"将元素放入它在文档布局流中的正常位置 - 这里没有什么特别的。
为了演示这一点,并为以后的部分设置示例,首先向 / HTML / Element / p"> < p>
:
<p class="positioned"> ... </p>
现在,将以下规则添加到CSS的底部:
.positioned { position: static; background: yellow; }
如果现在保存和刷新,除了第2段的更新的背景颜色,您将看不到任何差异。 这很好 - 正如我们之前所说,静态定位是默认行为!
注意:您现在可以在 -positioning.html"class ="external"> 1_static-positioning.html
( css-layout / positioning / 1_static-positioning.html"class ="external">见源代码)。
相对定位
相对定位是我们将要看的第一个位置类型。 这与静态定位非常相似,除了一旦定位的元素在正常布局流程中占据了位置,则可以修改其最终位置,包括使其与页面上的其他元素重叠。 继续并更新代码中的位置声明:
position: relative;
如果您在此阶段保存并刷新,则结果根本不会发生变化 - 那么如何修改元素的位置呢? 您需要使用 顶部
, / CSS / bottom"> bottom
, 左
,以及 右
属性,我们将在下一节中说明。
介绍顶部,底部,左侧和右侧
top
, > bottom
, 左
和 ="/ zh-CN / docs / Web / CSS / right"> right
与 position
指定要将定位元素移动到的位置。 要尝试这样做,请在CSS中的 .positioned
规则中添加以下声明:
top: 30px; left: 30px;
注意:这些属性的值可以采用逻辑上预期的任何单位(像素,毫米,垃圾邮件,%等) 。
如果你现在保存和refesh,你会得到一个这样的结果:
<h1>Relative positioning</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p class="positioned">By default we span 100% of the width of our parent element, and our are as tall as our child content. Our total width and height is our content + padding + border width/height.</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; margin: 0 auto; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; } .positioned { position: relative; background: yellow; top: 30px; left: 30px; }
酷,是吗? 好吧,所以这可能不是你期待的 - 为什么它移动到底部和右边,如果我们指定顶部和左边? 不合逻辑的,因为它可能初始的声音,这只是相对定位工作的方式 - 你需要考虑一个看不见的力,推动定位的盒子的一侧,移动它的相反方向。 所以例如,如果你指定 top:30px;
,力推动框的顶部,使它向下移动30px。
注意:您可以在此处查看此示例现在的 -positioning.html"class ="external"> 2_relative-positioning.html
( css-layout / positioning / 2_relative-positioning.html"class ="external">见源代码)。
绝对定位
绝对定位带来了非常不同的结果。 让我们尝试改变代码中的位置声明如下:
position: absolute;
如果你现在保存和刷新,你应该看到这样:
<h1>Absolute positioning</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p class="positioned">Now I'm absolutely positioned, I'm not playing by the rules any more!</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; margin: 0 auto; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; } .positioned { position: absolute; background: yellow; top: 30px; left: 30px; }
首先,请注意,定位的元素应该在文档流中的间隙不再存在 - 第一和第三元素已经关闭在一起,就像它不再存在! 好吧,在某种程度上,这是真的。 绝对定位的元素不再存在于正常文档布局流程中。 相反,它坐在它自己的层独立于一切。 这是非常有用的 - 这意味着我们可以创建不干扰页面上其他元素的位置的独立的UI功能 - 例如弹出信息框和控制菜单,滚动面板,UI功能,可以拖放到任何地方 在页面上,等等。
首先,请注意,定位的元素应该在文档流中的间隙不再存在 - 第一和第三元素已经关闭在一起,就像它不再存在! 好吧,在某种程度上,这是真的。 绝对定位的元素不再存在于正常文档布局流程中。 相反,它坐在它自己的层独立于一切。 这是非常有用的 - 这意味着我们可以创建不干扰页面上其他元素的位置的独立的UI功能 - 例如弹出信息框和控制菜单,滚动面板,UI功能,可以拖放到任何地方 在页面上,等等。...
注意:您可以使用 顶部
, zh-CN / docs / Web / CSS / bottom"> bottom
, left
和 right
来调整元素大小。 尝试设置 top:0;
bottom:0; left:0; right:0; 和 margin:0;
,看看会发生什么! 之后再回来...
注意:是的,边距仍会影响已定位的元素。 然而,保证金崩溃不是。
注意:您现在可以在 -positioning.html"class ="external"> 3_absolute-positioning.html
( css-layout / positioning / 3_absolute-positioning.html"class ="external">见源代码)。
定位上下文
哪个元素是绝对定位元素的"包含元素"? 默认情况下,它是 < html>
元素 - 定位元素嵌套在 HTML源代码中的 < body>
,但在最终布局中, 距离页面边缘顶部和左侧30px,即 < html>
/ a>元素。 这更准确地称为元素的定位上下文。
我们可以更改定位上下文 - 绝对定位元素相对于其定位的元素。 这是通过在元素的其他祖先之一上设置定位来实现的 - 它是嵌套在其中的元素之一(你不能相对于其中没有嵌套的元素来定位它)。 为了演示这一点,将以下声明添加到您的正文规则:
position: relative;
这应该给出以下结果:
<h1>Positioning context</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p class="positioned">Now I'm absolutely positioned relative to the <code><body></code> element, not the <code><html></code> element!</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; margin: 0 auto; position: relative; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; } .positioned { position: absolute; background: yellow; top: 30px; left: 30px; }
已定位的元素现在相对于 < body>
元素。
注意:您现在可以在 -context.html"class ="external"> 4_positioning-context.html
( css-layout / positioning / 4_positioning-context.html"class ="external">见源代码)。
介绍z-index
所有这些绝对定位是很好的乐趣,但还有另一件事,我们还没有考虑到 - 当元素开始重叠,什么决定哪些元素出现在其上的其他元素? 在我们已经看到的示例中,我们在定位上下文中只有一个定位的元素,它出现在顶部,因为定位的元素胜过未定位的元素。 当我们有多个?
尝试添加以下到您的CSS,使第一段绝对定位太:
p:nth-of-type(1) { position: absolute; background: lime; top: 10px; right: 30px; }
此时,您将看到第一段的颜色为绿色,移出文档流程,并位于原始位置上方一点。 它也堆叠在原始的 .positioned
段落下,其中两个重叠。 这是因为 .positioned
段落是源顺序中的第二个段落,并且稍后在源顺序中定位的元素将在源顺序中先前定位的元素上。
您可以更改堆叠顺序吗? 可以,您可以使用 z-index
属性。 "z-index"是对z轴的参考。 你可以从源代码中的上一点回想一下,我们使用水平(x轴)和垂直(y轴)坐标来讨论网页,以确定像背景图像和阴影偏移之类的东西的位置。 (0,0)位于页面(或元素)的左上角,x和y轴跨页面向右和向下(对于从左到右的语言,无论如何)。
网页也有一个z轴 - 一条从屏幕表面到你的脸(或你喜欢在屏幕前面的任何其他东西)的虚线。 / Web / CSS / z-index"> z-index
值会影响定位元素位于该轴上的位置 - 正值将它们向上移动到堆栈顶部,负值将它们向下移动 堆栈。 默认情况下,定位的元素都有一个 z-index
auto,实际上是0。
要更改堆叠顺序,请尝试将以下声明添加到您的 p:nth-of-type(1)
规则中:
z-index: 1;
你现在应该看到完成的例子:
<h1>z-index</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p class="positioned">Now I'm absolutely positioned relative to the <code><body></code> element, not the <code><html></code> element!</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; margin: 0 auto; position: relative; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; } .positioned { position: absolute; background: yellow; top: 30px; left: 30px; } p:nth-of-type(1) { position: absolute; background: lime; top: 10px; right: 30px; z-index: 1; }
注意, z-index
只接受无单位索引值; 你不能指定你想要一个元素是Z轴上23像素 - 它不工作这样。 较高的值将高于较低的值,这取决于您使用的值。 使用2和3将产生与300和40000相同的效果。
还要注意,我们在这里只真正讨论了一个单一的定位上下文。 如果你在同一页面中有两组不同的定位元素,并且希望使它们重叠,并使堆叠顺序以某种特定的方式工作,那么事情会变得复杂。 幸运的是,你很少会遇到这种与z-index的复杂性。 如果你想阅读关于z-index如何工作的更多细节,请查看 index"class ="external"> Web标准课程z-index writeup 。 在这篇文章中,我们为您提供了在这个阶段在学习中需要了解的所有信息。
注意:您现在可以在 -index.html"class ="external"> 5_z-index.html
( css-layout / positioning / 5_z-index.html"class ="external">见源代码)。
固定定位
还有一种类型的定位覆盖 - 固定。 这与绝对定位的工作方式完全相同,但有一个主要区别 - 而绝对定位会将元素固定在相对于 >< html>
元素或其最接近的已定位祖先,固定定位将元素相对于浏览器视口本身固定在适当位置。 这意味着您可以创建固定的有用的UI项目,如持久导航菜单。
让我们举一个简单的例子来说明我们的意思。 首先,从CSS中删除现有的 p:nth-of-type(1)
和 .positioned
规则。
现在,更新 body
规则以删除 position:relative;
声明并添加固定高度,如下所示:
body { width: 500px; height: 1400px; margin: 0 auto; }
现在,我们要提供 < h1>
元素 position:fixed;
,并让它坐在视口的顶部中心。 将以下规则添加到CSS:
h1 { position: fixed; top: 0px; width: 500px; margin: 0 auto; background: white; padding: 10px; }
需要 top:0;
才能使其粘贴到屏幕顶部; 我们然后给标题与内容列相同的宽度,并使用忠实的旧 margin:0 auto;
把它置于中心。 然后我们给它一个白色背景和一些填充,所以内容将不会在它下面可见。
如果您现在保存并刷新,您会看到一个有趣的小效果,标题保持固定,内容显示向上滚动并消失在其下。 但是我们可以改进这一点 - 目前有些内容从标题下面开始,因为定位的标题不再出现在文档流中,所以其他内容向上移动到顶部。 我们需要把它一点一点地移动; 我们可以通过在第一段设置一些顶部边距来做到这一点。 立即添加:
p:nth-of-type(1) { margin-top: 60px; }
你现在应该看到完成的例子:
<h1>Fixed positioning</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p class="positioned">I'm not positioned any more...</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body { width: 500px; height: 1400px; margin: 0 auto; } p { background: aqua; border: 3px solid blue; padding: 10px; margin: 10px; } span { background: red; border: 1px solid black; } h1 { position: fixed; top: 0px; width: 500px; margin: 0 auto; background: white; padding: 10px; } p:nth-of-type(1) { margin-top: 60px; }
注意:您现在可以在 -positioning.html"class ="external"> 6_fixed-positioning.html
( css-layout / positioning / 6_fixed-positioning.html"class ="external">见源代码)。
实验:位置粘性
有一个新的定位值可用称为 position:sticky
,其支持还不是很普遍。 这基本上是相对位置和固定位置之间的混合,其允许定位的元件像它被相对定位一样动作,直到其滚动到某一阈值点(例如,从视口的顶部10px),之后它被固定。 有关详细信息和示例,请参阅我们的位置:粘性引用条目。
概要
我相信你有乐趣玩基本定位 - 它是创建复杂的CSS布局和UI功能背后的基本工具之一。 考虑到这一点,在下一篇文章中,我们将更有趣的定位 - 我们将进一步,开始建立一些真实世界有用的东西。