纯css实现单屏滚动

最初接触到编程就是碰的前端,那时候布局还停留在float的时代,flex?grid?没听说过,现在偶尔接私单写前端发现css已经有了很大的改进,例如我们今天的猪脚,单屏滚动,你能想到几行代码就能用纯css实现吗?要不是看文档,我是不信。

本文其实要讲的是带导航的单屏滚动,是要用到js的,有人要骂了,这不标题党吗,骗我进来,为了不至于被骂我先放纯css实现的单屏滚动吧。为了方便伸手党,我索引将css啥的都写在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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>单页翻屏</title>
<style>
* {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block
}

body {
line-height: 1
}

ol,
ul {
list-style: none
}

blockquote,
q {
quotes: none
}

blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none
}

table {
border-collapse: collapse;
border-spacing: 0
}

main {
height: 100vh;
overflow-y: auto;
-ms-scroll-snap-type: y mandatory;
scroll-snap-type: y mandatory;
-webkit-overflow-scrolling: touch;
}

.section {
height: 100vh;
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
font-size: 2rem;
scroll-snap-align: start;
}

.section-1 {
background-color: #d1c4e9;
}

.section-2 {
background-color: #c8e6c9;
}

.section-3 {
background-color: #b3e5fc;
}

.section-4 {
background-color: #f0f4c3;
}

.section-5 {
background-color: #ffccbc;
}

</style>
</head>
<body>


<main id="main">
<section class="section section-1">
<h2>Section 1</h2>
</section>
<section class="section section-2">
<h2>Section 2</h2>
</section>
<section class="section section-3">
<h2>Section 3</h2>
</section>
<section class="section section-4">
<h2>Section 4</h2>
</section>
<section class="section section-5">
<h2>Section 5</h2>
</section>
</main>
</body>
</html>

看效果了啊。

有的同学又抱怨了,实现是可以实现,但实际应用中并没有卵用啊,不可以手动控制切换的单屏滚动都是扯淡,好吧,同学你赢了,如果要加上导航,是真的真的要借助js了,代码都给你了,就别再骂我了好吗?

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>单页翻屏</title>
<style>
*{
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block
}

body {
line-height: 1
}

ol,
ul {
list-style: none
}

blockquote,
q {
quotes: none
}

blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none
}

table {
border-collapse: collapse;
border-spacing: 0
}

main {
height: 100vh;
overflow-y: auto;
-ms-scroll-snap-type: y mandatory;
scroll-snap-type: y mandatory;
-webkit-overflow-scrolling: touch;
}

.section {
height: 100vh;
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
font-size: 2rem;
scroll-snap-align: start;
}

.section-1 {
background-color: #d1c4e9;
}

.section-2 {
background-color: #c8e6c9;
}

.section-3 {
background-color: #b3e5fc;
}

.section-4 {
background-color: #f0f4c3;
}

.section-5 {
background-color: #ffccbc;
}

body {
font-family: Lato, sans-serif;
}

.wrapper {
max-width: 800px;
margin-left: auto;
margin-right: auto;
padding-left: 1rem;
padding-right: 1rem;
}

.page-nav {
position: absolute;
right: 0;
top: 50%;
width: 25px;
transform: translate(0, -50%);
}

.page-nav>div {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #0F0F0F;
margin: 10px auto;
}

.page-nav .page-active {
background-color: #761C19;
width: 15px;
height: 15px;
margin: 10px auto;
}
</style>
</head>
<body>


<main id="main">
<section class="section section-1">
<h2>Section 1</h2>
</section>
<section class="section section-2">
<h2>Section 2</h2>
</section>
<section class="section section-3">
<h2>Section 3</h2>
</section>
<section class="section section-4">
<h2>Section 4</h2>
</section>
<section class="section section-5">
<h2>Section 5</h2>
</section>
</main>

<script type="text/javascript">
class Slide {
// 构造方法
constructor() {
this.box = document.getElementById('main')
// 页面数
this.page_nums = this.box.children.length
// 当前页面索引
this.current_index = 0
}
// 初始化轮播
init() {
var that = this;
// 监听鼠标滑轮滚动,是否翻屏
this.box.addEventListener('scroll', function() {
// 父元素距离顶部的高度除以页面的高度即当前在第几页
that.current_index = Math.floor(this.scrollTop / this.clientHeight)
// 清空其他导航选中状态
that.clear_artive_nav()
})

}
// 高亮当前导航
clear_artive_nav() {
// 循环导航元素
this.page_nav.childNodes.forEach((item, index) => {
// 清空每个元素的class属性
item.removeAttribute('class')
// 如果当前页码索引等于当前导航索引则高亮当前导航
if (this.current_index == index) {
item.setAttribute('class', 'page-active')
}
})
}
// 创建切换导航
create_nav() {
var that = this
// 创建页面导航
this.page_nav = document.createElement("div");
// 为导航父元素设置class属性
this.page_nav.setAttribute('class', 'page-nav')
// 循环页面数量,即创建与页面数量相同的导航元素
for (let i = 0; i < this.page_nums; i++) {
// 创建子元素
let page_nav_item = document.createElement("div")
// 第一个元素设为默认选中
if (i == 0) {
page_nav_item.setAttribute('class', 'page-active')
}
// 添加到父元素
this.page_nav.appendChild(page_nav_item)
}
// 添加导航的body元素的最后
document.body.appendChild(this.page_nav)

// 监听点击翻页导航
this.page_nav.childNodes.forEach((item, index) => {
// 监听当前导航的点击事件
item.addEventListener('click', function() {
// 当前页面索引设为点击的导航索引
that.current_index = index
// 页面也跟随切换到指定索引
that.box.scrollTo({
top: that.box.clientHeight * index,
behavior: "smooth"
})

})
})
}
}
var page = new Slide();
// 初始化
page.init();
// 创建导航元素
page.create_nav();
</script>
</body>
</html>

再看下效果