CSS 编码原则
by Ash Norseman
尽可能减少重复代码
不要写死
以下是一个正常的button
样式,看似完美地实现了设计稿。
button {
background: salmon linear-gradient(lightSalmon, salmon);
border: 1px solid indianRed;
border-radius: 4px;
box-shadow: 0 1px 5px salmon;
color: white;
font-size: 20px;
line-height: 30px;
padding: 6px 16px;
text-shadow: 0 -1px 1px fireBrick;
}
然则问题在于:当修改字体的时候,行高也要同时修改。padding
和border-radius
也变得不合时宜。
原则:如果有相互依赖的值,尽量在代码中体现出他们的关系。
button {
// 依赖于字体的长度值,用 em 体现
border-radius: 0.2em;
box-shadow: 0 0.05em 0.25em salmon;
// 用百分比或`em`来定义字体,当父元素字体变化的时候,可以随之改变
font-size: 1.25em;
line-height: 1.5;
padding: 0.3em 0.8em;
text-shadow: 0 -0.05em 0.05em fireBrick;
}
注意rem
和em
的区别。使用哪个单位,取决于字体大小所依赖的对象是根元素还是父元素。
进一步优化:考虑阴影在其他底色下的显示,使用纯黑/纯白叠加透明度的实现。
button {
// 底色叠加白色 -> 透明的蒙版
background: salmon linear-gradient(rgba(255, 255, 255, 0.2), transparent);
// 边框则是黑丝效果
border: 1px solid rgba(0, 0, 0, 0.1);
// 按钮底部的颜色应更深一些
border-bottom-color: rgba(0, 0, 0, 0.3);
box-shadow: 0 0.05em .25em rgba(0, 0, 0, 0.5);
text-shadow: 0 -0.05em 0.05em rgba(0, 0, 0, 0.5);
}
在添加其他颜色按钮的时候,只需更改background-color
即可。
button.ok {
background-color: mediumSeaGreen;
}
button.cancel {
background-color: crimson;
}
简洁 vs 可维护性
这两点有时互相冲突。今天写的少,不代表将来改动少。
button {
// 一行代码搞定,但如果要修改边框宽度,需修改三个值
border-width: 10px 10px 10px 0;
// 多行代码,但只需修改一处,而且更清晰
border-width: 10px;
border-left-width: 0;
}
currentColor
关键字,等于元素color
属性的值。
这个关键词有时用的不知不觉,比如在设置border
的时候很常见:border: 1px solid;
,自动采用前景色为边框颜色。
hr {
background: currentColor;
border: 0;
height: 0.5em;
}
属性继承
关键字inherit
:父元素的计算值。
// 令表单元素继承正文字体
button,
input,
select {
font: inherit;
}
// 令 a 元素继承正文颜色
a {
color: inherit;
}
悬浮气泡上的三角形,继承气泡的背景和边框:
.tool-tip {
background-color: salmon;
border: 1px solid rgba(0, 0, 0, 0.5);
color: white;
padding: 0.25em 0.5em;
position: relative;
width: 30%;
}
.tool-tip::before {
background: inherit;
border: inherit;
border-right: 0;
border-bottom: 0;
content: " ";
padding: 0.35em;
position: absolute;
top: -0.4em;
left: 1em;
transform: rotate(45deg);
}
一键添加错误提示框:
.tool-tip.error {
background: crimson;
}
响应式设计
错误的做法:发现问题,就添加 Media Query。导致项目中充满着 Media Query。改动代码时,容易遗漏。
原则:只有尝试了所有方案都不能使元素自适应的时候,再考虑添加 Media Query。
- 用百分比定义宽度,不要写死
- 不能用百分比的时候,考虑视口相关的单位:
vw, vh, vmin, vmax
- 为替换元素(
img, input, select, textarea, object, video, iframe
等)设置max-width: 100%
- 需要背景图片覆盖整个元素的时候,设置
background-size: cover
不滥用属性缩写
background
、font
等缩写很有用,但有时会产生一些副作用。
div {
// 同时覆盖了 background-image 等值
background: salmon;
// 只设置颜色
background-color: salmon;
}
缩写和单个属性可以结合使用,关键是明确缩写会覆盖什么值。
div {
// 重复设置了 background-size 和 background-repeat
background:
url(tr.png) no-repeat top right / 2em 2em,
url(br.png) no-repeat bottom right / 2em 2em,
url(bl.png) no-repeat bottom left / 2em 2em;
// 合理拆分
background:
url(tr.png) top right,
url(br.png) bottom right,
url(bl.png) bottom left;
background-size: 2em 2em;
background-repeat: no-repeat;
}