使用 overflow-scrolling 支持弹性滚动
要点:iOS 页面非 body
元素的滚动操作会非常卡(Android 不会出现此情况),通过 overflow-scrolling: touch
调用 Safari 原生滚动来支持弹性滚动,增加页面滚动的流畅度
场景:iOS 页面滚动
兼容:iOS 自带 -webkit-overflow-scrolling
body {
-webkit-overflow-scrolling: touch;
}
.elem {
overflow: auto;
}
2
3
4
5
6
使用 transform 启动 GPU 硬件加速
要点:有时执行动画可能会导致页面卡顿,可在特定元素中使用硬件加速来避免这个问题
场景:动画元素(绝对定位、同级中超过 6 个以上使用动画)
兼容:transform
.elem {
transform: translate3d(0, 0, 0); /* translateZ(0)亦可 */
}
2
3
使用 attr()抓取 data-*
要点:在标签上自定义属性 data-*
,通过 attr()
获取其内容赋值到 content
上
场景:提示框
兼容:data-*
、attr()
代码:在线演示
.tips {
position: relative;
margin-top: 10px;
padding: 0 20px;
border-radius: 10px;
height: 40px;
background-color: $purple;
line-height: 40px;
color: #fff;
&::after {
position: absolute;
left: 0;
top: 0;
border-radius: 5px;
width: 100%;
height: 100%;
background-color: rgba(#000, .5);
opacity: 0;
text-align: center;
font-size: 12px;
content: attr(data-msg);
transition: all 300ms;
}
&:first-child {
margin-top: 0;
}
&:hover::after {
left: calc(100% + 20px);
opacity: 1;
}
&[href]:empty::before {
content: attr(href);
}
&[href]:empty:hover::after {
display: none;
}
}
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
使用:valid 和:invalid 校验表单
要点:<input>
使用伪类 :valid
和 :invalid
配合 pattern
校验表单输入的内容
场景:表单校验
兼容:pattern
、:valid
、:invalid
代码:在线演示
.form-validation {
width: 500px;
div {
margin-top: 10px;
&:first-child {
margin-top: 0;
}
}
label {
display: block;
padding-bottom: 5px;
font-weight: bold;
font-size: 16px;
}
input,
textarea {
display: block;
padding: 0 20px;
outline: none;
border: 1px solid #ccc;
width: 100%;
height: 40px;
caret-color: $blue;
transition: all 300ms;
&:valid {
border-color: $green;
box-shadow: inset 5px 0 0 $green;
}
&:invalid {
border-color: $red;
box-shadow: inset 5px 0 0 $red;
}
}
textarea {
height: 122px;
resize: none;
line-height: 30px;
font-size: 16px;
}
}
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
使用 pointer-events 禁用事件触发
要点:通过 pointer-events:none
禁用事件触发(默认事件、冒泡事件、鼠标事件、键盘事件等),相当于<button>
的 disabled
场景:限时点击按钮(发送验证码倒计时)、事件冒泡禁用(多个元素重叠且自带事件、a 标签跳转)
兼容:pointer-events
代码:在线演示
.disabled-trigger {
padding: 0 20px;
border-radius: 10px;
height: 40px;
background-color: $purple;
pointer-events: none;
line-height: 40px;
color: #fff;
}
2
3
4
5
6
7
8
9
使用+或~美化选项框
要点:<label>
使用 +
或 ~
配合 for
绑定 radio
或 checkbox
的选择行为
场景:选项框美化、选中项增加选中样式
兼容:+、~
代码:在线演示
.beauty-selection {
display: flex;
li {
display: flex;
align-items: center;
margin-left: 20px;
&:first-child {
margin-left: 0;
}
}
input:checked + label {
background-color: $orange;
}
label {
margin-right: 5px;
padding: 2px;
border: 1px solid $orange;
border-radius: 100%;
width: 18px;
height: 18px;
background-clip: content-box;
cursor: pointer;
transition: all 300ms;
&:hover {
border-color: $blue;
background-color: $blue;
box-shadow: 0 0 7px $blue;
}
}
span {
font-size: 16px;
}
}
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
使用:focus-within 分发冒泡响应
要点:表单控件触发 focus
和 blur
事件后往父元素进行冒泡,在父元素上通过 :focus-within
捕获该冒泡事件来设置样式
场景:登录注册弹框、表单校验、离屏导航、导航切换
兼容::focus-within
、:placeholder-shown
代码:在线演示
.bruce {
background-color: #999;
}
.bubble-distribution {
position: relative;
margin-top: 50px;
padding: 25px;
border-radius: 2px;
width: 320px;
background-color: #fff;
h3 {
font-weight: bold;
font-size: 16px;
color: #333;
}
div {
margin-top: 10px;
}
img {
position: absolute;
left: 50%;
bottom: 100%;
margin: 0 0 -20px -60px;
width: 120px;
}
ul {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
height: 30px;
line-height: 30px;
}
li {
position: relative;
width: 45%;
transition: all 300ms;
&:focus-within {
background: linear-gradient(90deg, $blue 50%, transparent 0) repeat-x,
linear-gradient(90deg, $blue 50%, transparent 0) repeat-x,
linear-gradient(0deg, $blue 50%, transparent 0) repeat-y,
linear-gradient(0deg, $blue 50%, transparent 0) repeat-y;
background-position: 0 0, 0 100%, 0 0, 100% 0;
background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px;
animation: move 500ms infinite linear;
}
}
input[type=text],
input[type=password] {
padding: 10px;
outline: none;
border: 1px solid #e9e9e9;
border-radius: 2px;
width: 100%;
height: 40px;
transition: all 300ms;
&:focus:valid {
border-color: $blue;
}
&:focus:invalid {
border-color: $red;
}
}
input[type=radio] {
position: absolute;
width: 0;
height: 0;
&:checked + label {
border: 3px solid transparent;
background-color: $blue;
color: #fff;
}
}
label {
display: block;
border-bottom: 1px solid #ccc;
width: 100%;
background-clip: padding-box;
cursor: pointer;
text-align: center;
transition: all 300ms;
}
button {
overflow: hidden;
margin-top: 10px;
outline: none;
border: none;
border-radius: 2px;
width: 100%;
height: 40px;
background-color: $blue;
cursor: pointer;
color: #fff;
transition: all 300ms;
}
}
.accout,
.password,
.code {
img {
display: none;
margin-bottom: -27px;
}
&:focus-within {
img {
display: block;
}
& ~ img {
display: none;
}
}
}
.code {
display: flex;
justify-content: space-between;
button {
margin-top: 0;
}
input {
&:not(:placeholder-shown) {
width: 70%;
& + button {
width: 25%;
}
}
&:placeholder-shown {
width: 100%;
& + button {
width: 0;
opacity: 0;
}
}
}
}
@keyframes move {
to {
background-position: 6% 0, -6% 100%, 0 -6%, 100% 6%;
}
}
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
使用:hover 描绘鼠标跟随
要点:将整个页面等比划分成小的单元格,每个单元格监听 :hover
,通过 :hover
触发单元格的样式变化来描绘鼠标运动轨迹
场景:鼠标跟随轨迹、水波纹、怪圈
兼容::hover
代码:在线演示
@function randomNum($max, $min: 0, $u: 1) {
@return ($min + random($max)) * $u;
}
.mouse-following {
display: flex;
overflow: hidden;
flex-wrap: wrap;
height: 100%;
cursor: pointer;
li {
position: relative;
width: 30px;
height: 30px;
&::before {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
border-radius: 100%;
background-color: transparent;
content: "";
transform: scale3d(.1, .1, 1);
transition: all 500ms ease-in;
}
&:hover {
&::before {
transform: scale3d(1.8, 1.8, 1.8);
transition: transform 0s;
}
}
@for $i from 1 through 500 {
&:nth-child(#{$i}):hover {
&::before {
background-color: rgba(randomNum(255), randomNum(255), randomNum(255), .8);
}
}
}
}
}
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
使用 max-height 切换自动高度
要点:通过 max-height
定义收起的最小高度和展开的最大高度,设置两者间的过渡切换
场景:隐藏式子导航栏、悬浮式折叠面板
兼容:max-height
代码:在线演示
.auto-height {
width: 300px;
li {
margin-top: 5px;
cursor: pointer;
&:first-child {
margin-top: 0;
}
&:hover p {
border-bottom-width: 1px;
max-height: 600px;
}
}
h3 {
padding: 0 20px;
height: 40px;
background-color: $red;
cursor: pointer;
line-height: 40px;
font-size: 16px;
color: #fff;
}
p {
overflow: hidden;
padding: 0 20px;
border: 1px solid $red;
border-top: none;
border-bottom-width: 0;
max-height: 0;
line-height: 30px;
transition: all 500ms;
}
}
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
使用 transform 模拟视差滚动
要点:通过 background-attachment: fixed
或 transform
让多层背景以不同的速度移动,形成立体的运动效果
场景:页面滚动、视差滚动文字阴影、视差滚动文字虚影
兼容:background-attachment
、transform
代码:在线演示
$bg: "https://yangzw.vip/static/codepen/bg.jpg";
.bruce {
overflow: auto;
perspective: 1px;
transform-style: preserve-3d;
p {
height: 300px;
line-height: 300px;
text-align: center;
font-size: 20px;
color: $red;
}
}
.parallax-scrolling {
display: flex;
justify-content: center;
align-items: center;
height: 1000px;
background: url($bg) no-repeat center fixed;
li {
width: 500px;
text-align: center;
font-weight: bold;
font-size: 60px;
&:nth-child(1) {
color: $red;
transform: translateZ(-1px);
}
&:nth-child(2) {
color: $blue;
transform: translateZ(-2px);
}
&:nth-child(3) {
color: $green;
transform: translateZ(-3px);
}
}
}
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
使用 animation-delay 保留动画起始帧
要点:通过 transform-delay
或 animation-delay
设置负值时延保留动画起始帧,让动画进入页面不用等待即可运行
场景:开场动画
兼容:transform
、animation
代码:在线演示
.initial-keyframe {
position: relative;
width: 100px;
height: 100px;
li {
position: absolute;
border-radius: 100%;
width: 100%;
height: 100%;
background-color: $green;
transform: rotate(0) translate(-80px, 0);
animation: rotate 3s linear infinite;
&:nth-child(2) {
animation-delay: -1s;
}
&:nth-child(3) {
animation-delay: -2s;
}
}
}
@keyframes rotate {
to {
transform: rotate(1turn) translate(-80px, 0);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
使用 resize 拉伸分栏
要点:通过 resize
设置横向自由拉伸来调整目标元素的宽度
场景:富文本编辑器、分栏阅读
兼容:resize
代码:在线演示
.stretching-column {
overflow: hidden;
border: 1px solid $blue;
width: 600px;
height: 300px;
line-height: 20px;
font-size: 16px;
color: $orange;
.left {
overflow: hidden;
float: left;
position: relative;
height: 100%;
}
.right {
overflow: hidden;
padding: 10px;
height: 100%;
background-color: #f0f0f0;
word-break: break-all;
}
}
.resize-bar {
overflow: scroll;
width: 200px;
height: 100%;
opacity: 0;
resize: horizontal;
&::-webkit-scrollbar {
width: 200px;
height: 100%;
}
&:hover,
&:active {
& ~ .resize-line {
border-left: 1px dashed $blue;
}
}
}
.resize-line {
position: absolute;
right: 0;
top: 0;
bottom: 0;
border-left: 1px solid #ccc;
border-right: 2px solid #f0f0f0;
pointer-events: none;
}
.resize-text {
overflow-x: hidden;
position: absolute;
left: 0;
right: 5px;
top: 0;
bottom: 0;
padding: 10px;
word-break: break-all;
}
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
PS:本文整理自 https://juejin.im/post/5d4d0ec651882549594e7293 侵删。