html+css最佳实践

/ 前端

html5语义化标签

HTML5 中新引入的语义化标签大多数默认都是块级元素(block-level elements)

标签 描述
<article> 定义文档内的文章。
<aside> 定义页面内容之外的内容。
<bdi> 定义与其他文本不同的文本方向。
<details> 定义用户可查看或隐藏的额外细节。
<dialog> 定义对话框或窗口。
<figcaption> 定义 <figure> 元素的标题。
<figure> 定义自包含内容,比如图示、图表、照片、代码清单等等。
<footer> 定义文档或节的页脚。
<header> 定义文档或节的页眉。
<main> 定义文档的主内容。
<mark> 定义重要或强调的内容。
<menuitem> 定义用户能够从弹出菜单调用的命令/菜单项目。
<nav> 定义文档内的导航链接。
<progress> 定义任务进度。
<section> 定义文档中的节。
<summary> 定义 <details> 元素的可见标题。
<time> 定义日期/时间。

CSS选择器

CSS选择器是用于指定应用样式规则的HTML元素的方法。通过使用不同的选择器,你可以精确地控制页面上几乎任何元素的样式。

  1. 元素选择器(Element Selector)
  1. 类选择器(Class Selector)
  1. ID选择器(ID Selector)
  1. 属性选择器(Attribute Selector)
  1. 后代选择器(Descendant Selector)
  1. 子选择器(Child Selector)
  1. 相邻兄弟选择器(Adjacent Sibling Selector)
  1. 泛型兄弟选择器(General Sibling Selector)
  1. 伪类选择器(Pseudo-class Selector)
  1. 伪元素选择器(Pseudo-element Selector)

链接伪类选择器

  1. :link:

    • 适用于尚未被访问过的链接。

      1
      2
      3
      a:link {
      color: blue;
      }
  2. :visited:

    • 适用于已被用户访问过的链接。

    • 注意:出于隐私考虑,浏览器对 :visited 样式的控制有限制,例如不能改变 border 或者 outline 属性。

      1
      2
      3
      a:visited {
      color: purple;
      }
  3. :hover:

    • 当用户的指针悬停在元素上时应用的样式。

    • 这个伪类不仅限于链接,也可以应用于其他元素。

      1
      2
      3
      a:hover {
      color: red;
      }
  4. :active:

    • 当链接被激活(通常是指点击或按下的瞬间)时应用的样式。

      1
      2
      3
      a:active {
      color: orange;
      }
  5. :focus:

    • 当元素获得焦点时应用的样式,比如通过键盘导航到该链接。

    • 这个伪类同样可以应用于其他可聚焦的元素,如表单控件。

      1
      2
      3
      a:focus {
      outline: 2px solid yellow;
      }

使用顺序 (LVHA)

为了确保样式按照预期生效,应该遵循特定的顺序来声明链接伪类选择器,这个顺序是 LVHA

  1. :link
  2. :visited
  3. :hover
  4. :active

这种顺序保证了当多个伪类同时适用时,正确的一个会覆盖之前的样式。例如,如果一个链接既是已访问的又处于悬停状态,则 :hover 的样式会覆盖 :visited 的样式。

组合使用

你可以将多个伪类组合起来以创建更复杂的效果。例如,要为获得焦点且被悬停的链接设置样式,可以这样写:

1
2
3
a:focus:hover {
background-color: lightgray;
}

focus伪类选择器

:focus 是 CSS 中的一个伪类选择器,用于选择当前获得焦点的元素。当用户通过点击、使用键盘导航(例如 Tab 键)或者通过 JavaScript 程序性地将焦点设置到某个元素上时,该元素即处于 :focus 状态。

功能与用途

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 当输入框获得焦点时改变边框颜色 */
input:focus {
border-color: blue;
}

/* 当按钮获得焦点时改变背景颜色 */
button:focus {
background-color: lightgray;
}

/* 移除默认的 focus 外边框 */
a:focus {
outline: none;
}

CSS 伪元素

CSS 伪元素用于设置元素指定部分的样式

