代码示例

尽可能减少重复代码

不要写死

以下是一个正常的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;
}

然则问题在于:当修改字体的时候,行高也要同时修改。paddingborder-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;
}

注意remem的区别。使用哪个单位,取决于字体大小所依赖的对象是根元素还是父元素。

进一步优化:考虑阴影在其他底色下的显示,使用纯黑/纯白叠加透明度的实现。

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

不滥用属性缩写

backgroundfont等缩写很有用,但有时会产生一些副作用。

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;
}