学习 CSS 时忽视的几个知识点

Things I Wish I’d Known About CSS

文章的作者以老式的方式构建网站:查看网站源代码、复制然后修改,而没有经过阅读书籍等系统性的学习。作者在 1999 年就使用这种方式了,当时写的还是这种代码: <font size="4" color="#000000">。而当 CSS 面世的时候,作者没有改变自己的学习方法,而错过了太多基本知识。文章主要介绍的是作者希望早点学到的东西。

Block, inline and inline-block

  • block 元素水平扩展以占据一整行(就像标题)。我们可以对它们运用垂直 margin;
  • inline 元素仅水平扩展到足以容纳其内容(就像 strong 或者 em 元素);
  • inline-block 元素像 inline 元素,但是你可以对它们运用垂直的 margin(对 button 之类的元素有用);

图片是内联的

img 元素默认是内联的,一般来说没什么问题,但是在尝试定位图像或添加垂直边距时会引起混乱。建议添加如下规则:

1
img {display: block;}

也可以添加 max-width: 100%; 以阻止块级元素突破容器。
normalize.css 里面没有,我觉得是否添加智者见智。

计算宽度

默认情况下,盒子的宽度 / 高度是通过将以下各项相加得出的:

  • Content area(内容)
  • Padding area(内边距)
  • Border area(边框)
1
2
3
4
5
.box-class {
width: 50%;
padding: 2em;
border: 0.1rem;
}

包含 .box-class 类的属性的盒子的宽度就是 50% + 4em + 0.2rem
默认情况下,我们用 css 设置的 width 属性指的仅仅只是 Content area(内容)部分的宽度。

下列代码将应用于所有元素,使得 width 属性设置的为上述三者相加的值。

1
* {box-sizing: border-box;}

Padding & margin 不一样

CSS 盒模型还有一个重要的组成部分 margin

  • margin 是元素之间的间隔
  • padding 是内容和边框之间的间隔

Margins 崩塌

当边距崩塌时,它们将合并在一起,从而使两个元素之间的间隔变为两个边距中较大的一个。较小的边距基本上结束在较大的边距之内。

当两个边距相遇时,较大的边距会吸收较小的边距。如果边距值相同,则它们会相互吸收。

假设我们有两个相邻的 block 元素,上面一个设置 margin-bottom: 1em 下面一个设置 margin-top: 1.5em,这两个元素间的间距将合并为 1.5em 而不是 1em + 1.5em

Note: 当父元素设置为 display: griddisplay: flex 时,边距不会崩塌。

浏览器具有默认样式表

CSS(Cascading Style Sheets) 是层叠样式表。我们必须记住,始终存在默认的浏览器样式表。它会在任何自定义样式表之前加载,而我们可以很轻易的覆盖它们。

声明的样式因浏览器而异。抹平差异的方法主要有两种,任选其一:

  1. CSS 重置,将所有默认样式都设置为“零”,例如 https://meyerweb.com/eric/tools/css/reset/
  2. normalize.css, 对默认样式进行微调,使它们在不同的浏览器中具有相似的外观:http://necolas.github.io/normalize.css/

任何地方都使用相对单位

我们可以将 em 用于 @media 查询和垂直边距,而将 rem 用于一致的边框宽度。

::before 和 ::after 需要 content

当我们使用 ::before 或者 ::after 伪元素时,需要添加 content 属性,即使它的值为空白:

1
.some-class::before {content: '';}

如果不包含此属性,伪元素将不会显示。

ch 单位

ch(character),大致基于一行的字符数来设置宽度的时候 ch 很有用。

1ch 就是数字 0 的宽度。

1ch 通常比平均字符宽度宽 20%到 30%。

Normal flow(正常布局流)

“normal flow” 的意思是出现在页面上的元素和在源代码中实现的方式相同。
例如:

1
2
<h2>Heading</h2>
<p>Paragraph text.</p>

我们期望的是 <h2>Heading</h2> 出现在 <p>Paragraph text.</p> 的之前 / 顶部。这就是 normal flow

而绝对定位和浮动就脱离了 normal flow

风格化 :focus 状态

1
2
3
4
5
6
7
8
a {
color: black;
}
a:hover,
a:focus,
a:active {
color: red;
}

我们最好为 :focus 状态添加不同的样式。因为例如鼠标悬停或者已经激活,用户再按[tab]键,:focus就不起作用了。

为防止晚出现的规则覆盖前面出现的规则,按照如下顺序定义规则:
link、visited、focus、hover、active(缩写为 LVPHA)
或者 LVHFA 的顺序也是可以的。

:nth-child()

p:nth-child()计算所有同级元素
p:nth-of-type()仅计算同级的p元素

1
2
3
4
5
6
<h1>:nth-child()</h1>
<p>Paragraph one.</p>
<p>Paragraph two.</p>
<p>Paragraph three.</p>
<p>Paragraph four.</p>
<p>Paragraph five.</p><p>Paragraph six.</p>
1
2
3
p:nth-child(even) {
background: orange;
}

1595610186.png

1
2
3
p:nth-of-type(even) {
background: orange;
}

1595610292.png

结束语

掌握CSS的基础知识很容易,但是了解事情的方式和原因对编写更好的CSS至关重要。

花时间学习这些东西不仅帮助我更快地编写CSS,而且还使我的代码更高效,更灵活。

参考文献