CSS3 引入了双冒号 :: 来区分伪类和伪元素,尽管单冒号 : 仍然支持向后兼容旧版本。

  1. ::before

    • 在选中元素的内容前插入生成的内容。

      1
      2
      3
      4
      p::before {
      content: "提示: ";
      color: blue;
      }
      • 这将在每个 <p> 元素的内容前添加“提示: ”字样,并将其颜色设置为蓝色。
  2. ::after

    • 在选中元素的内容后插入生成的内容。

      1
      2
      3
      4
      p::after {
      content: " - 完";
      color: green;
      }
      • 这将在每个 <p> 元素的内容后添加“ - 完”字样,并将其颜色设置为绿色。
  3. ::first-line

    • 仅应用于块级元素,用于设置元素第一行文本的样式。

      1
      2
      3
      4
      p::first-line {
      font-weight: bold;
      color: red;
      }
      • 这将使 <p> 元素的第一行文本变为粗体且颜色为红色。
  4. ::first-letter

    • 仅应用于块级元素,用于设置元素首字母的样式。

      1
      2
      3
      4
      p::first-letter {
      font-size: 200%;
      color: purple;
      }
      • 这将使 <p> 元素的第一个字母大小变为原来的两倍,并将其颜色设置为紫色。
  5. ::selection (非标准但广泛支持)

    • 用于更改用户选中文本时的外观。

      1
      2
      3
      4
      ::selection {
      background-color: yellow;
      color: red;
      }
      • 当用户选中页面上的文本时,背景色会变成黄色,文字颜色会变成红色。

:nth-child()

:nth-child() 是一种 CSS 伪类选择器,它允许你根据元素在其父元素中的位置来选择一个或多个特定的子元素。这个选择器非常强大,可以用来创建复杂的样式规则而无需对每个目标元素单独添加类或ID。

1
:nth-child(an+b)

:root

:root 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示<html>元素,除了优先级更高之外,与html 选择器相同。

1
2
3
4
/* 选择文档的根元素(HTML 中的 <html>) */
:root {
background: yellow;
}

声明全局 CSS 变量

在声明全局 CSS 变量时 :root 会很有用:

1
2
3
4
:root {
--main-color: hotpink;
--pane-padding: 5px 42px;
}

使用 CSS 自定义属性

基本用法

声明一个自定义属性,属性名需要以两个减号(--)开始,属性值则可以是任何有效的 CSS 值

和其他属性一样,自定义属性也是写在规则集之内的,如下:

1
2
3
element {
--main-bg-color: brown;
}

注意,规则集所指定的选择器定义了自定义属性的可见作用域。

通常的最佳实践是定义在根伪类 :root下,这样就可以在 HTML 文档的任何地方访问到它了:

1
2
3
:root {
--main-bg-color: brown;
}

注意

自定义属性名是大小写敏感的--my-color--My-color 会被认为是两个不同的自定义属性

Var()函数

如前所述,使用一个局部变量时用 var() 函数包裹以表示一个合法的属性值

1
2
3
element {
background-color: var(--main-bg-color);
}

自定义属性的继承性

自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。

1
2
3
4
5
6
<div class="one">
<div class="two">
<div class="three"></div>
<div class="four"></div>
</div>
</div>
1
2
3
4
5
6
7
.two {
--test: 10px;
}

.three {
--test: 2em;
}

在这个情况下, var(--test) 的结果分别是:

注意,这些是自定义属性,并不是你在其他编程语言中遇到的实际的变量。这些值仅当需要的时候才会计算,而并不会按其他规则进行保存。

自定义属性备用值

var()函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换。

备注: 备用值并不是用于实现浏览器兼容性的。如果浏览器不支持 CSS 自定义属性,备用值也没什么用。它仅对支持 CSS 自定义属性的浏览器提供了一个备份机制,该机制仅当给定值未定义或是无效值的时候生效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.two {
color: var(--my-var, red); /* Red if --my-var is not defined */
}

.three {
background-color: var(
--my-var,
var(--my-background, pink)
); /* pink if --my-var and --my-background are not defined */
}

