在理解CSS是如何控制页面显示效果的时候,我们必须要掌握盒模型(Box Model)和定位(position)机制。今天就来针对定位展开学习。
定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素,或者另一个元素甚至浏览器窗口本身的位置。
CSS有三种基本的定位机制:
- 文档流(normal flow),包含默认定位(static)和相对定位(relative)。
- 绝对定位,包含绝对absolute和fixed
- 浮动
HTML的文档流
在介绍postion之前,有必要先了解下文档流。文档流在W3C中叫做normal flow,不知道为啥中文翻译成文档流,在W3C的CSS Positioned Layout Module Level 3的规范中对normal flow的定义如下:
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. See the CSS Basic Box Model moduleCSS3 BOX for further details aboutnormal flow.
简言之,文档流和CSS盒模型有关,在文档流中的盒子属于一个格式化的上下文,可以是块级或行内的盒子,但不能同时存在。在文档流中,元素按照其在HTML中的先后位置至上而下布局,在这个过程中,行内元素(inline)水平排列,直到当行被占满然后换行,块级元素(block)则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是文档流定位,也可以说,文档流中元素的位置由该元素在HTML文档中的位置决定。
有三种情况可以使得元素脱离文档流存在,分别为:浮动、绝对定位和固定定位(定位模式将在下文详细进行解释)。
堆叠顺序z-index
HTML元素的确放在三维空间中。每个网页都可以看成是由一层一层页面堆叠起来的,如下图所示:
备注:Firefox安装Tilt插件后,按Ctrl+Shift+M可查看网页的3D视图
除了平时我们知道的x轴和y轴,元素通过z轴控制他在第三个维度的显示。像我们熟悉的margin, float是用来控制元素在x轴和y轴的位置的。而z-index就是用来控制元素z轴的显示的。
z-index属性
z-index这个属性只能应用在position属性为relative(相对定位), absolute(绝对定位)或者fixed(固定定位)的元素上。它有下面三个取值:
值 | 描述 |
auto | 元素在当前层叠上下文中的堆叠顺序是0,元素不会创建新的局部层叠上下文 |
<integer> | 用整数值来定义堆叠顺序, 创建一个新的堆叠上下文 |
inherit | 设置和它父元素一样的堆叠上下文,并且不会创建新的层叠上下文 |
当我们使用z-index属性设置元素的堆叠顺序的时候,这个元素的堆叠顺序和页面上的其它元素的堆叠顺序并不会相互影响。元素的堆叠层级仅仅是相对于他的堆叠上下文。堆叠顺序就是当前元素在z轴上的值。较大的数值元素的堆叠顺序就高,离屏幕更近。
使用position属性进行定位
position属性规定元素的定位类型。有以下5种值可供选择。
position值 | 如何定位 |
static | position的默认值。元素将定位到它的正常位置,其实也就相当于没有定位。元素在页面上占据位置。不能使用top right bottom left移动元素位置。 |
relative | 相对定位,相对于元素的正常位置来进行定位。元素在页面占据位置。可以使用top right bottom left移动元素位置。 |
absolute | 绝对定位,相对于最近一级的 定位不是static的父元素来进行定位。元素在页面不占据位置。 可以使用top right bottom left移动元素位置。 |
fixed | 固定定位,相对于浏览器窗口来进行定位。其余和absolute一样,相当于一种特殊的absolute。 |
inherit | 从父元素继承position属性的值,IE8之前不支持。 |
sticky | 黏性定位,CSS3新增,表现类似position:relative和position:fixed的合体,在目标区域在屏幕中可见时,它的行为就像position:relative; 而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。 |
默认定位static
static,无特殊定位,它是html元素默认的定位方式,即我们不设定元素的position属性时默认的position值就是static,它遵循正常的文档流对象,对象占用文档空间,该定位方式下,top、right、bottom、left、z-index等属性是无效的。
相对定位relative
相对定位指的是相对自己文档流中的原始位置定位。它的特点是不会脱离文档流。也就是说,使用position:relative定位,其元素依旧在文档流中,他的位置可以使用left、right、top、bottom、z-index等定位参数。
绝对定位absolute
绝对定位,虽然它的名字号曰”绝对”,但是它的功能却更接近于”相对”一词。使用绝对定位后,元素会脱离文档流,并且只能根据祖先类元素(父类以上)进行定位,另外这个祖先类还必须是以postion非static方式定位的。也就是说,它可以相对于各种各样的东西进行定位,除了static。
绝对定位中元素框从文档流完全删除,并相对于其包含块定位。元素定位后生成一个块级框,而不论原来它在正常流中是何种类型的框。
因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的其它元素。可以通过设置 z-index 属性来控制这些框的堆放次序。
固定定位fixed固定定位类似于将 position 设置为 absolute,不过其包含块是视窗本身。fixed 是一种特殊的绝对定位,对其设置的偏移量永远是相对于视窗本身。我们常见到的导航条固定在页面顶部,回到页面顶部按钮基本都是采用此定位方式。同样可以通过设置 z-index 属性来控制这些框的堆放次序。
黏性定位 sticky
position: sticky 是一个新的 css3 属性,它的表现类似 position: relative 和 position: fixed 的合体,在目标区域在屏幕中可见时,它的行为就像 position: relative; 而当页面滚动超出目标区域时,它的表现就像 position: fixed,它会固定在目标位置。目前 sticky 在各个浏览器上的兼容性还有很多的问题,要实现类似的功能可使用 JS 的方式。
<div class="header"></div>
.sticky { position: fixed; top: 0; } .header { width: 100%; background: #F6D565; padding: 25px 0; }
var header = document.querySelector('.header'); var origOffsetY = header.offsetTop; function onScroll(e) { window.scrollY >= origOffsetY ? header.classList.add('sticky') : header.classList.remove('sticky'); } document.addEventListener('scroll', onScroll);
CSS 浮动布局
浮动的定义:使元素脱离文档流,按照指定方向发生移动,遇到父级边界或者相邻的浮动元素停了下来。浮动和绝对定位类似,可能会覆盖掉页面正常的框。
1、向右浮动,原来的空间被其他框所占用。
2、向左浮动,覆盖其他框。
3、三个框都浮动,后面的框碰着前一个框的边框顺序排列。
4、当一行无法容纳下完整的一个框时,自动从下一行依次排列。排列起始位置取决于第一行已经排好的框的高度,以已经排好的行的最后一个框的高度为基准。
浮动可能会覆盖别的框,但有例外。当行框与浮动框相遇时,浮动框旁边的行框被缩短,从而给浮动框留出空间,行框围绕浮动框,这里的行框也仅限于普通文档流中的行框(绝对定位中的文本还是会被覆盖的)。
由上我们可以看出,浮动会影响后面的元素,那怎么清理浮动呢?
假设希望让一个图片浮动在左边,文本块浮动在右边,并且希望这幅图片和文本包含在另一个具有背景颜色和边框的元素中。
由于浮动,容器将无法包围他们,当然无法达到我们想要的效果。
由于两个块都是浮动的,无法对他们进行清除浮动,所以只能借助第三方了。
我们使用一个空的 div 元素以实现下图的目标。
div.clear { clear: both; }
清除浮动的方式当然不止上面一种,但上面的方式兼容性强,使用方便,是初学时使用的上佳之选。
CSS overflow 属性
overflow 属性指定当内容溢出其块级容器时,是否剪辑内容,显示滚动条或显示溢出的内容。
/* 默认值。内容不会被修剪,会呈现在元素框之外 */ overflow: visible; /* 内容会被修剪,并且其余内容不可见 */ overflow: hidden; /* 内容会被修剪,浏览器会显示滚动条以便查看其余内容 */ overflow: scroll; /* 由浏览器定夺,如果内容被修剪,就会显示滚动条 */ overflow: auto; /* 规定从父元素继承 overflow 属性的值 */ overflow: inherit;
参考链接:
- CSS 定位机制之一:普通流
- 从 position: relative 说起 CSS 中的定位和文档流(normal flow)
- How z-index Works
- CSS 定位浮动
- 使用 position: sticky 实现粘性布局
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/position
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow
- https://www.w3school.com.cn/css/css_positioning_floating.asp
- 清理浮动的那些事儿——6种清理浮动的方法