# CSS3:sticky 粘性布局

# 1、效果图

xcooo

# 2、粘性定位是什么?

粘性定位 sticky 相当于相对定位 relative 和固定定位 fixed 的结合;在页面元素滚动过程中,某个元素距离其父元素的距离达到 sticky 粘性定位的要求时;元素的相对定位 relative 效果变成固定定位 fixed 的效果。

MDN 传送门 (opens new window)

# 3、如何使用?

使用条件:

  • 父元素不能 overflow:hidden 或者 overflow:auto 属性
  • 必须指定 top、bottom、left、right 4 个值之一,否则只会处于相对定位
  • 父元素的高度不能低于 sticky 元素的高度
  • sticky 元素仅在其父元素内生效 在需要滚动吸顶的元素加上以下样式便可以实现这个效果:
.sticky {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
}
1
2
3
4
5

# 4、兼容性

  • 它的兼容性比起 relative、fixed、absolute 相对差一些
  • 因为这个 API 还只是实验性的属性。不过这个 API 在 IOS 系统的兼容性还是比较好的。

# 5、demo代码

<!DOCTYPE html>
<meta charset="UTF-8">
<title>粘性定位</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<html>

<head>
    <style>
        .content {
            height: 2000px;
            font-size: 16px;
        }

        .title {
            position: sticky;
            top: 0;
            padding: 5px;
            background-color: #ccc;
        }

        .item {
            height: 50px;
            line-height: 50px;
            font-size: 16px;
        }
    </style>
</head>

<body>
    <div class="content">
        <h1>Contacts</h1>
        <div class="title">A</div>
        <div class="item">啊三</div>
        <div class="item">啊五</div>
        <div class="item">apple</div>
        <div class="item">Alph</div>
        <div class="item">ABC</div>
        <div class="item">apple</div>
        <div class="item">Alph</div>
        <div class="item">ABC</div>
        <div class="item">apple</div>
        <div class="item">Alph</div>
        <div class="item">ABC</div>
        <div class="title">B</div>
        <div class="item">Banana</div>
        <div class="item">Back</div>
        <div class="item">Banana</div>
        <div class="item">Back</div>
        <div class="item">Banana</div>
        <div class="item">Back</div>
        <div class="item">Banana</div>
        <div class="item">Back</div>
        <div class="item">Banana</div>
        <div class="item">Back</div>
        <div class="title">C</div>
        <div class="item">China</div>
        <div class="item">Cat</div>
        <div class="item">Cookie</div>
        <div class="item">Cake</div>
        <div class="item">Color</div>
        <div class="item">China</div>
        <div class="item">Cat</div>
        <div class="item">Cookie</div>
        <div class="item">Cake</div>
        <div class="item">Color</div>
    </div>

</body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

# 6、vue移动端框架van-sticky粘性布局,,实现原理和失效原因及注意点

# 实现原理

xcooo

# 失效原因

要实现这个效果,最简单的办法就是在css样式里添加position:sticky就可以实现,就这么简单,比用js监听页面滚动,然后达到一定高度样式变为fixed,简单且性能好。

vue 的van-sticky组件实现粘性的原理就是通过添加position:sticky实现的,但是如果你使用了position:sticky后失效,并没有效果的原因有:

  • 1.父元素高度没子元素高,通常为父元素设置height:100%;

  • 2:父元素设置了overflow:hidden,overflow-x:hidden,overflow-y:hidden,或者overflow:auto属性都能影响到

  • 其中父元素是指所有父元素,不单单是上一级父元素,在vue中如果失效了别忘了看app.vue组件里是不是设置了这些。

# 注意点

  • 解决好失效问题后,我们再看van-sticky的其中一个悬停的时候距离顶部的距离offset-top

  • offset-top单位为px,在pc端没问题,但在移动端就有问题了,比如你设计稿距离顶部的距离为90px,如果你直接offset-top=90,那么在手机上就会距离很远,

  • 用window.devicePixelRatio获取设备的像素,然后再进行换算,说实话不同手机上还是有差别,有的手机达到效果,有的没达到

  • 目前我是用了获取元素offsetHeight在赋值回去,如this.$refs.getheight.offsetHeight,经测试能准确达到固定的位置,

上次更新: 2021/1/29 上午11:18:53