Skip to content

✨ CSS 继承 👌

1. 继承概述

继承(Inheritance) 是 CSS 的核心特性之一,允许子元素自动获得父元素的某些样式属性。

1.1 什么是继承

继承是指子元素会自动获得父元素的某些 CSS 属性值,无需显式声明。这种机制简化了样式编写,提高了代码的可维护性。

1.2 继承的重要性

  • 减少代码重复:避免为每个子元素重复设置相同的样式
  • 保持一致性:确保相关元素具有统一的外观
  • 简化维护:修改父元素样式即可影响所有子元素
  • 符合设计直觉:模拟现实世界中的继承关系

1.3 继承的基本原理

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 父元素设置样式 */
      .parent {
        color: blue;
        font-size: 16px;
        font-family: Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      父元素文本
      <p>子元素段落</p>
      <span>子元素文本</span>
      <div>
        孙元素文本
        <em>曾孙元素文本</em>
      </div>
    </div>
  </body>
</html>

在上面的例子中,所有子元素都会继承父元素的 colorfont-sizefont-family 属性。

2. 继承机制

2.1 继承的工作原理

继承遵循 DOM 树结构,样式属性沿着父子关系向下传递:

父元素 (设置样式)
  ↓ 继承
子元素 (自动获得样式)
  ↓ 继承
孙元素 (自动获得样式)
  ↓ 继承
曾孙元素 (自动获得样式)

2.2 继承的条件

并非所有 CSS 属性都可以被继承,继承需要满足以下条件:

  1. 属性本身支持继承:只有特定的 CSS 属性才能被继承
  2. 没有显式声明:子元素没有显式设置该属性的值
  3. DOM 层次关系:必须存在父子关系

3. 可继承属性

3.1 文本相关属性

通常,跟文字内容相关的属性都能被继承

属性分类具体属性说明
字体属性font-family, font-size, font-style, font-weight, font-variant字体相关的所有属性
文本属性color, line-height, text-align, text-indent, text-transform文本显示和排版
文本装饰text-decoration-color, text-shadow部分文本装饰属性
字符间距letter-spacing, word-spacing字符和单词间距
列表属性list-style, list-style-type, list-style-position, list-style-image列表样式

3.2 详细的可继承属性列表

css
/* 字体相关属性 */
.parent {
  font-family: "Times New Roman", serif; /* 设置字体家族回退序列,按顺序匹配,找不到时使用通用族(serif/sans-serif) */
  font-size: 16px; /* 设置字体大小,影响排版密度与行高计算 */
  font-style: italic; /* 字体样式:normal/italic/oblique,用于斜体或倾斜效果 */
  font-weight: bold; /* 字重:normal/bold 或 100–900;bolder/lighter 相对父元素计算 */
  font-variant: small-caps; /* 字体变体:小型大写(small-caps)等 */
  font: 14px/1.5 Arial, sans-serif; /* 字体速记:按 [style variant weight] size/line-height family 设置;未声明的子属性重置为初始值 */
}

/* 文本相关属性 */
.parent {
  color: #333; /* 文本颜色,仅影响前景色,继承到子元素 */
  line-height: 1.6; /* 行框高度;无单位值按倍数继承,有单位/百分比继承为绝对值 */
  text-align: center; /* 块容器内行内内容对齐(左/中/右/两端),不影响块布局 */
  text-indent: 2em; /* 首行缩进,可为负值,仅作用首行 */
  text-transform: uppercase; /* 文本大小写转换(uppercase/lowercase/capitalize),仅影响呈现 */
  letter-spacing: 1px; /* 字距:正值增大、负值减小,影响可读性与密度 */
  word-spacing: 2px; /* 词距:调整单词间额外间隙,对中文等无空格语言影响不显著 */
  white-space: nowrap; /* 空白与换行处理:nowrap 不自动换行;pre/pre-wrap/pre-line 保留空白方式不同 */
}

/* 列表相关属性 */
.parent {
  list-style-type: disc; /* 项目符号类型(disc/square/decimal 等),用于 ul/ol 或 list-item 元素 */
  list-style-position: inside; /* 项目符号位置(outside/inside);inside 时符号算入内容流影响缩进与换行 */
  list-style-image: url("bullet.png"); /* 项目符号自定义图片,注意可访问性与加载表现 */
  list-style: square inside; /* 列表速记:同时设置 type/position/image,未声明的子属性会重置为初始值 */
}

/* 其他可继承属性 */
.parent {
  visibility: hidden; /* 可见性:hidden 隐藏但保留占位;子元素可显式设 visible 显示(区别于 display: none) */
  cursor: pointer; /* 光标形状(pointer/text/move 等),用于交互暗示,继承到子元素 */
  quotes: '"' '"' "'" "'"; /* 定义 open-quote/close-quote 生成内容使用的引号对,支持多层嵌套 */
  direction: rtl; /* 文本方向(ltr/rtl),影响双向文本排版与某些对齐默认值 */
}

3.3 继承属性的实际应用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 在根元素设置基础样式 */
      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          sans-serif;
        font-size: 16px;
        line-height: 1.6;
        color: #333;
        text-align: left;
      }

      /* 特定区域的样式调整 */
      .center-content {
        text-align: center;
      }

      .large-text {
        font-size: 1.2em;
      }

      .muted-text {
        color: #666;
      }
    </style>
  </head>
  <body>
    <header class="center-content">
      <h1>网站标题</h1>
      <p>副标题描述</p>
    </header>

    <main>
      <article class="large-text">
        <h2>文章标题</h2>
        <p>这是文章的正文内容,会继承父元素的字体和行高设置。</p>
        <p class="muted-text">这是一段辅助说明文字。</p>
      </article>
    </main>
  </body>
