在介绍定位之前,先了解一下浏览器默认的布局方式(Normal Flow),就是平时说的文档流。
正常/普通文档流(Normal Flow)
一般我们将元素分为块级元素、内联元素和块级内联元素。
默认的,一个块级元素的内容宽度是其父元素的100%,高度与其内容高度一致。而内联元素的宽高和内容一致,无法单独为其设置(如果要控制器宽高,可以通过设置display属性)。
那么正常文档流元素之间又是如何互相影响的呢?
默认的,块级元素在视口中垂直布局 --- 每个块级元素会在上一个元素下面另起一行,它们会被设置好的margin 分隔。行内元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他行内元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。如果两个相邻的元素都设置了margin 并且两个margin有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加(又叫做边距合并)。
下面我们就要介绍定位
定位(Position)
定位的想法就是改变上面所说的普通文档流行为,以产生对我们有用的效果,允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。举一个简单的列子:我们在浏览网页时出现的弹窗广告无论你滚动多少页总是固定在浏览器窗口的某个位置,这就可以通过定位来实现。很显然这个功能十分的强大也很让人吃惊。
CSS position
属性用于指定一个元素在文档中的定位方式。top
,right
,bottom
和 left
属性则决定了该元素的最终位置。
top样式属性定义了定位元素的上外边距边界与其包含块上边界之间的偏移,非定位元素设置此属性无效。
right样式属性定义了定位元素的右外边距边界与其包含块右边界之间的偏移,非定位元素设置此属性无效。
bottom样式属性定义了定位元素下外边距边界与其包含块下边界之间的偏移,非定位元素设置此属性无效。
left属性定义了定位元素的左外边距边界与其包含块左边界之间的偏移,非定位元素设置此属性无效。
z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
Position一共有五个属性值
- static(静态定位)
- relative(相对定位)
- absolute(绝对定位)
- fixed(固定定位)
- sticky(粘性定位)
static(静态定位)
该属性值为默认值,指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。这里没什么特别的内容,但是也给大家展示一下代码(我在代码中设置了top和left属性,但是页面没有变化,属性值是无效的)。
HTML内容
CSS内容
页面展示
relative(相对定位)
相对定位的元素并未脱离文档流,相对定位的元素是在文档中的正常位置偏移给定的值,但是不影响其他元素的偏移,元素仍保持其未定位前的形状,它原本所占的空间仍保留。
HTML内容
CSS内容
页面展示
我们通过设置top、left、right和bottom的值来精确的指定要将定位元素移动到的新位置,所谓相对就是指现对于元素文档流中的正常位置的偏移,我们设置了top和left各20px,为什么展示结果是向下和向右移动,我们可以理解为有一个力从盒子的顶部(top)和左边(left)分别向相反方向即底部(bottom)和右边(right)推动20px的距离。所以盒子是移动到了右下方(解释用语很通俗,是为了便于理解)。
absolute(绝对定位)
绝对定位的元素脱离了文档流。在布置文档流中其它元素时,绝对定位元素不占据空间。绝对定位元素相对于最近的position的值为非 static 祖先元素定位(如果所有的父元素都没有显式地定义position属性,那么所有的父元素默认情况下position属性都是static。)。当这样的祖先元素不存在时,则相对于ICB(inital container block, 初始包含块)。
这里有个名词叫定位上下文,就是指绝对定位元素相对哪个元素定位(上面已经解释了怎么判断),默认的定位上下文是 <html>。假如你想设定某个绝对定位元素的定位上下文,则需要在这个元素的某个祖先元素上设置 position: relative。
HTML内容
CSS内容
页面展示
一般来说绝对定位元素仿佛独立于一切。这是非常有用的:这意味着我们可以创建不干扰页面上其他元素的位置的隔离的UI功能 。例如,弹出信息框和控制菜单;翻转面板;可以在页面上的任何地方拖放的UI功能……
fixed(固定定位)
固定定位与绝对定位相似,同样脱离文档流,但元素的包含块为 viewport 视口(浏览器视口)。该定位方式常用于创建在滚动屏幕时仍固定在相同位置的元素。
HTML内容
CSS内容
页面展示
从代码中我给body添加固定高度,当我们滚动右侧滚动条时会发现Four元素始终在浏览器窗口得到固定位置,保持不动。这样我们就可以创建固定的有用的UI项目,如持久导航菜单。浏览器经常出现的垃圾广告也喜欢用固定定位。
sticky(粘性定位)
粘性定位是相对定位和固定定位的结合。默认情况下表现为相对定位,当浏览器窗口顶端与元素的距离等于 top 属性的值时,转变为固定定位。就是元素在跨越特定阈值前为相对定位,之后为固定定位。
HTML内容
<div>
<dl>
<dt>A</dt>
<dd>a1</dd>
<dd>a2</dd>
<dd>a3</dd>
<dd>a4</dd>
<dd>a5</dd>
<dd>a6</dd>
</dl>
<dl>
<dt>B</dt>
<dd>b1</dd>
<dd>b2</dd>
<dd>b3</dd>
<dd>b4</dd>
<dd>b5</dd>
<dd>b6</dd>
</dl>
</div>
CSS内容
body {
height: 1400px;
}
dl {
margin: 0;
padding: 20px 0 0 0;
}
dt {
background: #B8C1C8;
border: 2px solid gray;
color: #FFF;
margin: 0;
padding: 2px 0 0 12px;
position: sticky;
top: -1px;
}
dd {
font: bold 20px/45px Helvetica, Arial, sans-serif;
margin: 0;
padding: 0 0 0 12px;
white-space: nowrap;
}
dd + dd {
border-top: 1px solid #CCC;
}
页面展示效果不好截图,可以复制代码自己运行一下。
粘性定位常用于定位字母列表的头部元素。标示 B 部分开始的头部元素在滚动 A 部分时,始终处于 A 的下方。而在开始滚动 B 部分时,B 的头部会固定在屏幕顶部,直到所有B的项均完成滚动后,才被后面元素的头部替代。
须指定 top
, right
, bottom
或 left
四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
总结
我相信大家可以用基本定位愉快地玩耍;它是创建复杂的CSS布局和UI功能背后的基本工具之一。