.three {
background-color: var(
--my-var,
--my-background,
pink
); /* Invalid: "--my-background, pink" */
}

第二个例子展示了如何处理一个以上的 fallback。该技术可能会导致性能问题,因为它花了更多的时间在处理这些变量上。

JavaScript 中的值

在 JavaScript 中获取或者修改 CSS 变量和操作普通 CSS 属性是一样的:

1
2
3
4
5
6
7
8
// 获取一个 Dom 节点上的 CSS 变量
element.style.getPropertyValue("--my-var");

// 获取任意 Dom 节点上的 CSS 变量
getComputedStyle(element).getPropertyValue("--my-var");

// 修改一个 Dom 节点上的 CSS 变量
element.style.setProperty("--my-var", jsVar + 4);

最佳单位实践

1. px(像素)

1
2
3
div {
width: 200px; /* 固定宽度 */
}

2. em

1
2
3
p {
font-size: 1.5em; /* 相对于父元素字体大小放大1.5倍 */
}

3. rem(root em)

1
2
3
4
5
6
7
html {
font-size: 16px;
}

div {
font-size: 1.2rem; /* 相对于根元素字体大小放大1.2倍 */
}

4. vwvh(视窗宽度和高度百分比)

1
2
3
4
div {
width: 50vw; /* 占据视口宽度的一半 */
height: 30vh; /* 占据视口高度的30% */
}

5. %(百分比)

1
2
3
div {
width: 80%; /* 占据父元素宽度的80% */
}

6. fr(网格分数单位)

1
2
3
4
.container {
display: grid;
grid-template-columns: 1fr 2fr; /* 第二列是第一列宽度的两倍 */
}

@media

@media CSS@规则可用于基于一个或多个媒体查询的结果来应用样式表的一部分。使用它,你可以指定一个媒体查询和一个 CSS 块,当且仅当该媒体查询与正在使用其内容的设备匹配时,该 CSS 块才能应用于该文档。

备注: 在 JavaScript 中,可以使用 CSSMediaRuleCSS 对象模型接口访问使用 @media 创建的规则。

语法

@media at 规则可置于你代码的顶层或嵌套至其他任何的 at 条件规则组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 在你的代码的顶层 */
@media screen and (min-width: 900px) {
article {
padding: 1rem 3rem;
}
}

/* 嵌套至其他的 at 条件规则中 */
@supports (display: flex) {
@media screen and (min-width: 900px) {
article {
display: flex;
}
}
}

媒体类型

媒体类型(media type)描述设备的一般类别。除非使用 notonly 逻辑运算符,否则媒体类型是可选的,并且会(隐式地)应用 all 类型。

块元素

块级元素的特点

  1. 独占一行

    • 每个块级元素通常会从新的一行开始,并且在其后也会创建换行,使得它与前后元素之间有明显的分隔。
  2. 宽度默认为容器宽度

    • 如果没有特别指定宽度,块级元素的宽度将自动扩展到其包含块(通常是父元素)的100%。
  3. 可以设置高度和宽度

    • 与内联元素不同,块级元素支持设置明确的高度和宽度属性。
  4. 支持内边距和外边距

    • 可以使用 paddingmargin 属性来控制元素内部和外部的空间。
  5. 可包含其他块级或内联元素

    • 块级元素不仅能够容纳文本内容,还可以包含其他块级元素或内联元素。
  6. 影响布局流

    • 块级元素会影响文档的正常流,它们按照出现的顺序垂直排列。
  7. 生成新的块格式化上下文 (BFC)

    • 某些块级元素(如浮动元素、绝对定位元素等)可以生成新的 BFC,这有助于解决某些布局问题,例如清除浮动。

常见的块级元素

行内元素

