CSS层级样式表详细介绍(一)

一、CSS基本概念

CSS (Cascading Style Sheets,层叠样式表) 是一种样式表语言,用于描述HTML或XML文档的呈现方式。它由万维网联盟(W3C)在1996年首次提出,现已成为Web开发的三大核心技术之一(HTML、CSS和JavaScript)。

核心特性

1. 层叠性

层叠是CSS的核心概念,指多个样式规则可以应用于同一个元素,按照一定的优先级规则进行"层叠"。

具体机制

  • 样式表可以来自浏览器默认样式(用户代理样式表)
  • 用户设置的样式
  • 开发者定义的样式(内联、内部或外部样式表)

当多个规则作用于同一元素时,CSS根据以下因素决定最终应用的样式:

  • 来源:开发者样式通常覆盖浏览器默认样式
  • 特异性(选择器优先级)
  • 顺序:相同特异性的规则,后声明的覆盖先声明的
  • !important标记:可以提升规则优先级

示例

p { color: blue; }              /* 常规规则 */
#intro { color: black; }        /* ID选择器优先级更高 */
p { color: red !important; }    /* 使用!important提升优先级 */

2. 继承性

某些CSS属性会从父元素传递到子元素,这称为继承。

常见可继承属性

  • 文本相关:color, font-family, font-size, font-weight, text-align
  • 可见性:visibility
  • 列表属性:list-style

常见不可继承属性

  • 盒模型属性:width, height, padding, margin, border
  • 定位属性:position, top, left
  • 背景属性:background, background-color

控制继承

/* 强制继承 */
.child {
  color: inherit;  /* 从父元素继承颜色 */
}

/* 阻止继承 */
.child {
  color: initial;  /* 使用浏览器默认值 */
}

3. 优先级

CSS规则的优先级(特异性)决定了当多个规则冲突时,哪个规则会被应用。

优先级计算

  1. 内联样式:1000分
  2. ID选择器:100分
  3. 类选择器、属性选择器、伪类:10分
  4. 元素选择器、伪元素:1分

优先级示例

  • h1 = 1分(一个元素选择器)
  • h1.title = 11分(一个元素选择器 + 一个类选择器)
  • #header h1 = 101分(一个ID选择器 + 一个元素选择器)
  • style="color:red" = 1000分(内联样式)
  • h1 { color: red !important; } = 最高优先级

二、CSS语法结构

CSS使用简单易懂的语法结构,通过规则将样式应用到HTML元素。

基本语法

CSS规则由两个主要部分组成:

  1. 选择器(Selector):指定样式规则适用的HTML元素
  2. 声明块(Declaration Block):包含一组由属性和值组成的声明
选择器 {
    属性1: 值1;
    属性2: 值2;
    /* 注释可以这样写 */
}

语法细节

1. 选择器

选择器可以是单个选择器或组合选择器。

/* 单个选择器 */
h1 { color: blue; }

/* 组选择器 - 同时选择多个元素 */
h1, h2, h3 { font-family: Arial; }

/* 组合选择器 - 基于元素关系选择 */
nav > ul { margin: 0; }

2. 声明

每个声明由属性名称和值组成,中间使用冒号分隔,末尾使用分号结束。

p {
    color: #333;       /* 颜色属性 */
    font-size: 16px;   /* 字体大小属性 */
    line-height: 1.5;  /* 行高属性 */
}

3. 注释

CSS注释使用/* */格式,可以跨越多行。

/* 这是一个单行注释 */

/*
这是一个
多行注释
*/

4. 值的类型

CSS属性值可以有多种类型:

  • 关键字auto, none, inherit
  • 数字1, 2.5
  • 长度10px, 2em, 50%
  • 颜色red, #FF0000, rgba(255, 0, 0, 0.5)
  • URLurl('image.jpg')
  • 函数calc(100% - 20px), rgb(255, 0, 0)
  • 多值10px 20px 30px (用空格分隔)

5. 简写属性

许多CSS属性可以使用简写形式,将多个相关属性合并为一个。

/* 单独属性 */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;

/* 简写形式 */
margin: 10px 20px;  /* 上下=10px, 左右=20px */

三、CSS引入方式

