网页开发入门|11 定位
Word中的图片会随着文本内容的变化跟着移动,而PowerPoint中的图片则不会,这就是图片的“定位”。

在上节课的最后,我们遗留下来了三个问题,其一便是下图中的这个小红点。

把未读消息标记为小红点已经成为设计中的惯例,我们会在大量的网页或者APP上看到类似的设计。

有些时候还会显示出具体的数字。

还有的时候还会显示出文字,甚至形状也不再是圆的。

这些小红点学名称作徽章Badge,是一种常见的装饰,通常用来提醒用户,图标或者按钮这里有一些特别的东西可以关注。
徽章有时还会出现在另外三个角落上,以应对更丰富的场景。
比如提醒用户换头像:

展示用户的尊贵身份:

游戏中标记人物等级或者状态:

但不论徽章是什么样子,用于什么目的,它都需要重叠在它要装饰的元素上。
我们知道可以用块级元素block
实现垂直排列元素,也知道了使用行内块级元素 inline-block
进行水平排列,但是如何把元素叠在一起呢?
本节课就让我们来解决这个重叠的问题。
文档流Normal Flow
两个元素叠在一起,说明这两个元素所在的位置发生了重合,所以我们需要重新思考一下,网页上的各个元素为什么会在现在的位置上。
网页中各元素的位置在默认的情况下,都是按照HTML
代码里的书写顺序,在不发生遮盖的情况下,尽可能的靠上(块级元素)、靠左(行内元素)显示。
也就是说每个元素的位置取决于上一个元素的位置,而不是自己决定自己的位置。
我们可以通过分别在Word
和PowerPoint
中插入图片来感受一下两者区别。
在Word
中的图片会随着文本内容的变化跟着移动。

而PowerPoint
中的图片则不会随着别的内容修改而改变自己的位置。

网页中元素的位置更接近在Word
文档中的这种,当前面的内容删除了之后,后面的内容会自动补充过去,就好像是流水一样,哪里低就流向哪里。所以,称作文档流Normal Flow。

绝对定位
元素的样式属性「定位」position
,可以告诉浏览器是否将元素从文档流中拿出来单独处理。
设置position: absolute
绝对定位,就是一种让元素从文档流中脱离出来的方法。绝对定位的元素将保持在页面某个位置上,出现类似PowerPoint
中的效果。
让我们创建一个新文件position.html
,然后体验一下。
<div class="absolute">
<img src="assets/icon.png">
</div>
<div class="greeting">欢迎关注弦五说!!</div>
.absolute {
position: absolute;
}

因为图片变成了绝对定位的元素,所以它脱离了文档流。原本应在图片下一排显示的文字,不再被图片影响,从而显示在了图片原本的位置,两个元素的位置相同,从而引发了重叠。
绝对定位的元素默认会呆在它原本在文档流中的位置,如何调整它的位置呢?
这需要使用left
、right
、top
、bottom
4个样式属性,用来指明元素的位置距离文档的4个边缘多远。

.absolute {
position: absolute;
left: 25px;
top: 40px;
}

通常,我们只需在left
和right
这一对中选取一个进行设定,没有必要同时设定两个。top
和bottom
也是类似的情况。
即使我们同时设定了两个,其实也只会有一个生效,具体是哪个生效取决于文档流的方向,在一般情况下 left
和top
具有更高的优先级。
绝对定位适合用于排版准确度要求比较高,且内容相对明确的页面,比如产品的官网、邀请函等。

但用绝对定位来实现徽章却不太方便:徽章只是用来装饰,我们不能要求被装饰的对象也一起成为绝对定位的元素。如果原本要被装饰的对象依然是在文档流中的,一旦被装饰的对象随着文档流发生变化,徽章就很难跟着同步移动了。
固定定位
还有的时候,我们不是要将元素的位置固定在在页面中的某处,而是要相对于浏览器窗口来定位。
比如,给用户弹出的对话框,无论用户目前阅读到了页面的哪里,都需要在整个浏览器窗口里居中。

这种定位方法叫做固定定位,对应的position: fixed
。
固定定位的元素同样会脱离文档流,也使用left
、right
、top
、bottom
4个样式属性,用来标记元素的位置应该距离浏览器窗口的4个边缘多远。
看一下效果。
<div class="fixed">
<img src="assets/icon.png">
</div>
.fixed {
position: fixed;
right: 25px;
top:40px
}

固定定位因为会跟着浏览器窗口移动,没有办法准确的停在某个元素附近,就更不适合实现徽章了。
相对定位
除了绝对定位和固定定位还有一种相对定位的方法,对应的position: relative
将元素设定为相对定位时,元素将依然存在于文档流中,这时left
、right
、top
、bottom
4个样式属性,让元素偏离原本所在的位置。
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="relative">
<img src="assets/icon.png">
</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
.relative {
position: relative;
left: 25px;
top: 40px;
}

相对定位能实现元素的重叠的同时,还能跟着文档流流动,比较适合实现徽章。
但相对定位也有一个不尽如人意的地方:因为相对定位的元素并没有脱离文档流,尽管它显示的位置发生了偏移,但它依然占据着文档流中原本的位置,这导致原本的位置会显示出一个空白区域。

复合定位
我们可以综合使用绝对定位和相对定位,可以让元素既能在局部发生位移,又能让元素脱离文档流,避免空白区域。
这需要用到绝对定位的一个特性。
当绝对定位的父元素不是默认定位方式,而是绝对定位、固定定位、相对定位中的任何一种时,这个绝对定位的元素仍然会脱离文档流,但位置不再以整个文档的边缘为基准偏移,而是以这个父元素的(外边距)边缘为基准偏移。
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="relative">
<div class="absolute"><img src="assets/icon.png"></div>
</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
<div class="greeting">欢迎关注弦五说!!</div>
.absolute {
position: absolute;
left: 25px;
top: 40px;
}
.relative {
position: relative;
}

这种复合定位的方式,很适合实现徽章的效果。
我们可以把要被装饰的元素和小红点装到同一个父元素里,并把这个父元素设置为相对定位,然后把小红点设置为绝对定位,这时再调整小红点的位置即可。
<div class="badge-father">
<img src="assets/icon.png">
<div class="badge"></div>
</div>
.badge-father {
position: relative;
width: fit-content;
}
.badge {
position: absolute;
top: 0px;
right: 0px;
background-color: red;
width: 12px;
height: 12px;
border-radius: 50%;
}

这样小红点以及它所装饰的icon
就可以随着父元素一起,随着原本的文档流移动了,从而实现了徽章的效果。
我将本课程所有的代码托管在gitee
上了,你可以点击这个链接,或到gitee.com
上搜索弦五 网页开发入门,查看和获取本课程的全部代码。