最近在工作中偶尔接触到 CSS 布局的问题,想着自己 CSS 实在太水,因此对这些问题总结一下,统一加深一下印象,以备不虞。
之前在研究 avalon 拖动组件 的时候,总是弄不清拖动的实现原理。后来发现是使用 relative
来进行定位。后来发现这个定位方式确实符合拖动的需求,它的主要效果是 使元素偏离正常的位置 ,其他元素不会调整位置来弥补其偏离后留下来的空隙。其与 absolute
不同,其偏离对于父元素的定位方式没有要求,且始终占位,不脱离文档流。
在帮人看项目的时候遇到了脱离文档流的情况,一时手足无措,只会去查找 float
,后来发现是由于定位是 position: absolute
引起的。也就是说,绝对定位是脱离文档流的。
发现 position: absolute
居然也可以脱离文档流之后,我不仅陷入了沉思:
什么是文档流?还有什么其他情况会导致脱离文档流呢?
所谓的文档流实际上是一种民间说法,正常称谓应该指的是 常规流(normal flow) ,个人感觉这两者应该是“阀值”与“阈值”的关系。从直观上理解正常流指的是元素按照其在 HTML 中的位置顺序决定排布的过程,主要的形式是自上而下,一行接一行,每一行从左至右。
后来翻阅了一下 CSS2.1 规范 ,算是彻底搞明白了这个问题。CSS2.1 中, 定位方案(Positioning Schemes) 一共分三种:
absulote
和 fix
两种 由此我们就知道,所谓的不脱离文档流就只有三种情况:块级、行内和相对定位。由此上面遇到的第一个问题也就得以证实: 相对定位是不脱离文档流的 。
其实脱离文档流的问题也迎刃而解,就只有两种情况: 浮动 和 绝对定位 。而这两者的表现实际上非常相似,区别仅在于 宽度缺失 (详见 这里 )。
由于使用了相对定位和绝对定位的元素都会产生宽度缺失,因此会造成层叠的情况。层叠顺序基本按照后者覆盖前者的顺序。但是如果要改变顺序的话,就需要使用 z-index
属性。
需要注意的是: z-index
只有在 position
值为 relative
, absolute
和 fixed
的元素上有效。而其比较的规则遵循“拼爹原则”,即先比较具有 z-index
属性的父辈元素,父辈元素 z-index
大的子辈元素都大。
但更需要注意的是:并非使用了 absolute
来进行定位就一定要设置 z-index
,大量的 z-index
会使项目无法维护。
上文已经说明了一点,即尽量依托后来居上的方式来设置 z-index
,不要造成其滥用;同时还有一点是使用 absolute
也不是必须设置 TRBL。一般的教程都会说:使用 absolute
后,使用 TRBL 可以将元素定位到最近的非 static
的元素之内对应的偏移位置,却都没有说如果不使用 TRBL 会怎样。实际上如果不使用 TRBL, absolute
会立即 原地脱离文档流 ,即立刻在原来的位置浮动并不占用宽度,效果与下拉框十分相似。如果配合 margin
就可以将其定位到某一个元素的下方进行浮动,从而实现下拉框的效果。