HTML

语义

HTML5 为我们提供了许多语义元素,旨在精确描述内容。确保你受益于它丰富的词汇。

<!-- bad -->
<div id=main>
  <div class=article>
    <div class=header>
      <h1>Blog post</h1>
      <p>Published: <span>21st Feb, 2015</span></p>
    </div>
    <p>…</p>
  </div>
</div>

<!-- good -->
<main>
  <article>
    <header>
      <h1>Blog post</h1>
      <p>Published: <time datetime=2015-02-21>21st Feb, 2015</time></p>
    </header>
    <p>…</p>
  </article>
</main>

确保您了解正在使用的元素的语义。用错误的方式使用语义元素比保持中立更糟糕。

<!-- bad -->
<h1>
  <figure>
    <img alt=Company src=logo.png>
  </figure>
</h1>
 
<!-- good -->
<h1>
  <img alt=Company src=logo.png>
</h1>

简洁

保持代码简洁。忘记你旧的XHTML习惯。

<!-- bad -->
<!doctype html>
<html lang=en>
  <head>
    <meta http-equiv=Content-Type content="text/html; charset=utf-8" />
    <title>Contact</title>
    <link rel=stylesheet href=style.css type=text/css />
  </head>
  <body>
    <h1>Contact me</h1>
    <label>
      Email address:
      <input type=email placeholder=you@email.com required=required />
    </label>
    <script src=main.js type=text/javascript></script>
  </body>
</html>

<!-- good -->
<!doctype html>
<html lang=en>
  <meta charset=utf-8>
  <title>Contact</title>
  <link rel=stylesheet href=style.css>
  <h1>Contact me</h1>
  <label>
    Email address:
    <input type=email placeholder=you@email.com required>
  </label>
  <script src=main.js></script>
</html>

辅助功能

辅助功能不应该是事后考虑的。您不必是 WCAG 专家来改进您的网站,您可以立即开始修复能带来巨大变化的小事情,例如:

  • 学习正确使用属性alt
  • 确保您的链接和按钮被标记为此类(无暴行)
  • 不完全依靠颜色来传达信息
  • 明确标记表单控件

    img alt=Logo src=logo.png

    img alt=Company src=logo.pn

语言和字符编码

虽然定义语言是可选的,但建议始终在根元素上声明它。

HTML 标准要求页面使用 UTF-8 字符编码。必须声明它,虽然可以在内容类型 HTTP 标头中声明它,但建议始终在文档级别声明它。

<!-- bad -->
<!doctype html>
<title>Hello, world.</title>

<!-- good -->
<!doctype html>
<html lang=en>
  <meta charset=utf-8>
  <title>Hello, world.</title>
</html>

性能

除非在内容之前加载脚本有正当理由,否则不要阻止页面的呈现。如果样式表很重,请隔离最初绝对必需的样式,并推迟在单独的样式表中加载辅助声明。两个 HTTP 请求明显慢于一个请求,但速度感知是最重要的因素。

<!-- bad -->
<!doctype html>
<meta charset=utf-8>
<script src=analytics.js></script>
<title>Hello, world.</title>
<p>...</p>

<!-- good -->
<!doctype html>
<meta charset=utf-8>
<title>Hello, world.</title>
<p>...</p>
<script src=analytics.js></script>

CSS

分号

虽然分号在技术上是 CSS 中的分隔符,但始终将其视为终止符。

/* bad */
div {
  color: red
}

/* good */
div {
  color: red;
}

箱模型

理想情况下,整个文档的框模型应相同。全局是好的,但如果可以避免,则不要更改特定元素上的默认框模型。* { box-sizing: border-box; }

/* bad */
div {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;
}

/* good */
div {
  padding: 10px;
}

Flow

如果可以避免元素的默认行为,请不要更改它。尽可能多地将元素保留在自然文档流中。例如,删除图像下方的空白不应使您更改其默认显示:

/* bad */
img {
  display: block;
}
 
/* good */
img {
  vertical-align: middle;
}

同样,如果可以避免元素,请不要从流中取下元素。

/* bad */
div {
  width: 100px;
  position: absolute;
  right: 0;
}

/* good */
div {
  width: 100px;
  margin-left: auto;
}

定位

有许多方法可以定位 CSS 中的元素。青睐现代布局规范(如 Flexbox 和 Grid),并避免从普通文档流中删除元素,例如使用 。position: absolute
选择

