CSS 基础:选择器、盒模型与布局

2019-05-15 前端

CSS(Cascading Style Sheets,层叠样式表)是网页的表现层,负责控制 HTML 元素的样式、布局和动画。如果说 HTML 是房子的骨架,那么 CSS 就是房子的装修。本文将系统讲解 CSS 的引入方式、选择器、盒模型、定位机制,并通过实战案例巩固知识。

CSS 的三种引入方式

1. 行内样式(Inline Styles)

直接在 HTML 元素的 style 属性中写 CSS,不推荐在正式项目中使用,维护困难。

<p style="color: red; font-size: 16px;">这段文字是红色的</p>

2. 内部样式表(Internal Stylesheet)

在 HTML 的 <head> 中使用 <style> 标签定义样式,适合单页面小项目。

<!DOCTYPE html>
<html>
<head>
  <style>
    p {
      color: blue;
      line-height: 1.8;
    }
    .highlight {
      background-color: yellow;
    }
  </style>
</head>
<body>
  <p>蓝色文字</p>
  <p class="highlight">高亮文字</p>
</body>
</html>

3. 外部样式表(External Stylesheet)—— 推荐

将 CSS 写在独立的 .css 文件中,通过 <link> 引入。这是生产环境的标准做法。

<!-- index.html -->
<head>
  <link rel="stylesheet" href="style.css">
</head>
/* style.css */
body {
  margin: 0;
  font-family: sans-serif;
}

三种方式的对比:

方式 优点 缺点 使用场景
行内样式 优先级最高,快速测试 难以维护,无法复用 临时调试
内部样式 单文件,无需额外请求 无法多页面复用 单页小 demo
外部样式 可复用,易维护,缓存友好 需要额外 HTTP 请求 所有正式项目

CSS 选择器

选择器用于「选中」你想要样式化的 HTML 元素。

基本选择器

/* 1. 元素选择器:选中所有该元素 */
p {
  color: #333;
}

/* 2. 类选择器:选中 class 属性包含该值的元素(最常用) */
.highlight {
  background-color: yellow;
}

/* 3. ID 选择器:选中特定 ID 的元素(页面中应唯一) */
#header {
  height: 60px;
}

/* 4. 通配符选择器:选中所有元素 */
* {
  box-sizing: border-box;
}

/* 5. 属性选择器:选中具有特定属性的元素 */
input[type="text"] {
  border: 1px solid #ccc;
}
a[href^="https"]::after {
  content: " 🔒";  /* 给外部链接添加锁图标 */
}

组合选择器

/* 后代选择器:选中 .article 内所有 p(无论层级多深) */
.article p {
  margin-bottom: 1em;
}

/* 子元素选择器:只选中直接子元素 */
.nav > li {
  display: inline-block;
}

/* 相邻兄弟选择器:选中紧接在 h2 后的第一个 p */
h2 + p {
  font-weight: bold;
}

/* 通用兄弟选择器:选中 h2 后所有 p */
h2 ~ p {
  color: gray;
}

伪类选择器

/* 状态伪类 */
a:hover { color: red; }        /* 鼠标悬停 */
a:visited { color: purple; }   /* 已访问链接 */
input:focus { outline: 2px blue solid; }  /* 获得焦点 */