</html>

4. 不可继承属性

4.1 布局相关属性

与布局、定位、尺寸相关的属性通常不可继承,因为每个元素都应该有自己独立的布局特性。

属性分类具体属性原因
盒模型width, height, margin, padding每个元素的尺寸应该独立
边框border, border-width, border-style, border-color边框是元素自身的视觉特征
背景background, background-color, background-image背景属于元素自身
定位position, top, right, bottom, left, z-index定位信息必须独立
浮动float, clear布局行为不应继承
显示display, overflow, visibility显示方式应该独立控制

4.2 详细的不可继承属性列表

css
/* 盒模型属性 - 不可继承 */
.parent {
  width: 300px; /* 不可继承 */
  height: 200px; /* 不可继承 */
  margin: 20px; /* 不可继承 */
  padding: 15px; /* 不可继承 */
  box-sizing: border-box; /* 不可继承 */
}

/* 边框属性 - 不可继承 */
.parent {
  border: 1px solid #ccc; /* 不可继承 */
  border-radius: 5px; /* 不可继承 */
  border-collapse: collapse; /* 不可继承 */
}

/* 背景属性 - 不可继承 */
.parent {
  background-color: #f5f5f5; /* 不可继承 */
  background-image: url("bg.jpg"); /* 不可继承 */
  background-position: center; /* 不可继承 */
  background-repeat: no-repeat; /* 不可继承 */
  background-size: cover; /* 不可继承 */
}

/* 定位属性 - 不可继承 */
.parent {
  position: relative; /* 不可继承 */
  top: 10px; /* 不可继承 */
  left: 20px; /* 不可继承 */
  z-index: 100; /* 不可继承 */
}

/* 布局属性 - 不可继承 */
.parent {
  display: flex; /* 不可继承 */
  float: left; /* 不可继承 */
  clear: both; /* 不可继承 */
  overflow: hidden; /* 不可继承 */
  vertical-align: middle; /* 不可继承 */
}

/* 变换和动画 - 不可继承 */
.parent {
  transform: rotate(45deg); /* 不可继承 */
  transition: all 0.3s ease; /* 不可继承 */
  animation: fadeIn 1s ease-in-out; /* 不可继承 */
}

5. 继承值计算

5.1 继承值的计算过程

当子元素继承父元素的属性时,继承的是计算后的值,而不是声明的值:

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        font-size: 14px;
      }

      .parent {
        font-size: 150%; /* 计算为 21px (14px × 1.5) */
        color: #333;
        line-height: 2; /* 计算为 42 */
      }

      .inherited-child {
        /* 继承父元素计算后的值:
       font-size: 21px (不是150%)
       color: #333 
       line-height: 42 (不是2) */
      }

      .overridden-child {
        font-size: 0.8em; /* 基于继承的21px计算:21px × 0.8 = 16.8px */
        color: blue; /* 覆盖继承的颜色 */
      }
    </style>
  </head>
  <body>
    <div class="parent">
      父元素 - 21px, #333颜色
      <div class="inherited-child">
        继承的子元素 - 21px, #333颜色(真正继承计算值)
      </div>
      <div class="overridden-child">
        覆盖的子元素 - 16.8px, blue颜色(基于继承的21px计算)
      </div>
    </div>
  </body>
</html>

5.2 百分比值的继承

css
/* 百分比值继承示例 */
.parent {
  width: 400px;
  font-size: 20px;
  line-height: 150%; /* 计算为 20px * 1.5 = 30px */
}

.child {
  font-size: 16px;
  /* line-height 继承的是计算值 30px,而不是 150% */
  /* 所以 line-height 不会重新计算为 16px * 1.5 = 24px */
}