最小化与 DOM 紧密耦合的选择器。考虑在选择器超过 3 个结构伪类、后代或同级组合器时,将类添加到要匹配的元素。

/* bad */
div:first-of-type :last-child > p ~ *

/* good */
div:first-of-type .info

避免在不需要时使选择器过载。

/* bad */
img[src$=svg], ul > li:first-child {
  opacity: 0;
}

/* good */
[src$=svg], ul > :first-child {
  opacity: 0;
}

特 异性

不要使值和选择器难以覆盖。尽量减少 的 和 的 使用。id!important

/* bad */
.bar {
  color: green !important;
}
.foo {
  color: red;
}

/* good */
.foo.bar {
  color: green;
}
.foo {
  color: red;
}

重写

重写样式使选择器和调试更加困难。尽可能避免。

/* bad */
li {
  visibility: hidden;
}
li:first-child {
  visibility: visible;
}

/* good */
li + li {
  visibility: hidden;
}

继承

不要复制可以继承的样式声明。

/* bad */
div h1, div p {
  text-shadow: 0 1px 0 #fff;
}

/* good */
div {
  text-shadow: 0 1px 0 #fff;
}

简洁

保持代码简洁。使用速记属性,避免在不需要时使用多个属性。

/* bad */
div {
  transition: all 1s;
  top: 50%;
  margin-top: -10px;
  padding-top: 5px;
  padding-right: 10px;
  padding-bottom: 20px;
  padding-left: 10px;
}

/* good */
div {
  transition: 1s;
  top: calc(50% - 10px);
  padding: 5px 10px 20px;
}

语言

比起数学,更喜欢英语。

/* bad */
:nth-child(2n + 1) {
  transform: rotate(360deg);
}

/* good */
:nth-child(odd) {
  transform: rotate(1turn);
}

供应商前缀

积极终止过时的供应商前缀。如果需要使用它们,请在标准属性之前插入它们。

/* bad */
div {
  transform: scale(2);
  -webkit-transform: scale(2);
  -moz-transform: scale(2);
  -ms-transform: scale(2);
  transition: 1s;
  -webkit-transition: 1s;
  -moz-transition: 1s;
  -ms-transition: 1s;
}

/* good */
div {
  -webkit-transform: scale(2);
  transform: scale(2);
  transition: 1s;
}

动画

有利于转换而不是动画。避免对 和 以外的其他属性进行动画处理。opacitytransform

/* bad */
div:hover {
  animation: move 1s forwards;
}
@keyframes move {
  100% {
    margin-left: 100px;
  }
}

/* good */
div:hover {
  transition: 1s;
  transform: translateX(100px);
}

单位

可以时使用无单位值。如果您使用相对单位,则有利。首选秒数而不是毫秒。rem

/* bad */
div {
  margin: 0px;
  font-size: .9em;
  line-height: 22px;
  transition: 500ms;
}

/* good */
div {
  margin: 0;
  font-size: .9rem;
  line-height: 1.5;
  transition: .5s;
}

颜色

如果需要透明度,请使用 。否则,始终使用十六进制格式。rgba

/* bad */
div {
  color: hsl(103, 54%, 43%);
}

/* good */
div {
  color: #5a3;
}

绘图

当资源易于使用 CSS 进行复制时,请避免 HTTP 请求。

/* bad */
div::before {
  content: url(white-circle.svg);
}

/* good */
div::before {
  content: "";
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
}

Hack

不要使用它们。

/* bad */
div {
  // position: relative;
  transform: translateZ(0);
}

/* good */
div {
  /* position: relative; */
  will-change: transform;
}

常用语义标签使用解析

无序列表 UL

并不是所有的并列关系的数据都要使用到ul无序列表,ul他大多数出现在行文中间,也就是在ul的上部,我们一般会有文字说明,如列举一些选项啥的。

所以,对于语义标签,我的态度是:‘“用对" 比“不用” 好,“不用" 比“用错”好。当然了,我觉得有理想的前端工程师还是应该去追求“用对”它们。

所以,有时候用其他元素替换ul,反倒可以减少冗余的标签。

EM强调倾斜和STRONG强调加粗

em可能常常和strong标签概念混淆,而strong的大量使用,其实原因就是他不倾斜,文本加粗,在日常使用中,这种情况更多一些,即便可以用em,我们也不想多书写一条重置样式的css而去使用em