行内元素的特点

  1. 不独占一行

    • 行内元素不会自动换行,它们与其他行内元素或文本内容在同一行内显示,直到同一行的空间用尽为止。
  2. 宽度和高度由内容决定

    • 行内元素的宽度和高度仅限于其包含的内容,不会扩展到父容器的宽度。
  3. 不影响文档流布局

    • 行内元素不会影响周围块级元素的布局,它们只在当前行内占据空间。
  4. 有限的内边距和外边距控制

    • 可以设置 paddingmargin,但这些属性对水平方向的影响有效,而垂直方向(上下)的 paddingmargin 不会影响周围的行内元素的位置。
  5. 不能包含块级元素

    • 行内元素通常只能包含文本和其他行内元素,不能直接包含块级元素。如果尝试这样做,浏览器可能会根据规范调整结构,或者产生不可预期的效果。
  6. 支持行内样式

    • 行内元素可以接受各种 CSS 样式,如颜色、字体大小、文本装饰等,但不像块级元素那样可以自由地控制宽高。

常见的行内元素

行内块元素

行内块元素的特点

行内块元素(inline-block elements)结合了行内元素和块级元素的特性。它们在布局中像行内元素一样,不会自动换行,并且可以与其他行内内容并排显示;但同时,它们又像块级元素一样,可以设置宽度、高度、内边距(padding)和外边距(margin),并且这些属性会对元素的实际尺寸产生影响。以下是行内块元素的主要特点:

  1. 不独占一行

    • 行内块元素不会自动换行,而是与其他行内或行内块元素在同一行内显示。
  2. 可设置宽度和高度

    • 与块级元素类似,行内块元素支持明确地设置 widthheight 属性,这会影响它们在页面上的大小。
  3. 支持内边距和外边距

    • 行内块元素可以应用所有方向的 paddingmargin,并且这些属性会按照预期工作,包括垂直方向。
  4. 不影响文档流布局

    • 行内块元素不会打断周围的文本流或其他行内内容,它们只是占据自身所需的水平空间。
  5. 可以包含其他行内或行内块元素

    • 虽然不如块级元素那样常见,但行内块元素也可以包含其他行内或行内块元素。
  6. 保持行内特性

    • 尽管它们具有某些块级元素的特性,但行内块元素仍然保留了作为行内元素的基本行为,例如它们不会像块级元素那样自动扩展到父容器的宽度。

常用的行内块元素

font系列

字体系列

使用通用字体系列

如果你希望文档使用一种 sans-serif 字体,但是你并不关心是哪一种字体,以下就是一个合适的声明:

1
body {font-family: sans-serif;}

这样用户代理就会从 sans-serif 字体系列中选择一个字体(如 Helvetica),并将其应用到 body 元素。因为有继承,这种字体选择还将应用到 body 元素中包含的所有元素,除非有一种更特定的选择器将其覆盖。

使用font-family系列

下面的例子为所有 h1 元素设置了 Georgia 字体:

1
h1 {font-family: Georgia;}

这样的规则同时会产生另外一个问题,如果用户代理上没有安装 Georgia 字体,就只能使用用户代理的默认字体来显示 h1 元素。

我们可以通过结合特定字体名和通用字体系列来解决这个问题:

1
h1 {font-family: Georgia, serif;}

如果读者没有安装 Georgia,但安装了 Times 字体(serif 字体系列中的一种字体),用户代理就可能对 h1 元素使用 Times。尽管 Times 与 Georgia 并不完全匹配,但至少足够接近。

因此,我们建议在所有 font-family 规则中都提供一个通用字体系列。这样就提供了一条后路,在用户代理无法提供与规则匹配的特定字体时,就可以选择一个候选字体。

如果您对字体非常熟悉,也可以为给定的元素指定一系列类似的字体。要做到这一点,需要把这些字体按照优先顺序排列,然后用逗号进行连接:

1
2
p {font-family: Times, TimesNR, 'New Century Schoolbook',
Georgia, 'New York', serif;}

根据这个列表,用户代理会按所列的顺序查找这些字体。如果列出的所有字体都不可用,就会简单地选择一种可用的 serif 字体。

使用引号

您也许已经注意到了,上面的例子中使用了单引号。只有当字体名中有一个或多个空格(比如 New York),或者如果字体名包括 # 或 $ 之类的符号,才需要在 font-family 声明中加引号。

