定位
定位
一个元素可以通过 position 属性来定义为定位元素,它有如下属性值:
- static:默认的初始值,可以认为元素是“未被定位的”;而使用其它值可以认为元素“已被定位”。
- relative:相对定位,相对于元素原本的位置进行偏移,且原本占据的空间不会消失(可能会造成原本位置形成空白区域,或偏移后元素覆盖其它元素);该属性值通常用来将一个元素声明为绝对定位元素的容纳块。
- absolute:绝对定位,会将元素从文档流中移除,其位置相对于容纳块确定。容纳块是 position 属性不为 static 的最近祖辈元素。
- fixed:固定定位,元素框行为与absolute类似,不过容纳块是视区本身。例如,fixed声明的元素若在屏幕中间,无论我们怎样滚动页面,它始终在屏幕中间。
- sticky:粘滞定位,是绝对定位与固定定位的结合体。正常情况下,元素随页面滚动,但当元素到达屏幕特定位置后,继续滚动,元素会触发粘滞条件,锁定在该边界位置,此时元素从文档流中移除,但原本占据的空间仍保留。
定位元素的位置由偏移属性 top、right、bottom、left 确定,正值是内向偏移(向容纳块中心移动),负值则是外向偏移。实际上,由四个偏移量也能确定元素的大小,而无需再使用 width 与 height 属性来确定。注意:当元素使用 width 与 height 属性来指定大小后,又指定了 top right bottom left 四个偏移量,通常元素的大小仍由 width 与 height 确定,同时使用top 与 left属性来确定元素的偏移位置,而忽略 botton 与 right 属性。
使用定位实现一个下拉菜单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ width: 80%; max-width: 1000px; margin: 1em auto; } .dropdown{ display: inline-block; /*使得宽度由内容区大小而定,而不是占据整个屏幕宽度*/ position: relative; } .dropdown-label{ padding: 0.5em 2em 0.5em 1.5em; border: 1px solid #ccc; background-color: #eee; } /* 在菜单标签旁边设计一个小箭头 */ .dropdown-label::after{ content: ""; position: absolute; /*其容纳块为.dropdown */ top:1em; right: 1em; border: 0.3em solid; border-color: black transparent transparent transparent;/* 由border属性设计的小三角形*/ } .dropdown-menu{ display: none; /* 菜单选项默认隐藏 */ position: absolute; /* 其容纳块为.dropdown ,菜单选项定位在菜单标签下方*/ left: 0; top:2.1em; min-width: 100%; /* 当元素宽度很小的时候,适应.dropdown的框体宽度*/ background-color: #eee; } /* 选取的是悬浮状态下的.dropdown元素的后代元素.dropdown-menu*/ .dropdown:hover .dropdown-menu{ display: block; } /* 菜单打开时,小箭头由向下变为向上*/ .dropdown:hover .dropdown-label::after{ top: 0.7em; border-color: transparent transparent black transparent ; } .submenu{ padding-left: 0; margin: 0; list-style-type: none; border: 1px solid #999; } .submenu > li + li{ border-top: 1px solid #999; } .submenu >li >a{ display: block; padding: .5em 1.5em; background-color: #eee; color: #369; text-decoration: none; } .submenu >li >a:hover{ background-color: #fff; } </style> </head> <body> <div class="container"> <nav> <div class="dropdown"> <div class="dropdown-label">Main Menu</div> <div class="dropdown-menu"> <ul class="submenu"> <li><a href="/">Home</a></li> <li><a href="/coffees">Coffees</a></li> <li><a href="/brewers">Brewers</a></li> <li><a href="/specials">Specials</a></li> <li><a href="/about">About us</a></li> </ul> </div> </div> </nav> </div> </body> </html>
堆叠上下文
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ position: relative; background-color: #999999; overflow: auto; } .container div{ width: 100px; height: 100px; } .one{ margin: 10px; background-color: #eeeeee; /*position: relative;*/ } .two{ margin-top: -60px; margin-left: 20px; background-color: brown; /*position: relative;*/ } .three{ margin-top: -60px; margin-left: 40px; background-color: #336699; } </style> </head> <body> <div class="container"> <div class="one"></div> <div class="two"></div> <div class="three"></div> </div> </body> </html>
上面代码中使用了负外边距使元素形成重叠,而堆叠的顺序是按照元素在浏览器中的绘制顺序(也即HTML文档中源码的顺序),如下图1所示。但使用定位元素时,这种行为会改变——浏览器会先绘制所有非定位元素,再绘制定位元素。因此给.two元素声明position:relative时,它就呈现在最前面了,如图2所示。
对于定位元素之间,我们又如何改变堆叠顺序呢?我们可以使用 z-index 属性。该属性只适用于定位元素(有非static的position属性),调整元素的堆叠次序,该属性的值越大,意味着元素离读者越近,也就越在最上层。注意,定位元素是基于容纳块的堆叠上下文进行堆叠的,也就是说,若容纳块的z-index属性值过低,它里面的定位元素的z-index值即使再高也是处于其他元素(与容纳块同一层级的元素)的底下。
总结z-index属性失效的情况(元素设置了z-index值但没有取得预期效果)
- 该元素不是定位元素,也即没有position属性或者position属性是static;
- 该元素的父元素的z-index值过低;
- 对于设定了负值的子元素,它仍然会显示在父元素上层;
- 父元素可能溢出或设置了隐藏;
注:这里的“父元素”就是指容纳块。
所有堆叠上下文内的元素按一下顺序,从后往前堆叠:
- 堆叠上下文的根
- z-index 为负的定位元素及其子元素;
- 非定位元素;
- z-index 为auto的定位元素及其子元素;
- z-index 为正的定位元素及其子元素;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)