CSS可以通过多种方式应用到HTML文档,每种方式都有其特定的用途和优缺点。

1. 内联样式

内联样式直接应用于HTML元素的style属性中。

语法

<p style="color: blue; font-size: 16px; margin: 10px;">这是一段带有内联样式的文本。</p>

优点

  • 优先级最高(覆盖其他CSS规则)
  • 样式直接与元素关联,方便查看
  • 适用于需要动态生成样式的情况

缺点

  • 样式与内容混合,违背CSS的分离原则
  • 难以维护,尤其是大型网站
  • 无法利用缓存复用样式
  • 无法使用伪类、伪元素等CSS特性

使用场景

  • 需要覆盖所有其他样式规则
  • 通过JavaScript动态生成的样式
  • 电子邮件HTML模板(有限的CSS支持)
  • 快速原型或测试

2. 内部样式表

内部样式表通过在HTML文档头部的<style>标签中定义CSS规则。

语法

<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 20px;
    }
    h1 {
      color: navy;
      border-bottom: 1px solid #ddd;
    }
    p {
      line-height: 1.6;
    }
  </style>
</head>
<body>
  <h1>内部样式表示例</h1>
  <p>这个页面使用内部样式表定义样式。</p>
</body>
</html>

优点

  • 样式与HTML在同一文件,便于单文件分发
  • 不需要额外的HTTP请求
  • 可以使用选择器、伪类等所有CSS功能

缺点

  • 样式不能在多个页面间共享
  • 增加HTML文件大小
  • 样式和内容未完全分离

使用场景

  • 单页面应用或内容
  • 样式仅适用于特定页面
  • 简单的演示或测试

3. 外部样式表

外部样式表是将CSS代码保存在独立的.css文件中,然后通过<link>标签或@import规则引入HTML文档。

使用<link>标签引入

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>外部样式表示例</h1>
  <p>这个页面使用外部样式表定义样式。</p>
</body>
</html>

styles.css文件内容

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 20px;
}
h1 {
  color: navy;
  border-bottom: 1px solid #ddd;
}
p {
  line-height: 1.6;
}

优点

  • 完全分离内容和样式
  • 样式可以在多个页面间共享
  • 浏览器可以缓存CSS文件,提高加载速度
  • 便于维护,可由专门的CSS开发者管理
  • 文件体积较小,加载更快

缺点

  • 需要额外的HTTP请求(可通过HTTP/2多路复用减轻)
  • 引入额外的文件依赖

使用场景

  • 大多数生产网站和应用
  • 多页面网站
  • 需要良好维护性的项目

4. @import方式

@import规则允许从一个CSS文件导入其他CSS文件的样式规则。

在HTML中使用

<style>
  @import url("typography.css");
  @import url("layout.css");
  
  /* 本地样式可以在这里定义 */
  body {
    background-color: #f5f5f5;
  }
</style>

在CSS文件中使用

/* main.css */
@import url("reset.css");
@import url("colors.css");
@import url("typography.css");

/* 主样式表中的规则 */
.container {
  max-width: 1200px;
  margin: 0 auto;
}

优点

  • 允许模块化CSS文件
  • 便于组织大型项目的样式
  • 可以在CSS文件中使用,无需修改HTML

缺点

  • 可能导致页面渲染延迟(串行加载)
  • 增加HTTP请求数量
  • 在某些情况下性能不如<link>标签

使用场景

  • 模块化CSS架构
  • 主题切换功能
  • 有条件地加载特定样式

比较不同引入方式的性能和应用场景

引入方式 性能 维护性 缓存 最佳应用场景
内联样式 无额外请求,但增加HTML大小 不可缓存 关键渲染路径优化、电子邮件、小型组件
内部样式表 无额外请求,但增加HTML大小 中等 随HTML缓存 单页面、独立应用、快速原型
外部样式表(link) 额外HTTP请求,但可并行加载 良好 单独缓存 大多数生产网站、多页面应用
@import 串行加载,通常性能较差 良好 单独缓存 CSS模块化、主题系统、条件加载

四、选择器系统