单引号或双引号都可以接受。但是,如果把一个 font-family 属性放在 HTML 的 style 属性中,则需要使用该属性本身未使用的那种引号:

1
2
<p style="font-family: Times, TimesNR, 'New Century Schoolbook', Georgia,
'New York', serif;">...</p>

字体大小

font-size 属性设置文本的大小

字体加粗

font-weight 属性设置文本的粗细。

使用 bold 关键字可以将文本设置为粗体。

关键字 100 ~ 900 为字体指定了 9 级加粗度。如果一个字体内置了这些加粗级别,那么这些数字就直接映射到预定义的级别,100 对应最细的字体变形,900 对应最粗的字体变形。数字 400 等价于 normal,而 700 等价于 bold。

字体风格

font-style 属性最常用于规定斜体文本。

该属性有三个值:

italic 和 oblique 的区别

通常情况下,italic 和 oblique 文本在 web 浏览器中看上去完全一样。

字体变形

font-variant 属性可以设定小型大写字母。

小型大写字母不是一般的大写字母,也不是小写字母,这种字母采用不同大小的大写字母。

font复合属性写法

font 属性是一个简写的复合属性,可以同时设置多个字体相关属性。它的语法如下:

1
2
3
selector {
font: [font-style] || [font-variant] || [font-weight] || [font-size] / [line-height] [font-family];
}
  1. [font-style] (可选):定义字体样式(如斜体)。可能的值包括:

    • normal
    • italic
    • oblique
  2. [font-variant] (可选):定义是否使用小型大写字母。可能的值包括:

    • normal
    • small-caps
  3. [font-weight] (可选):定义字体粗细。可能的值包括:

    • normal
    • bold
    • bolder
    • lighter
    • 数字值 (100, 200, …, 900)
  4. [font-size] (必需):定义字体大小。可以是绝对尺寸(如 12px)、相对尺寸(如 1.2em)或关键字(如 largersmaller)。

  5. / [line-height] (可选):定义行高。如果提供,则必须紧跟在 font-size 后面,并用斜杠分隔。它可以是数字、百分比或长度单位。

  6. [font-family] (必需):定义字体族。应该按照优先级顺序列出一系列字体名称,以逗号分隔。通常包括首选字体和通用字体族(如 serif, sans-serif, monospace 等)作为后备选项。

CSS背景

background-color

background-color 属性指定元素的背景色。

通过 CSS,颜色通常由以下方式指定:

不透明度 / 透明度

opacity 属性指定元素的不透明度/透明度。取值范围为 0.0 - 1.0。值越低,越透明:

注意:使用 opacity 属性为元素的背景添加透明度时,其所有子元素都继承相同的透明度。

使用 RGBA 的透明度

如果您不希望对子元素应用不透明度,例如上面的例子,请使用 RGBA 颜色值。下面的例子设置背景色而不是文本的不透明度:

RGBA 颜色值指定为:rgba(red, green, blue, alpha)。alpha 参数是介于 0.0(完全透明)和 1.0(完全不透明)之间的数字。

1
2
3
div {
background: rgba(0, 128, 0, 0.3) /* 30% 不透明度的绿色背景 */
}

background-image

background-size

  1. 指定宽度和高度:可以使用具体的长度值(如像素px)、百分比或自动来设定背景图像的尺寸。例如,background-size: 50px 100px; 将宽度设置为50px,高度设置为100px。

  2. 使用百分比:当使用百分比时,背景图像的大小是相对于其容器的宽度和高度而言的。例如,background-size: 100% 100%; 会使背景图像完全填充其容器,可能会导致图像变形,因为宽度和高度都被拉伸以匹配容器的尺寸。

  3. cover 关键字background-size: cover; 会按比例缩放背景图像,使其完全覆盖背景区域。图像的比例保持不变,但是可能有一部分图像不会显示出来,因为它超出了容器的范围。

  4. contain 关键字background-size: contain; 同样按比例缩放图像,但保证整个图像都可见。这意味着图像将被缩放到尽可能大的尺寸,同时仍完全适应内容区域,可能会在图像与容器之间留下空白空间。