而em的代表了这个文字是重音,所以从理解上可以这么去读:em会对文本含义有改变作用,类似于读一段话时,里面的重音部分,重点部分。

我吃了一个<em>苹果</em>
我吃了<em>一个</em>苹果

两句话,不同的重音意思也不一样。

第一句突出我吃的是苹果

第二句突出我只吃了一个

所以文字的重音其实和strong是完全不一样的。

那么strong又是什么意思?

strong表达的是文本的重要性、严重性和紧急性等

比如:一条重要的通知,一个特别的价格,一段不能忽视的文本,这个作用着重于强调重要性,对文本的理解并不会产生语义上的变化。他更多的是一个作用。

这里说的比较绕,仔细理解下就会明白。

标题和HGROUP

h1-h6是不同层级的标题,不同层级的标题按照顺序排列,我们可以生成目录树的结构

<h1>一级目录</h1>
<p>一级目录介绍</p>
<h2>二级目录</h2>
<p>二级目录介绍</p>
<h2>二级目录</h2>
<p>二级目录介绍</p>

他会生成如下格式的目录:

一级目录

二级目录
二级目录
这种是最基本的标题,而当我们的标题出现副标题的时候,其实很多人会使用span啊,这种行内元素,但其实html5已经考虑到这种情况,给了一个hgroup元素。

<hgroup>
  <h1>标题</h1>
  <h2>副标题</h2>
  <p>其他内容</p>
</hgroup>

他会生成如下格式目录:

标题 - 副标题

其他内容
可以看到,在hgroup中,h1-h6被视为标题的组成部分,而不是独立标题。

为什么会生成这种目录结构

html标准中专门规定了生成目录结构的算法,所以说,即便我们不打算深入,也应该尽量在大的层面上保证这些元素的语义化使用。

SECTION元素

section不仅仅是一个有语义的div标签,虽然大部分时候,我们对他的理解是混淆的,但是它会改变h1-h6的语义。

在section元素中,标题元素h1-h6会下降一级。

也因此,我们只需要section和h1-h6就足以形成文档的树形结构。

<section>
  <h1>section的语义</h1>
  <p>xxxx</p>
  <section>
    <h1>语义1</h1>
    <p>xxxx</p>
  </section>
  <section>
    <h1>语义2</h1>
    <p>xxxx</p>
  </section>
</section>

生成:

section的语义

语义1
语义2
section表示的是一个内容的区块,区域,比如内容章节区块,页眉,页脚。

section容易和article混淆,在原则上,能用section就能用article,但是如果情景上article更合适,那么就应该使用article。

那么什么情形使用article更合适?

一篇博客文章的文章部分,包含标题,内容等

论坛的帖子文章

单条评论部分

等等...

ARTICLE

我们需要明确article内容的独立性,该内容本身独立于上下文,即便是周围所有的内容被移掉,也不会影响该内容的阅读。

在article中,可以存在header和footer,这两个标签语义就是头部和底部。

这种也适合拿来做博客的mini文章卡片展示。

针对 section和artcle,dive,我们可以按照以下原则:

内容是否独立完整,是,用article;
如果该内容上下文相关,考虑使用section;
仅仅是个块内容,使用div。

HEADER和FOOTER

header: 如其名,常出现在头部,表示导航或者介绍性内容

footer: 通常出现在底部,包含一些作者信息,相关链接,版权信息

header和footer-般都是放在article或者body的直接子元素,但是标准中并没有明确规定,footer也 可以和aside, nav, section相关联 ( header不存在关联问题)。

ASIDE

可以理解为侧边栏,实际上aside可以是侧边栏,但不仅仅是侧边栏。

aside中的导航,虽然和header一样都可以有nav,但是,aside的导航一般是一些相关性的导航,最典型的就是博客的侧边栏了,什么相关文章啊,tag标签云啊,这些。

ADDRESS

footer中一般包含address标签,这是个非常容易被误用的标签,address用于表示文章的联系方式或作者的联系方式,它明确的只关联article和body元素。

HTML 的<address>元素可以让作者为它最近的<article>或者<body>祖先元素提供联系信息。在后一种情况下,它应用于整个文档。

当表示一个和联系信息无关的任意的地址时,使用<p>元素而不是<address>元素。
这个元素不能包含除了联系信息之外的任何信息,比如出版日期(这应该包含在<time>元素中)。
通常,<address>元素可以放在当前section的<footer>元素中,如果存在的话。
TIME

