Libon

Modern CSS Reset

4 分钟 #CSS
一个现代化 CSS 重置样式的方案

ToC

在一个从零开始的项目在搭建框架后,都会有一件要做的事,那就是:样式重置 。多年以来业内一直都在做这同样的一件事,因为在以前,各个浏览器之间的默认样式往往差距很大,所以那时候也诞生除了非常多的样式重置的方案,比如:normalize.css、reset.css 之类的,它们所做的事都是为了解决这种样式间的差异,使得开发者们能更好得去编写属于自己项目的样式代码。但 web 开发发展至今,浏览器之间的差异变得越来越小,很多属性也不再需要手动去处理,所以我认为很多重置都是多余的。我在学习的过程中记录了这些属性样式的重置方案,其中也有针对于某些特殊场景进行处理的情况,比如在偏好设置中设置了减少动画等。它可能还不够完整,也可能不太适用于每个人,所以按需取就好了,它还会不断更新。完整代码如下:

1
/* 让所有盒子的宽高不再受 padding/border 影响 */
2
*,
3
*::before,
4
*::after {
5
box-sizing: border-box;
6
}
7
8
* {
9
/*
174 collapsed lines
10
基于 calc() 计算 em 的基础行高,
11
较大的行高用于较小的字体大小,
12
较小的行高用于较大的字体大小
13
https://kittygiraudel.com/2020/05/18/using-calc-to-figure-out-optimal-line-height/
14
*/
15
line-height: calc(0.25rem + 1em + 0.25rem);
16
}
17
18
/* 移除所有默认的外边距 */
19
body,
20
h1,
21
h2,
22
h3,
23
h4,
24
p,
25
figure,
26
blockquote,
27
dl,
28
dd {
29
margin: 0;
30
}
31
32
*:not(fieldset, progress, meter) {
33
border-width: 0;
34
border-style: solid;
35
background-origin: border-box;
36
background-repeat: no-repeat;
37
}
38
39
html {
40
--color-theme: #00c483;
41
--color-danger: #ff5656;
42
/* 在应用程序中允许基于百分比的高度 */
43
block-size: 100%;
44
/* 确保文本大小仅由字体大小控制 */
45
-webkit-text-size-adjust: none;
46
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
47
Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
48
}
49
50
/* 只有在设置了 roll="list" 的时候才显示符号,防止在想要的时候但渲染不出来 */
51
ul[role="list"], ol[role="list"] {
52
list-style: none;
53
}
54
55
body {
56
min-height: 100vh;
57
line-height: 1.5;
58
/* 提高文本渲染 */
59
-webkit-font-smoothing: antialiased;
60
/* https://marco.org/2012/11/15/text-rendering-optimize-legibility */
61
text-rendering: optimizeSpeed;
62
/* 允许通过百分比设置高度 */
63
min-block-size: 100%;
64
/* https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-gutter#example_2 */
65
/* scrollbar-gutter: stable both-edges; Removed until this bug is fixed: https://bugs.chromium.org/p/chromium/issues/detail?id=1318404#c2 */
66
}
67
68
/* 如果没有设置减少动画选项 */
69
@media (prefers-reduced-motion: no-preference) {
70
/* 如果当前页面获取到了焦点,则使得滚动变得平滑 */
71
/* 如果在页面中使用 ctrl + f 搜索内容则不启用平滑滚动 */
72
html:focus-within {
73
scroll-behavior: smooth;
74
}
75
}
76
/* 如果在偏好设置里设置了减少动画,则将所有的动画、过渡加快 */
77
@media (prefers-reduced-motion: reduce) {
78
*,
79
*::before,
80
*::after {
81
animation-duration: 0.01ms !important;
82
animation-iteration-count: 1 !important;
83
transition-duration: 0.01ms !important;
84
scroll-behavior: auto !important;
85
}
86
}
87
88
img, svg, video, canvas, audio, iframe, embed, object {
89
display: block;
90
}
91
img, svg, video {
92
block-size: auto;
93
max-inline-size: 100%;
94
}
95
96
/* 使所有表单、按钮的字体于项目设置一致 */
97
:where(input,button,textarea,select) {
98
font: inherit;
99
}
100
101
/* 没有设置类名的 a 元素恢复成默认样式 */
102
a:not([class]) {
103
text-decoration-skip-ink: auto;
104
}
105
106
/* 移除描边并设置填充颜色为继承的字体颜色 */
107
:where(svg):where(:not([fill])) {
108
/* Remove fill and set stroke colour to the inherited font colour */
109
stroke: currentColor;
110
fill: none;
111
/* 让填充的线条边顶端变圆角 */
112
stroke-linecap: round;
113
stroke-linejoin: round;
114
}
115
116
/* 如果没有携带 width 则设置默认值 */
117
:where(svg):where(:not([width])) {
118
inline-size: 5rem;
119
}
120
121
/* 删除内置的表单排版样式 */
122
:where(input, button, textarea, select),
123
:where(input[type="file"])::-webkit-file-upload-button {
124
color: inherit;
125
font: inherit;
126
font-size: inherit;
127
letter-spacing: inherit;
128
word-spacing: inherit;
129
caret-color: var(--color-theme, #00c483);
130
}
131
132
a {
133
color: inherit;
134
text-decoration: none;
135
}
136
137
/* 更改文本区域的大小调整为仅垂直和仅当浏览器支持块 */
138
textarea {
139
resize: vertical;
140
}
141
@supports (resize: block) {
142
textarea {
143
resize: block;
144
}
145
}
146
147
/* 避免文本溢出 */
148
p, h1, h2, h3, h4, h5, h6 {
149
overflow-wrap: break-word;
150
}
151
152
/* 明确表示这些元素是可交互的 */
153
:where(a[href], area, button, input:not([type="text"]), label[for], select, summary, textarea, [tabindex]:not([tabindex*="-"])) {
154
cursor: pointer;
155
touch-action: manipulation;
156
accent-color: var(--color-theme, #00c483);
157
}
158
:where(input[type="file"]) {
159
cursor: auto;
160
}
161
:where(input[type="file"])::-webkit-file-upload-button,
162
:where(input[type="file"])::file-selector-button {
163
cursor: pointer;
164
}
165
166
/* 确保用户不能选择按钮文本 */
167
::placeholder,
168
button,
169
button[type],
170
input[type="button"],
171
input[type="submit"],
172
input[type="reset"],
173
input[type="file"]::-webkit-file-upload-button,
174
input[type="file"]::file-selector-button {
175
-webkit-tap-highlight-color: transparent;
176
-webkit-touch-callout: none;
177
user-select: none;
178
}
179
180
/* 禁用按钮 */
181
:where(button, button[type], input[type="button"], input[type="submit"], input[type="reset"])[disabled] {
182
cursor: not-allowed;
183
}

CD ..