background-repeat

background-repeat: no-repeat

background-position

background-position 属性用于指定背景图像的位置。

描述
left-top right-center left-bottom 如果您仅规定了一个关键词,那么第二个值将是”center”。默认值:0% 0%。
x% y% 第一个值是水平位置,第二个值是垂直位置。左上角是 0% 0%。右下角是 100% 100%。如果您仅规定了一个值,另一个值将是 50%。
xpos ypos 第一个值是水平位置,第二个值是垂直位置。左上角是 0 0。单位是像素 (0px 0px) 或任何其他的 CSS 单位。如果您仅规定了一个值,另一个值将是50%。您可以混合使用 % 和 position 值。

背景附着

background-attachment 属性指定背景图像是应该滚动还是固定的(不会随页面的其余部分一起滚动):

1
2
3
4
5
6
body {
background-image: url("tree.png");
background-repeat: no-repeat;
background-position: right top;
background-attachment: fixed;
}
1
2
3
4
5
6
body {
background-image: url("tree.png");
background-repeat: no-repeat;
background-position: right top;
background-attachment: scroll;
}

color

CSS 语法

1
color: color|initial|inherit;

属性值

描述
color_name 规定颜色值为颜色名称的颜色(比如 red)。
hex_number 规定颜色值为十六进制值的颜色(比如 #ff0000)。
rgb_number 规定颜色值为 rgb 代码的颜色(比如 rgb(255,0,0))。
inherit 规定应该从父元素继承颜色。

text-align

定义和用法

text-align 属性规定元素中的文本的水平对齐方式。

CSS 语法

1
text-align: left|right|center|justify|initial|inherit;

属性值

描述
left 把文本排列到左边。默认值:由浏览器决定。
right 把文本排列到右边。
center 把文本排列到中间。
justify 实现两端对齐文本效果。
inherit 规定应该从父元素继承 text-align 属性的值。

text-decoration

text-decoration 属性规定添加到文本的修饰。

CSS 语法

1
text-decoration: text-decoration-line text-decoration-color text-decoration-style text-decoration-thickness|initial|inherit;

属性值

描述
text-decoration-line 设置要使用的文本装饰类型(如下划线、上划线、划线)。
text-decoration-color 设置文字装饰的颜色。
text-decoration-style 设置文本装饰的样式(如实心、波浪形、点线、虚线、双线)。
text-decoration-thickness 设置装饰线的粗细。
initial 将此属性设置为其默认值。请参阅 initial。
inherit 从其父元素继承此属性。请参阅 inherit。

text-indent

text-indent 属性规定文本块中首行文本的缩进。

**注释:**允许使用负值。如果使用负值,那么首行会被缩进到左边。

**注意:**在 CSS 2.1 之前,text-indent 总是继承计算值,而不是声明值。

属性值

描述
length 定义固定的缩进。默认值:0。
% 定义基于父元素宽度的百分比的缩进。
inherit 规定应该从父元素继承 text-indent 属性的值。

line-height

line-height 属性设置行间的距离(行高)。

**注释:**不允许使用负值

CSS 语法

1
line-height: normal|number|length|initial|inherit;

属性值

描述
normal 默认。设置合理的行间距。
number 设置数字,此数字会与当前的字体尺寸相乘来设置行间距。
length 设置固定的行间距。
% 基于当前字体尺寸的百分比行间距。
inherit 规定应该从父元素继承 line-height 属性的值。

box-sizing 属性

为了更好地控制元素尺寸,CSS 提供了 box-sizing 属性:

flex布局

Flexbox 元素

要开始使用 Flexbox 模型,首先需要定义一个 Flex 容器。这通过设置容器的 display 属性为 flex 来完成。一旦定义了 Flex 容器,其直接子元素将自动成为 Flex 项目。

父元素(容器)

关键属性

子元素(项目)

Flex 项目的特定属性允许进一步定制单个项目的布局行为: