id 与 class
id 和 class 是 HTML 中最常用的全局属性,用于为元素添加唯一标识和分类标记。它们是 CSS 样式选择器和 JavaScript DOM 操作的基础。
前置知识
阅读本节前,建议先了解:大纲算法
基础概念
id 属性
id 属性为元素指定一个在整个文档中唯一的标识符。一个页面中不能有两个元素具有相同的 id 值。
html
<!-- id 必须唯一 -->
<div id="main-content">主内容</div>
<nav id="primary-nav">导航</nav>
<!-- 错误:重复 id -->
<div id="content">内容1</div>
<div id="content">内容2</div> <!-- 错误!id 不能重复 -->id 的命名规则:
| 规则 | 说明 | 示例 |
|---|---|---|
| 唯一性 | 页面中只能出现一次 | id="header" |
| 不能以数字开头 | 必须以字母开头 | 错误:id="1nav" |
| 不包含空格 | 用连字符替代空格 | 正确:id="main-content" |
| 区分大小写 | ID 和 id 是不同的 | id="header" ≠ id="Header" |
| 不包含特殊字符 | 避免使用 #、.、/ 等 | id="my_header" |
class 属性
class 属性为元素指定一个或多个类名(用空格分隔)。多个元素可以共享相同的 class。
html
<!-- 单个类名 -->
<div class="card">内容</div>
<!-- 多个类名(空格分隔) -->
<div class="card card-primary shadow">内容</div>
<!-- 多个元素共享 class -->
<div class="card">卡片1</div>
<div class="card">卡片2</div>
<div class="card">卡片3</div>语法与使用
id 的用法
html
<!-- CSS 选择器 -->
<style>
#main-content { max-width: 800px; margin: 0 auto; }
#primary-nav { background: #333; }
</style>
<!-- 锚点链接 -->
<a href="#main-content">跳转到主内容</a>
<div id="main-content">主内容区</div>
<!-- label 关联 -->
<label for="email">邮箱</label>
<input type="email" id="email">
<!-- JavaScript DOM 操作 -->
<script>
const element = document.getElementById('main-content');
element.style.display = 'block';
</script>class 的用法
html
<!-- CSS 类选择器 -->
<style>
.card { background: #fff; border-radius: 8px; }
.card-primary { border: 2px solid #3b82f6; }
.shadow { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
</style>
<!-- JavaScript 类操作 -->
<script>
const card = document.querySelector('.card');
card.classList.add('active'); // 添加类
card.classList.remove('shadow'); // 移除类
card.classList.toggle('open'); // 切换类
card.classList.contains('open'); // 检查类
</script>详细说明
id 与 class 的对比
| 特征 | id | class |
|---|---|---|
| 唯一性 | 必须唯一 | 可以重复 |
| 选择器权重 | (1,0,0,0) - 最高 | (0,1,0,0) |
| 数量 | 每个元素一个 id | 每个元素多个 class |
| JS 获取 | getElementById() | getElementsByClassName() / querySelectorAll() |
| 锚点跳转 | 支持 | 不支持 |
| label 关联 | 支持 | 不支持 |
| CSS 性能 | 快(浏览器内部优化) | 稍慢 |
id 的正确用途
html
<!-- 1. 页面锚点 -->
<a href="#section1">跳转到第一节</a>
<section id="section1">...</section>
<!-- 2. 表单关联 -->
<label for="username">用户名</label>
<input id="username" type="text">
<!-- 3. CSS 唯一样式(少用) -->
<style>
#site-header { position: fixed; top: 0; }
</style>
<header id="site-header">...</header>
<!-- 4. JavaScript 唯一操作 -->
<script>
const dialog = document.getElementById('confirm-dialog');
dialog.showModal();
</script>class 的 BEM 命名法
html
<!-- BEM: Block__Element--Modifier -->
<div class="card"> <!-- Block -->
<div class="card__header"> <!-- Element -->
<h2 class="card__title">标题</h2>
</div>
<div class="card__body">
<p>内容...</p>
</div>
</div>
<div class="card card--primary"> <!-- Modifier -->
<div class="card__header">
<h2 class="card__title">重要卡片</h2>
</div>
<div class="card__body">
<p>重要内容...</p>
</div>
</div>实战示例
完整的 id 和 class 使用示例
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>id 与 class 示例</title>
<style>
/* id 选择器:页面中唯一 */
#skip-link {
position: absolute; top: -100%; left: 0;
background: #0078d7; color: #fff;
padding: 0.5rem 1rem; z-index: 10000;
text-decoration: none;
}
#skip-link:focus { top: 0; }
#site-header {
background: #1e293b; color: #fff;
padding: 1rem 2rem;
position: sticky; top: 0; z-index: 100;
}
/* class 选择器:可复用 */
.container { max-width: 1000px; margin: 0 auto; }
.card-list {
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 1.5rem; margin-top: 2rem; padding: 0 2rem;
}
.card {
background: #fff; padding: 1.5rem; border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
transition: transform 0.2s;
}
.card:hover { transform: translateY(-2px); }
.card--featured {
border: 2px solid #3b82f6;
}
.card__title {
font-size: 1rem; font-weight: 600;
margin-bottom: 0.5rem;
}
.card__desc {
font-size: 0.85rem; color: #64748b;
line-height: 1.5;
}
.card__tag {
display: inline-block; padding: 0.15rem 0.5rem;
background: #e0f2fe; color: #0369a1;
border-radius: 3px; font-size: 0.75rem;
margin-top: 0.5rem;
}
/* form 样式 */
.form-group { margin-bottom: 1rem; }
.form-group label {
display: block; font-weight: 500;
margin-bottom: 0.25rem; font-size: 0.9rem;
}
.form-group input {
width: 100%; padding: 0.6rem 0.75rem;
border: 1px solid #d1d5db; border-radius: 6px;
}
.btn {
padding: 0.6rem 1.5rem; border: none;
border-radius: 6px; cursor: pointer;
font-size: 0.9rem; transition: background 0.2s;
}
.btn--primary { background: #3b82f6; color: #fff; }
.btn--primary:hover { background: #2563eb; }
main { padding: 2rem; }
.newsletter {
background: #f1f5f9; padding: 2rem; border-radius: 8px;
text-align: center; margin-top: 2rem; max-width: 600px; margin-left: auto; margin-right: auto;
}
@media (max-width: 768px) {
.card-list { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<!-- id:skip link 目标 -->
<a id="skip-link" href="#main-content">跳转到主要内容</a>
<!-- id:header 唯一标识 -->
<header id="site-header">
<div class="container" style="display:flex;justify-content:space-between;align-items:center">
<h1>TechHub</h1>
<nav aria-label="主导航">
<a href="#" style="color:#cbd5e0;text-decoration:none;margin-left:1rem">首页</a>
</nav>
</div>
</header>
<!-- id:main content 锚点 -->
<main id="main-content" class="container">
<h2>推荐文章</h2>
<!-- class:可复用的卡片 -->
<div class="card-list">
<div class="card card--featured">
<h3 class="card__title">CSS Grid 详解</h3>
<p class="card__desc">Grid 是二维布局系统,同时控制行和列。</p>
<span class="card__tag">CSS</span>
</div>
<div class="card">
<h3 class="card__title">JavaScript 事件</h3>
<p class="card__desc">事件是 JS 交互的核心机制。</p>
<span class="card__tag">JavaScript</span>
</div>
<div class="card">
<h3 class="card__title">TypeScript 入门</h3>
<p class="card__desc">TypeScript 为 JS 添加类型系统。</p>
<span class="card__tag">TypeScript</span>
</div>
</div>
<!-- id + class:表单 -->
<div class="newsletter">
<h3>订阅技术周刊</h3>
<form id="subscribe-form">
<div class="form-group">
<!-- id:label 关联 -->
<label for="subscriber-email">邮箱地址</label>
<input type="email" id="subscriber-email" class="form-input" placeholder="your@email.com" required>
</div>
<button type="submit" class="btn btn--primary">订阅</button>
</form>
</div>
</main>
<script>
// 使用 id 获取唯一元素
const form = document.getElementById('subscribe-form');
// 使用 class 获取多个元素
const cards = document.querySelectorAll('.card');
// 使用 classList 操作类
const featuredCard = document.querySelector('.card--featured');
console.log('推荐文章数:', cards.length);
</script>
</body>
</html>注意事项
常见错误
- id 重复:同一 id 出现多次会导致不可预测的行为
- id 以数字开头:不合法,浏览器可能无法正确识别
- class 中有空格:多个类名用空格分隔,但单个类名不能包含空格
- 滥用 id 做样式:尽量用 class 做样式,id 留给锚点和 JS
最佳实践
- id 用于唯一标识:锚点、label 关联、JS 操作
- class 用于样式和复用:CSS 样式、组件分类
- 使用一致的命名规范:推荐 BEM 或 kebab-case
- id 保持简短有意义:
id="main"比id="div123"好 - class 描述用途而非样式:
.card比.blue-box"好
下一节
继续学习:style 内联样式