CSS 定位 position 学习笔记
定位不适合总体布局,因为它会把元素拉出页面的正常流。
反过来看,这也正是定位在 CSS 中之所以重要的原因。
定义
定位(position) 总共有 5 种类型:
-
static
静态定位,元素的初始定位方式,意思是块级元素垂直堆叠。
-
relative
相对定位,可以相对于其原始位置控制该元素的偏移,同时又不影响其周围的元素。
与此同时,这也为该元素的后代元素创造了定位上下文,这一点也是相对定位的真正用处。
-
absolute
绝对定位,支持精确定位元素。
绝对元素会根据其最近的定位上下文——其非静态定位的祖先元素,如果祖先元素不存在,则使用 HTML 元素——进行偏移。绝对定位的元素会脱离页面流,然后再相对于其定位上下文进行定位。
默认情况下,它们会被浏览器定位于之前静态定位是所处的位置,但不会影响周围元素(已脱离标准文档流)。
可以相对于 定位上下文 来改变其位置。
有一个说法是 子绝父相,意思就是说子元素是绝对定位,而父元素是相对定位。主要是因为父元素在大多数情况下是要在 标准文档流 之中定位的,因此在大多数的业务场景之下,父元素使用的是相对元素。
但是绝对定位的 定位上下文 是非静态的祖先元素,也就是说相对元素、绝对元素、固定元素、粘附元素都可以作为其 定位上下文。
-
fixed
与 绝对定位基本类似,只不过 定位上下文 被自动设置为 浏览器视口(viewport)。
-
sticky
当元素在文档流的原始位置在视窗内时,根据正常的文档流定位。当元素不在文档流的原始位置在视窗内时,根据其 最近滚动祖先 进行定位。
滚动祖先的定义是:当该祖先的
overflow
是hidden
,scroll
,auto
, 或overlay
,这点要注意一下。
定位类型总结对比如下:
属性 | 脱离标准流 | 移动参照物 | 使用频率 |
---|---|---|---|
static | 否 | 无 | 少 |
relative | 否(有占位) | 自身 | 多 |
absolute | 是(不占位) | 最近祖先 | 多 |
fixed | 是(不占位) | 视图(viewport) | 多 |
sticky | 否(有占位) | 视图(viewport) | 少 |
使用场景
-
static
没有声明的情况,也就是默认的情况下使用。
-
relative
书中原文:
以前,在一些古老的布局技巧中,经常要偏移元素,当然现在已经很少这样了。
目前的用法是做子元素的定位源。
-
absolute
弹出层、提示、对话框、焦点图这种都可以应用绝对定位去完成。
一些学习案例:
-
效果如下,即白色的小圆点部分:
-
其实这个学成在线首页利用绝对定位的部分,也是在焦点图的制作
-
这一块,工程师旁边的 分割线 用的是绝对定位去做的,适用浮动会导致盒子被撑开,根据视觉效果来说,很明显这个分割线需要脱离这个浮动的文档流。
再建立一个 div 去包这个分割线也不是不行,但是在这种能够相对比较轻松的用定位去解决的情况下,再包一层无意义的 div 去降低语义化的意义不是很大。
效果图如下:
-
-
fixed
以 CSDN 为例,最右侧的工具栏,也就是新手引导、客服、举报这一块是用 fixed 做的。
案例的话,学成在线首页完整版 中的 sidebar 用的就是 fixed。
-
sticky
以 CSDN 为例,右侧的工具栏,也就是分类专栏这一块可以用 sticky 去做。目前是采用当视图在焦点的时候的定位是 relative,当移动到了一定的位置下方后,定位是 absolute。
如下:
注意看 csdn-toolbar 的 position 在这个时候还是 relative。
一旦脱离了视窗所在的高度之后,csdn-toolbar 的 position 就变成了 fixed。
这就是用 JavaScript 完成的 sticky 功能。
目前 sticky 的兼容性可能还有点问题,opera 和 edge 一直到现在还是 partial support,比较早的 chrome 版本,即 90 之前都是处于 partial support 的状态。opera mini 则是到现在都还没有支持。