/* 结构伪类 */
li:first-child { font-weight: bold; }  /* 第一个子元素 */
li:last-child { border-bottom: none; }
li:nth-child(odd) { background: #f5f5f5; }   /* 奇数行 */
li:nth-child(even) { background: #fff; }      /* 偶数行 */
li:nth-child(3n+1) { color: red; }            /* 每3个选第1个 */

/* :not 否定伪类 */
button:not(.disabled) { cursor: pointer; }

选择器优先级(层叠规则)

当多个选择器同时作用于一个元素时,优先级高的生效。优先级用「特异性值」(specificity) 计算:

!important  >  行内样式  >  #id  >  .class  >  元素选择器  >  通配符
选择器 特异性值 示例
!important 最高,覆盖一切 color: red !important;
#id 100 #header
.class 10 .nav
element 1 div
* 0 *
/* 特异性计算示例 */
#nav .item a { color: blue; }    /* 100 + 10 + 1 = 111 */
.nav a { color: red; }           /* 10 + 1 = 11,上面的优先级更高 */

盒模型(Box Model)

CSS 中每个元素都被视为一个「盒子」,理解盒模型是掌握布局的关键。

盒模型的组成

┌─────────────────────────────────┐
│           margin(外边距)        │
│  ┌───────────────────────────┐  │
│  │     border(边框)          │  │
│  │  ┌─────────────────────┐  │  │
│  │  │   padding(内边距)   │  │  │
│  │  │  ┌───────────────┐  │  │  │
│  │  │  │ content(内容) │  │  │  │
│  │  │  └───────────────┘  │  │  │
│  │  └─────────────────────┘  │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘
.box {
  /* content:内容区域 */
  width: 200px;        /* 内容宽度 */
  height: 100px;       /* 内容高度 */

  /* padding:内边距,内容与边框之间的距离 */
  padding: 20px;               /* 四边都是 20px */
  padding: 10px 20px;          /* 上下 10px,左右 20px */
  padding: 10px 20px 15px 5px; /* 上 右 下 左(顺时针) */

  /* border:边框 */
  border: 2px solid #333;      /* 宽度 样式 颜色 */
  border-radius: 8px;          /* 圆角 */

  /* margin:外边距,与其他元素的距离 */
  margin: 30px auto;           /* 上下 30px,左右自动(居中) */
}

content-box vs border-box

这是 CSS 中一个非常重要的概念!

/* 默认:content-box —— width 只包括内容宽度 */
.box-content {
  box-sizing: content-box;     /* 默认值 */
  width: 200px;
  padding: 20px;
  border: 5px solid red;
  /* 实际占用宽度 = 200 + 20*2 + 5*2 = 250px */
}

/* 推荐:border-box —— width 包括内容+padding+border */
.box-border {
  box-sizing: border-box;      /* 推荐使用! */
  width: 200px;
  padding: 20px;
  border: 5px solid blue;
  /* 实际占用宽度 = 200px(内容自动压缩为 150px)*/
}

最佳实践:在 CSS 文件开头加上 * { box-sizing: border-box; },让所有元素都使用 border-box 模式,布局计算会简单很多!

CSS 定位机制

CSS 有五种定位方式:static、relative、absolute、fixed、sticky。

position: static(默认定位)

元素按照正常文档流排列,忽略 top、right、bottom、left 和 z-index 设置。

.static {
  position: static;  /* 默认值,可以不写 */
}

position: relative(相对定位)

相对于自身原来的位置进行偏移,不脱离文档流(原位置仍保留)。

.relative {
  position: relative;
  top: 10px;    /* 向下移动 10px(相对于原位置) */
  left: 20px;   /* 向右移动 20px */
  /* 原位置仍然被占据,不会影响其他元素布局 */
}

position: absolute(绝对定位)

相对于最近的已定位祖先元素(position 不是 static 的元素)进行定位。如果找不到,则相对于 <html> 根元素。

.parent {
  position: relative;  /* 成为子元素的定位参照 */
  width: 400px;
  height: 300px;
}

.child {
  position: absolute;
  top: 20px;
  right: 20px;
  /* 相对于 .parent 的右上角定位 */
}

绝对定位脱离文档流,不占据原空间,其他元素会当它不存在。

position: fixed(固定定位)

相对于浏览器视口定位,滚动页面时位置不变(如「回到顶部」按钮)。

.back-to-top {
  position: fixed;
  bottom: 30px;
  right: 30px;
  padding: 10px 15px;
  background: #333;
  color: white;
  border-radius: 50%;
  cursor: pointer;
}

position: sticky(粘性定位)

混合了 relative 和 fixed,在跨越特定阈值前是相对定位,之后是固定定位。常用于表格表头、导航栏。

.sticky-header {
  position: sticky;
  top: 0;  /* 当元素距离视口顶部 0px 时,变为 fixed */
  background: white;
  z-index: 10;
}

z-index 层叠顺序

z-index 控制定位元素的堆叠顺序,值越大越靠上(只对 relative、absolute、fixed、sticky 有效)。

.modal {
  position: fixed;
  z-index: 1000;       /* 模态框在最上层 */
  top: 0; left: 0;
  width: 100%; height: 100%;
  background: rgba(0,0,0,0.5);
}

实战:卡片式布局页面

综合运用选择器、盒模型和定位,创建一个响应式卡片布局:

总结

本文系统讲解了 CSS 的核心知识:

  1. 引入方式:外部样式表是最佳实践
  2. 选择器:从基本选择器到伪类,掌握特异性计算
  3. 盒模型:content、padding、border、margin 的关系,border-box 更实用
  4. 定位:static、relative、absolute、fixed、sticky 各有用途
  5. 实战:卡片布局综合运用了以上所有知识

下一篇文章我们将学习 JavaScript 基础,让网页「动」起来。

扩展阅读