CSS选择器是样式表的基础,用于定位并选择需要应用样式的HTML元素。CSS提供了一套丰富的选择器系统,可以基于元素类型、属性、状态和位置等多种条件进行精确选择。

基础选择器

1. 元素选择器

根据标签名称选择所有匹配的HTML元素。

/* 选择所有段落元素 */
p {
  line-height: 1.6;
  margin-bottom: 1em;
}

/* 选择所有一级标题 */
h1 {
  font-size: 2em;
  font-weight: bold;
}

使用场景

  • 定义元素的基本样式
  • 实现CSS重置或标准化
  • 建立网站的整体排版基础

2. 类选择器

选择具有特定class属性的元素。类选择器以点(.)开头,后跟类名。

/* 选择所有带有"primary"类的元素 */
.primary {
  color: blue;
  font-weight: bold;
}

/* 选择所有带有"btn"类的元素 */
.btn {
  display: inline-block;
  padding: 8px 16px;
  border-radius: 4px;
}

/* 选择同时具有多个类的元素 */
.btn.btn-primary {
  background-color: blue;
  color: white;
}

使用场景

  • 定义可复用的样式组件
  • 创建变体样式(如按钮的不同状态)
  • 实现布局系统(如网格系统)

3. ID选择器

选择具有特定id属性的元素。ID选择器以井号(#)开头,后跟ID名。每个ID在页面中应当唯一。

/* 选择ID为"header"的元素 */
#header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

/* 选择ID为"main-content"的元素 */
#main-content {
  padding: 20px;
  margin-top: 60px;
}

使用场景

  • 选择页面中唯一的元素
  • 定义特定区域的布局
  • JavaScript交互的钩子(虽然现代实践更推荐使用类)

4. 通用选择器

选择所有元素。通用选择器使用星号(*)表示。

/* 选择文档中的所有元素 */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* 选择#container内的所有元素 */
#container * {
  transition: all 0.3s ease;
}

使用场景

  • CSS重置或初始化
  • 应用全局盒模型
  • 调试(如添加边框或背景色)

注意:通用选择器应谨慎使用,可能影响性能,尤其是在大型文档中。

组合选择器

组合选择器根据元素之间的关系选择元素。

1. 后代选择器(空格)

选择指定元素的所有后代元素,不论层级深度。

/* 选择nav元素内的所有li元素 */
nav li {
  display: inline-block;
  margin-right: 10px;
}

/* 选择article元素内的所有段落 */
article p {
  text-indent: 1em;
  line-height: 1.8;
}

使用场景

  • 定义特定容器内元素的样式
  • 创建上下文相关的样式规则

2. 直接后代选择器(>)

仅选择指定元素的直接子元素。

/* 选择nav的直接子元素ul */
nav > ul {
  list-style: none;
  display: flex;
}

/* 选择section直接子元素中的段落 */
section > p {
  font-size: 1.1em;
  margin-bottom: 1.5em;
}

使用场景

  • 避免样式泄漏到更深层级
  • 精确控制元素层级关系的样式

3. 相邻兄弟选择器(+)

选择紧接在指定元素后的同级元素。

/* 选择紧接在h2后面的段落 */
h2 + p {
  font-size: 1.2em;
  font-weight: bold;
}

/* 选择紧接在label后面的输入框 */
label + input {
  margin-left: 10px;
}

使用场景

  • 设置元素之间的间距
  • 定义标题后内容的特殊样式
  • 表单元素的布局

4. 通用兄弟选择器(~)

选择指定元素后的所有同级元素。

/* 选择h1后的所有段落 */
h1 ~ p {
  color: #666;
}

/* 选择checkbox后的所有相关元素 */
input[type="checkbox"] ~ label {
  color: gray;
}

input[type="checkbox"]:checked ~ label {
  color: black;
  font-weight: bold;
}

使用场景

  • 创建基于表单状态的界面反馈
  • 实现无JS的交互效果
  • 根据前面元素的存在控制后续元素样式

属性选择器

属性选择器基于元素的属性及其值来选择元素。

1. 基本属性选择器

选择具有指定属性的元素,不论属性值是什么。

/* 选择所有带有title属性的元素 */
[title] {
  cursor: help;
}

/* 选择所有带有data-role属性的元素 */
[data-role] {
  padding: 10px;
}

2. 精确匹配属性选择器

选择带有指定属性且属性值完全匹配的元素。

/* 选择type属性为"text"的输入框 */
input[type="text"] {
  border: 1px solid #ccc;
  padding: 5px 10px;
}

/* 选择rel属性为"external"的链接 */
a[rel="external"] {
  color: orange;
}

3. 部分匹配属性选择器

  • 开头匹配 [attr^="value"]:属性值以指定值开头
  • 结尾匹配 [attr$="value"]:属性值以指定值结尾
  • 包含匹配 [attr*="value"]:属性值包含指定值
  • 空格分隔匹配 [attr~="value"]:属性值包含指定词(以空格分隔)
  • 连字符匹配 [attr|="value"]:属性值等于指定值或以指定值后,接连字符开头
/* 选择所有以"https"开头的链接 */
a[href^="https"] {
  color: green;
}

/* 选择所有链接到PDF文件的链接 */
a[href$=".pdf"] {
  background-image: url('pdf-icon.png');
  background-repeat: no-repeat;
  padding-left: 20px;
}

/* 选择所有href中包含"example"的链接 */
a[href*="example"] {
  text-decoration: underline dotted;
}

/* 选择class中包含单词"button"的元素 */
[class~="button"] {
  border-radius: 4px;
}

/* 选择语言属性为英语及其变种的元素 */
[lang|="en"] {
  font-family: 'Times New Roman', serif;
}

使用场景

  • 基于文件类型设置链接样式
  • 实现图标系统
  • 根据数据属性应用样式
  • 选择特定类型的输入控件

4. 大小写敏感性

属性选择器默认区分大小写。使用i修饰符可以使选择器不区分大小写。

/* 大小写敏感匹配 */
[type="submit"] {
  background-color: blue;
}

/* 大小写不敏感匹配 */
[type="submit" i] {
  color: white;
}

伪类选择器

伪类选择器选择处于特定状态或位置的元素。伪类以冒号(:)开头。

1. 状态伪类

选择处于特定交互状态的元素。

/* 鼠标悬停状态 */
a:hover {
  text-decoration: underline;
}

/* 被激活的链接(鼠标按下时) */
a:active {
  color: red;
}

/* 获得焦点的输入框 */
input:focus {
  border-color: blue;
  outline: none;
}

/* 已访问的链接 */
a:visited {
  color: purple;
}

/* 被禁用的表单元素 */
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 被选中的复选框或单选按钮 */
input:checked + label {
  font-weight: bold;
}

使用场景

  • 创建交互反馈
  • 提高用户界面可用性
  • 增强表单元素的视觉反馈

2. 结构性伪类

基于元素在文档结构中的位置选择元素。

/* 第一个子元素 */
li:first-child {
  font-weight: bold;
}

/* 最后一个子元素 */
li:last-child {
  margin-bottom: 0;
}

/* 唯一的子元素 */
li:only-child {
  list-style-type: none;
}

/* 特定位置的子元素 */
li:nth-child(odd) {
  background-color: #f5f5f5;
}

li:nth-child(3n+1) {
  color: blue;
}

/* 倒数第二个子元素 */
li:nth-last-child(2) {
  text-decoration: underline;
}

/* 特定类型的第一个元素 */
p:first-of-type {
  font-size: 1.2em;
}

/* 特定类型的最后一个元素 */
p:last-of-type {
  margin-bottom: 2em;
}

/* 特定类型的唯一元素 */
img:only-of-type {
  display: block;
  margin: 0 auto;
}

/* 特定类型的第n个元素 */
h2:nth-of-type(2) {
  color: navy;
}

使用场景

  • 创建交替行样式(斑马条纹)
  • 特殊处理第一个或最后一个项目
  • 实现网格布局或列表样式
  • 精确定位无类或ID的元素

3. 特殊伪类

/* 所有未被访问的链接 */
a:link {
  color: blue;
}

/* 空元素(不包含子元素或文本) */
div:empty {
  display: none;
}

/* 目标元素(URL片段指向的元素) */
section:target {
  background-color: #fffacd;
  animation: highlight 2s ease;
}