5.3 相对单位的继承

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .grandparent {
        font-size: 16px;
      }

      .parent {
        font-size: 1.2em; /* 16px * 1.2 = 19.2px */
      }

      .child {
        font-size: 1.2em; /* 19.2px * 1.2 = 23.04px */
      }

      .grandchild {
        font-size: 1.2em; /* 23.04px * 1.2 = 27.648px */
      }
    </style>
  </head>
  <body>
    <div class="grandparent">
      祖父元素 (16px)
      <div class="parent">
        父元素 (19.2px)
        <div class="child">
          子元素 (23.04px)
          <div class="grandchild">孙元素 (27.648px)</div>
        </div>
      </div>
    </div>
  </body>
</html>

5.4 避免累积效应

为了避免相对单位的累积效应,可以使用 rem 单位:

css
/* 使用 rem 避免累积效应 */
html {
  font-size: 16px; /* 设置根字体大小 */
}

.parent {
  font-size: 1.2rem; /* 16px * 1.2 = 19.2px */
}

.child {
  font-size: 1.2rem; /* 16px * 1.2 = 19.2px (不是基于父元素) */
}

.grandchild {
  font-size: 1.2rem; /* 16px * 1.2 = 19.2px (保持一致) */
}

6. 强制继承

6.1 inherit 关键字

使用 inherit 关键字可以强制任何属性继承父元素的值,即使该属性默认不可继承:

css
/* 强制继承示例 */
.parent {
  border: 2px solid red;
  background-color: yellow;
  width: 300px;
  height: 200px;
}

.child {
  border: inherit; /* 强制继承边框 */
  background-color: inherit; /* 强制继承背景色 */
  width: inherit; /* 强制继承宽度 */
  height: inherit; /* 强制继承高度 */
}

6.2 inherit 的实际应用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .button-group {
        border: 2px solid #007bff;
        border-radius: 8px;
        background-color: #f8f9fa;
      }

      .button {
        border: inherit; /* 继承父元素的边框 */
        border-radius: inherit; /* 继承父元素的圆角 */
        background-color: inherit; /* 继承父元素的背景色 */
        padding: 10px 15px;
        margin: 5px;
        cursor: pointer;
      }

      .button:hover {
        background-color: #e9ecef;
      }
    </style>
  </head>
  <body>
    <div class="button-group">
      <button class="button">按钮1</button>
      <button class="button">按钮2</button>
      <button class="button">按钮3</button>
    </div>
  </body>
</html>

6.3 initial 和 unset 关键字

css
/* CSS 关键字对比 */
.element {
  color: inherit; /* 继承父元素的值 */
  color: initial; /* 使用属性的初始值 */
  color: unset; /* 如果属性可继承则继承,否则使用初始值 */
  color: revert; /* 回退到用户代理样式表的值 */
}

/* 实际应用示例 */
.parent {
  color: red;
  background-color: yellow;
}

.child {
  color: inherit; /* 红色 (继承) */
  background-color: initial; /* transparent (初始值) */
}

.another-child {
  color: unset; /* 红色 (color可继承) */
  background-color: unset; /* transparent (background-color不可继承,使用初始值) */
}

6.4 all 属性

all 属性可以同时重置所有属性:

css
/* 重置所有属性 */
.reset-all {
  all: initial; /* 所有属性都使用初始值 */
}

.inherit-all {
  all: inherit; /* 所有属性都继承父元素 */
}

.unset-all {
  all: unset; /* 所有属性都使用 unset 行为 */
}

/* 实际应用:创建一个完全独立的组件 */
.isolated-component {
  all: initial; /* 重置所有继承的样式 */
  /* 然后重新定义需要的样式 */
  font-family: Arial, sans-serif;
  color: #333;
  background-color: white;
}

7. 实际应用

7.1 全局样式设置

利用继承机制设置全局基础样式:

css
/* 全局基础样式 */
html {
  font-size: 16px; /* 设置根字体大小 */
  line-height: 1.6; /* 设置基础行高 */
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
    "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
    "Helvetica Neue", sans-serif;
  color: #333; /* 设置基础文字颜色 */
  background-color: #fff; /* 设置基础背景色 */
  text-rendering: optimizeLegibility; /* 优化文字渲染 */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* 所有子元素都会继承这些基础样式 */

7.2 主题系统实现

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 主题变量 */
      .theme-light {
        --primary-color: #007bff;
        --secondary-color: #6c757d;
        --background-color: #ffffff;
        --text-color: #333333;
        --border-color: #dee2e6;
      }

      .theme-dark {
        --primary-color: #0d6efd;
        --secondary-color: #6c757d;
        --background-color: #1a1a1a;
        --text-color: #ffffff;
        --border-color: #444444;
      }

      /* 基础样式,使用继承 */
      body {
        background-color: var(--background-color);
        color: var(--text-color);
        font-family: Arial, sans-serif;
        transition: all 0.3s ease;
      }

      .card {
        background-color: inherit; /* 继承主题背景色 */
        color: inherit; /* 继承主题文字色 */
        border: 1px solid var(--border-color);
        padding: 20px;
        margin: 10px;
        border-radius: 8px;
      }

      .button {
        background-color: var(--primary-color);
        color: white;
        border: none;
        padding: 10px 20px;
        border-radius: 4px;
        cursor: pointer;
      }
    </style>
  </head>
  <body class="theme-light" id="app">
    <div class="card">
      <h2>卡片标题</h2>
      <p>这是卡片内容,会继承主题的颜色设置。</p>
      <button class="button" onclick="toggleTheme()">切换主题</button>
    </div>

    <script>
      function toggleTheme() {
        const app = document.getElementById("app");
        if (app.classList.contains("theme-light")) {
          app.classList.remove("theme-light");
          app.classList.add("theme-dark");
        } else {
          app.classList.remove("theme-dark");
          app.classList.add("theme-light");
        }
      }
    </script>
  </body>
</html>

7.3 响应式字体系统

css
/* 响应式字体系统 */
html {
  font-size: 14px; /* 移动端基础字体 */
}

/* 平板设备 */
@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

/* 桌面设备 */
@media (min-width: 1024px) {
  html {
    font-size: 18px;
  }
}

/* 大屏设备 */
@media (min-width: 1200px) {
  html {
    font-size: 20px;
  }
}

/* 使用 rem 单位,自动适应不同屏幕 */
body {
  font-size: 1rem; /* 继承根字体大小 */
  line-height: 1.6;
}

h1 {
  font-size: 2.5rem;
} /* 自动缩放 */
h2 {
  font-size: 2rem;
}
h3 {
  font-size: 1.75rem;
}
h4 {
  font-size: 1.5rem;
}
h5 {
  font-size: 1.25rem;
}
h6 {
  font-size: 1rem;
}

.small {
  font-size: 0.875rem;
}
.large {
  font-size: 1.25rem;
}

7.4 组件样式继承

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 基础组件样式 */
      .form-group {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
        font-size: 14px;
        color: #495057;
        line-height: 1.5;
      }

      /* 子元素自动继承基础样式 */
      .form-label {
        display: block;
        margin-bottom: 5px;
        font-weight: 500;
        /* 继承 font-family, font-size, color, line-height */
      }

      .form-input {
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #ced4da;
        border-radius: 4px;
        font-family: inherit; /* 显式继承字体 */
        font-size: inherit; /* 显式继承字体大小 */
        color: inherit; /* 显式继承颜色 */
      }

      .form-help {
        margin-top: 5px;
        font-size: 0.875em; /* 相对于继承的字体大小 */
        color: #6c757d;
        /* 继承 font-family, line-height */
      }

      /* 特殊状态 */
      .form-group.error {
        color: #dc3545;
      }

      .form-group.success {
        color: #28a745;
      }
    </style>
  </head>
  <body>
    <div class="form-group">
      <label class="form-label">用户名</label>
      <input type="text" class="form-input" placeholder="请输入用户名" />
      <div class="form-help">用户名长度应在3-20个字符之间</div>
    </div>

    <div class="form-group error">
      <label class="form-label">密码</label>
      <input type="password" class="form-input" placeholder="请输入密码" />
      <div class="form-help">密码不能为空</div>
    </div>
  </body>
</html>

8. 最佳实践建议

8.1 合理利用继承

8.1.1 在根元素设置基础样式

css
/* 推荐:在根元素设置基础样式 */
html {
  font-size: 16px;
  line-height: 1.6;
}

body {
  font-family: system-ui, -apple-system, sans-serif;
  color: #333;
  background-color: #fff;
}

8.1.2 使用继承减少代码重复

css
/* 推荐:利用继承 */
.article {
  font-family: Georgia, serif;
  font-size: 18px;
  line-height: 1.8;
  color: #2c3e50;
}

.article h1 {
  font-size: 2em; /* 相对于继承的 18px */
  margin-bottom: 0.5em;
}

.article p {
  margin-bottom: 1em;
  /* 自动继承 font-family, font-size, line-height, color */
}

8.3 性能优化

8.3.1 合理使用 CSS 自定义属性

css
/* 结合继承和 CSS 变量 */
:root {
  --primary-font: system-ui, sans-serif;
  --primary-color: #333;
  --primary-line-height: 1.6;
}

body {
  font-family: var(--primary-font);
  color: var(--primary-color);
  line-height: var(--primary-line-height);
}

/* 子元素自动继承,同时可以访问 CSS 变量 */
.special-section {
  --primary-color: #007bff; /* 局部覆盖 */
  /* font-family 和 line-height 继承自 body */
  /* color 使用局部覆盖的值 */
}