让我们聊聊 position
属性。我知道初学者对此很感兴趣。我最近收到了一个问题。
我刚开始接触网页设计,还没有掌握元素定位的不同之处。我知道有
absolute
、fixed
和relative
。还有其他方法吗?它们之间有很大的区别吗?什么时候应该使用哪种方法?
简短回答
还有两种:static
,这是默认值,以及sticky
,它是一个非常花哨的东西。是的,所有这些都有很大不同!它们都非常有用,您应该使用哪一个当然取决于预期结果。
更详细的回答
首先要理解的一个重要概念是,网页上的每个元素都是一个块。从字面上讲,它是一个像素矩形。当您将元素设置为display: block;
或元素默认情况下是块级元素(如<div>
)时,这一点很容易理解。这意味着您可以设置width
和height
,并且该元素将尊重这些设置。但是,默认情况下为display: inline;
的元素(如<span>
)也是矩形,它们只是以不同的方式在页面上流动,并尽可能地水平排列。
现在您已经将每个页面元素都想象成一个像素块,我们可以谈论如何使用定位将这些像素块精确地放置在您想要的位置。
.el {
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;
position: inherit;
}
static
这是每个页面元素的默认值。不同元素没有不同的定位默认值,它们都以static
开始。静态并不意味着什么;它只是意味着元素将按照正常的方式流入页面。您唯一会将元素设置为position: static;
的原因是为了强制删除一些超出您控制范围的应用于元素的定位。这种情况很少见,因为定位不会级联。
relative
这种类型的定位可能最令人困惑,使用也最频繁。它的真正含义是“相对于自身”。如果您在元素上设置position: relative;
但不设置任何其他定位属性(top
、left
、bottom
或right
),它将不会对它的定位产生任何影响,它将与您将其保留为position: static;
时完全一样。但是,如果您确实为它提供了一些其他定位属性,比如top: 10px;
,它会将其位置从它正常的位置向下移动 10 个像素。我敢肯定您能想象到,根据元素的常规位置来移动元素的能力非常有用。我发现自己经常使用它来对齐表单元素,这些元素往往不愿意按照我想要的方式对齐。
在元素上设置position: relative;
时还会发生另外两件事,您应该注意。一是它引入了对该元素使用z-index
的能力,而这在静态定位元素上不起作用。即使您没有设置z-index
值,该元素现在也会出现在任何其他静态定位元素的顶部。您无法通过在静态定位元素上设置更高的z-index
值来对抗它。
另一件事是它限制了绝对定位子元素的范围。任何作为相对定位元素的子元素的元素都可以被绝对定位在该块内。这带来了一些强大的机会,我在这里讨论过。
absolute
这是一种非常强大的定位方式,它允许您将任何页面元素放置在您想要的确切位置。您使用定位属性top
、left
、bottom
和right
来设置位置。请记住,这些值将相对于具有相对(或绝对)定位的下一个父元素。如果不存在这样的父元素,它将默认返回到<html>
元素本身,这意味着它将相对于页面本身进行定位。
绝对定位的权衡(也是最重要的是要记住的)是这些元素从页面上元素的流中移除。具有这种定位类型的元素不受其他元素的影响,并且它也不影响其他元素。在每次使用绝对定位时,这都是一个需要认真考虑的事情。过度使用或不当使用它会限制网站的灵活性。
fixed
一个fixed
定位元素相对于视窗(或浏览器窗口本身)进行定位。当窗口滚动时,视窗不会改变,因此固定定位元素在页面滚动时会保持在它所在的位置。
这可能用于导航栏,您希望它始终可见,无论页面的滚动位置如何。固定定位的问题是它会导致固定元素覆盖内容,导致内容无法访问。解决的办法是留出足够的空隙以避免这种情况,以及这样的技巧。
sticky
粘性定位非常独特!一个sticky
元素会像静态元素一样在那里,但是当您滚动经过它时,如果它的父元素有空间(通常:额外的高度),则粘性元素将表现得好像它是fixed
,直到该父元素没有空间为止。用语言表达起来很奇怪,但很容易通过演示看到它发生的过程。
当我第一次开始使用MacRabbit 的 CSSEdit时,真正帮助我理解所有这些选项的是,能够看到正在进行的更改的实时预览,这确实有助于全面理解 CSS 代码的每一行实际在做什么以及它如何影响布局的其余部分。
PS – 不,我与 MacRabbit 没有关联,只是每天工作时都会使用该产品。
对于任何进入网页设计领域的人来说,这都是一个很棒的资源。
亲爱的 Chris,请学习“it’s”和“its”的区别。谢谢。
说实话,我一直试图避免使用定位,除非绝对必要。谢谢,Chris,我的身份暴露了,你给了我充分理解它的理由。
好文章!
@Schwallex: 对不起,我真的在努力避免这种情况,但我已经养成了不好的习惯,显然它有时还是会溜进来。
既然我们都在指出彼此的坏习惯,我看到你的网站上,你把每个 h2 元素都包裹在一个 div 中来进行定位。这是多余的代码,因为 h2 本身已经是块级元素,可以像其他块级元素一样进行定位。
很棒的文章!我非常欣赏它简洁和详细的风格。谢谢!
不错的文章,Chris!
我之前也写过一些关于这方面的文章
http://www.onyx-design.net/weblog2/css/css-positioning/
我一直期待着这样的文章。
非常感谢!
谢谢 Chris!我刚开始学习网页设计,对于这三者的区别我一直很困惑。这篇文章让我对它们有了更清晰的理解。
解释得很清楚,Chris!我一定会推荐我的 CSS 学生看这篇!
我记得刚开始学习 CSS 的时候,定位给我带来了很大的困扰,所以我相信这篇文章会启发许多人!
什么时候使用浮动是最佳实践?通过将元素设置为相对定位的元素内的绝对定位,难道不能实现浮动所带来的相同效果吗?而且通过将元素设置为绝对定位,我们可以避免清除浮动吗?
我希望我将我的问题解释清楚了!感谢你的文章
作为一个“传统”的程序员(本质上是我主要在编译代码而不是解释代码),这对我来说是 CSS 最难学习的部分。这是由于它相对于上下文的差异。
感谢你写了这篇文章,阅读它感觉很棒,继续学习的感觉真棒!
为了回答 fallsemo 的问题,我提供一些建议:如果可以,不要混合使用浮动和定位。
这只是我的个人意见,我并没有否认它们可以展现的技巧,我只是建议抑制它们可能带来的所有问题。
@fallsemo
重要的区别是,浮动元素仍然是页面“流动”的一部分,而绝对定位的元素则不是。因此,浮动元素可能是更“灵活”的选择。
嗨,chi
当我增加窗口大小的时候,div 容器并没有固定在特定的位置。我也使用了绝对定位,但它没有起作用。请帮帮我。
嗨,我是 Finsta,感谢你的帮助!我现在理解可怕的定位了 xD 你帮助了我以及许多其他人。还有那个论坛里的那个家伙,我忘记了他的名字
嘿,感谢你的文章,非常有用,就像复习之前学过的东西一样
再次感谢
不错的文章。谢谢。
感谢你的文章,Chris。当我开始为网页开发时,我在这方面遇到了很大的困难。为了理解它是如何工作的,我进行了一些自己研究。现在我认为我已经了解了差异,并且开发了一个使用固定头部和侧边栏的购物中心。
像往常一样很棒的文章,Chris。感谢你的信息。我通常使用浮动,但会尝试使用其中一些方法,看看哪个最适合我(如果这说得通)。
嗨,Chris,作为Bluelounge网站的开发人员,你上面使用的网站作为示例,我希望我可以分享一些我的经验。
当我们开始重新设计网站时,左侧导航栏上的菜单项较少,因此即使在 800×600 的屏幕上,所有内容都可见。但是随着网站的不断发展,导航栏也越来越长,对于屏幕较小的浏览器来说,它可能不是最友好的。我非常清楚这个问题,并且正在努力寻找一种解决方案,而无需减少菜单项。欢迎提出建议 :-)
很棒的文章。你确实涵盖了我一直在努力学习的关于定位及其用途的所有内容。感谢你将其变得如此简单和简洁。
Chris,定位的总结非常棒,我一定会收藏它。回顾基础知识总是有用的,因为它们通常是我最容易忘记并且最难以处理的部分!
很好的概述,谢谢!
我认为 position: fixed; 将某个元素固定到最近的拥有 position: relative(默认情况下是视窗(<html>))的父元素。有没有机会确认一下?
感谢你,Chris。我一直想知道为什么导航元素没有更常被固定。现在我知道该避免什么了……我想:)
嗨,Chris,
感谢你写这篇文章,Chris。
我遇到了与 David 上面提出的相同的问题,关于固定定位。
我认为固定定位是相对于<HTML> 而不是视窗(屏幕)。
我创建了一个页面,其中包含一个框架。
框架包含一个页面,页面中有一个加载图像,它的 CSS 代码如下所示:
position:fixed; left:50%; right:50%; top:50%; bottom:50%; height:1px; width:1px;
当我在内部页面中单独浏览时,这张图片显示在中间,但是当我浏览包含此页面的父页面(父页面包含此页面的 iframe)时,它显示在 iframe 的中间,而不是屏幕的中间。
我希望图片显示在屏幕的中间而不是 iframe 的中间,我已经尝试过,但没有得到想要的结果。
有没有什么方法可以做到这一点?
我漏掉了<HTML> 的一个语句。
更正*
我认为固定定位是相对于<HTML> 而不是视窗(屏幕)>> 我认为固定定位是相对于<HTML> 而不是视窗(屏幕)。
非常感谢你,Chris。我真的很感谢你的“中等答案”。它真的很有帮助!
我还要补充一点,当滚动到固定元素的边界时,它们不会继续滚动它们的父元素。它们只会在其边界处停止滚动,就像你预期的那样。它们可以是获得多个嵌套滚动区域的好方法,这些滚动区域不会相互干扰,从而导致 body 元素出现意外滚动。
嘿,伙计们
如何学习 Bootstrap?