/* 否定伪类(选择不符合选择器列表的元素) */
p:not(.special) {
  color: #333;
}

/* 选择具有特定值的输入元素 */
input:valid {
  border-color: green;
}

input:invalid {
  border-color: red;
}

/* 选择根元素(通常是html元素) */
:root {
  --main-color: blue;
  font-size: 16px;
}

/* lang伪类 */
:lang(fr) {
  quotes: "«" "»";
}

使用场景

  • 根据元素状态应用样式
  • 创建表单验证的视觉反馈
  • 根据URL片段高亮内容
  • 定义全局CSS变量

伪元素选择器

伪元素选择器创建或选择元素的特定部分。伪元素使用双冒号(::)表示。

/* 在元素内容前插入内容 */
.icon::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  background-image: url('icon.png');
  margin-right: 5px;
}

/* 在元素内容后插入内容 */
a[href^="http"]::after {
  content: " ↗";
  font-size: 0.8em;
}

/* 选择元素的第一个字母 */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
  float: left;
  margin-right: 5px;
}

/* 选择元素的第一行 */
p::first-line {
  font-variant: small-caps;
}

/* 选择用户选中的文本 */
::selection {
  background-color: gold;
  color: black;
}

/* 选择占位符文本 */
input::placeholder {
  color: #aaa;
  font-style: italic;
}

使用场景

  • 添加装饰性内容(如图标)
  • 创建特殊排版效果(如首字下沉)
  • 自定义输入控件的外观
  • 改变用户选择文本的样式

选择器组合与优化

1. 组选择器

将多个选择器组合应用同一组样式规则。

/* 多个选择器共用相同的样式规则 */
h1, h2, h3, h4, h5, h6 {
  font-family: 'Georgia', serif;
  line-height: 1.2;
}

button, .button, input[type="submit"] {
  border-radius: 4px;
  padding: 8px 16px;
  cursor: pointer;
}

2. 选择器组合

可以将多种选择器组合使用,创建高度具体的选择模式。

/* 多种选择器组合 */
#sidebar ul.navigation li.active > a:hover {
  color: #ff6600;
}

/* 属性选择器与伪类组合 */
input[type="checkbox"]:checked + label::before {
  content: "✓";
  color: green;
}

3. 选择器优化

过于复杂的选择器可能影响性能,尤其是在大型网页上。

优化建议

  • 避免过深的后代选择器(超过3-4级)
  • 尽量使用类选择器,少用通用选择器
  • 避免过度依赖位置选择器
  • 优先使用直接子代选择器(>)而非后代选择器(空格)
/* 过于复杂的选择器 */
body div.container ul li a span { color: red; }

/* 优化后 */
.nav-link-text { color: red; }

选择器实践应用

1. BEM命名约定下的选择器

BEM(Block, Element, Modifier)是一种命名约定,有助于创建模块化、可维护的CSS。

/* 块 */
.card {
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* 元素 */
.card__title {
  font-size: 18px;
  margin-bottom: 10px;
}

.card__image {
  width: 100%;
  border-radius: 4px 4px 0 0;
}

/* 修饰符 */
.card--featured {
  border: 2px solid gold;
}

.card__title--large {
  font-size: 24px;
}

2. 媒体元素控制

使用选择器创建响应式媒体元素。

/* 图像适应容器 */
img {
  max-width: 100%;
  height: auto;
}

/* 响应式视频容器 */
.video-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9宽高比 */
  height: 0;
  overflow: hidden;
}

.video-container iframe,
.video-container object,
.video-container embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

3. 表单样式化

使用选择器精确控制表单元素样式。

/* 所有输入控件的基本样式 */
input, select, textarea {
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 16px;
}

/* 特定类型的输入控件 */
input[type="text"],
input[type="email"],
input[type="password"] {
  width: 100%;
  margin-bottom: 15px;
}

/* 表单状态和验证 */
input:focus {
  border-color: #4a90e2;
  box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.25);
  outline: none;
}

input:invalid {
  border-color: #e74c3c;
}

input:valid {
  border-color: #2ecc71;
}

/* 禁用状态 */
input:disabled,
select:disabled,
textarea:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
  opacity: 0.7;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容