time标签用于表示时间,方便机器抓取理解

例子:

<time itemprop="date" datetime="2016-08-12">下一周</time>

ADDR

addr用于表示缩写

<abbr title= "World Wide Web ">WWW</ abbr>

HR

hr表示的是故事走向的转变或者话题的转变,类似于这篇文章已经完事了,或者讲的内容不同了,就用hr进行分隔。

像那种主标题和副标题之间有横线的,那种就用border实现,因为他只是个样式,内容是没有发生转变。

BLOCKQUOTE、Q、CITE

cite 用于作品名称的引述,如果某药物名啊,某文章标题啊,这种。

blockquote 用于表示一大段引述的内容,比如你从别人的文章里copy的文字,就应该是使用该标签表示

q 在本质上与 blockquote标签是一样的。不同之处在于它们的显示和应用。<q> 标签用于简短的行内引用。如果需要从周围内容分离出来比较长的部分(通常显示为缩进的块),请使用 <blockquote> 标签。

q元素会给文本加上引号

FIGURE、FIGCAPTION

用于表示与主文章相关的图像,照片流等,比如文章的说明插图,医学文章的示例图等等这种

figcaption表示的是内容的标题,比如图片的名字,当然也可以没有标题。

<figure>
  <img src="https://.... .440px-NeXTcube_ first_ webserver . JPG"/>
  <figcaption>The NeXT Computer used by Tim Berners-Lee at CERN. </ figcaption>
</figure>

DFN

dfn用于包裹一个被定义的词汇,比如:

<dnf>Internet </dnf>是一个由相互连接的计算机网络组成的全球系统。

Internet 是一个被定义的词汇,他表示是一个由相互连接的计算机网络组成的全球系统

<dfn>万维网</dfn>是文档和其他资源的全球集合,它们相互链接

万维网也是一个被定义的词汇

也可以简单理解为,如果这个名词我们需要后面进行解释,那么这个名词就需要被dfn包裹。

NAV、UL、OL

nav表示的是一个导航,导航里面可以有ul或者ol,而ul和ol的区别就在于内容是否有顺序关系,有顺序使用ol,无顺序ul

无论使用ol还是ul,不要因为默认的视觉的效果,也就是默认样式,而去改变本身的语义而去使用。

比如: 一个本来是有序列表的关系,但是要显示无序列表的样式,我们不能使用ul,而是ol,然后用css去调整默认样式。

PRE、SAMP、CODE

pre表示格式化文本,不需要浏览器进行格式化,如换行,空格

而pre常常作为格式化文本的容器,里面包裹samp或者code元素

samp: 表示系统的输出,比如 shell 、浏览器控制台等的输出,除了放在pre中使用,本身也可以作为行内高亮使用,虽然默认样式和普通文本没啥区别

code则表示计算机代码,也可以行内表示

其他的一些标签

标签 说明
small 之前表示字体缩小的废弃标签,HTML5救回来表示补充评论。
s 之前表示划线的废弃标签,HTML5救回来表示错误的内容,经常用于电商领
域表示打折前的价格。
i 之前表示斜体的废弃标签,HTML5救回来表示读的时候变调。
b 之前表示黑体的废弃标签,HTML5救回来表示关键字。
u 之前表示下划线的废弃标签,HTML .5救回来表示避免歧义的注记。
data 跟time标签类似,给机器阅读的内容,意义广泛,可以自由定义。
var 变量,多用于计算机和数学领域。
kbd 用户输入,表示键盘按键居多。
sub 下标,多用于化学/物理/数学领域。
sup 下标,多用于化学/物理/数学领域。
bdi,bdo 用于多语言混合时指定语言或者书写方向(左到右或者右到左)。
mark 表示高亮,这里并非指显示为高亮,而是从读者角度希望的高亮(注意与strong的区分)
wbr 表示可以换行的位置,主要是英文等文字不允许单词中间换行,这个标签一般在把多个单词粘成很长的单词时候用。
menu ul的变体,用于功能菜单时使用。
dl,dd,dt 一般出现较为严肃的文章,对一些术语进行定义,dt和dd其实并不总是成对出,两者是多对多的关系.
main 整个页面只出现一个,表示页面的主要内容,可以理解为特殊的div
尽量只用自己熟悉的语义标签,并且只在有把握的场景引入语义标签。

部分来自:Github 翻译待整理;还有些出处找不到源头。