从零搭建一个 TP-Link 产品卡片,每一步解释一个 HTML 核心概念
HTML 的本质就是用标签包裹内容,告诉浏览器"这是标题""这是段落""这是按钮"。
<h3>Deco X50</h3> <p>全屋覆盖 Mesh WiFi 系统</p> <p>$199.99</p>
全屋覆盖 Mesh WiFi 系统
$199.99
<h3> 标题标签h1 最大、h6 最小。这里用 h3 因为卡片标题不是页面主标题。
<p> 段落标签一段文字。浏览器自动换行、自动加间距。
<p> 开头,</p> 结尾,中间是内容。
HTML 标签就像信封。信封告诉邮局"这是信件"还是"这是包裹",标签告诉浏览器"这是标题"还是"这是段落"。<h3> 和 <p> 视觉上看都是文字,但浏览器知道它们的语义不同——搜索引擎会把 <h3> 里的文字当作关键信息加权。
<img src="deco-x50.jpg" alt="Deco X50 产品图" width="280" height="200"> <h3>Deco X50</h3> <p>全屋覆盖 Mesh WiFi 系统</p> <p>$199.99</p> <button>加入购物车</button>
全屋覆盖 Mesh WiFi 系统
$199.99
<img> 标签有 4 个属性:src(图片来源)、alt(图片加载失败或屏幕阅读器用的替代文字)、width 和 height(尺寸)。属性写在开始标签里,用来给标签提供额外信息。就像寄快递时,信封上除了写"包裹"(标签),还要写收件地址、重量(属性)。
右边的按钮是浏览器的默认样式——灰色、方角、丑。这就是为什么 HTML 离不开 CSS。HTML 只管"这是一个按钮",CSS 管"这个按钮是蓝色的、圆角的、有阴影的"。
现在内容都散着,没有层次。用 <div>(division,分区)把相关的内容包在一起:
<!-- 最外层:整张卡片 --> <div class="product-card"> <!-- 图片区域 --> <img src="deco-x50.jpg" alt="Deco X50 产品图"> <!-- 信息区域 --> <div class="card-body"> <h3>Deco X50</h3> <p class="tagline">全屋覆盖 Mesh WiFi</p> <p class="price">$199.99</p> <button>加入购物车</button> </div> </div>
<div> 容器标签本身不显示任何东西,只是把子元素包在一起形成一组。就像文件夹——文件夹本身不是文件,但把相关文件归在一起。
class 属性给标签起一个"名字",让 CSS 能找到它并设置样式。一个 class 可以被多个标签共享。
div 里面套 div,div 里面套 h3 和 p。HTML 就是一棵树,右边的示意图就是这棵树的样子。
HTML 的所有标签形成一棵树。外层标签是"父级",里面的是"子级"。product-card 是最外层的父级,card-body 是它的子级,h3、p、button 是 card-body 的子级。这个层级关系决定了 CSS 和 JS 怎么定位和操作页面上的元素。
同样的 HTML 结构,加上 CSS 后变成一个好看的产品卡片:
/* 卡片容器 */ .product-card { width: 280px; border: 1px solid #e5e7eb; border-radius: 12px; /* 圆角 */ overflow: hidden; /* 图片不超出圆角 */ } /* 信息区域的内边距 */ .card-body { padding: 16px; } /* 价格加粗加大 */ .price { font-size: 20px; font-weight: 700; } /* 按钮样式 */ button { width: 100%; padding: 10px; background: #0ea5e9; /* TP-Link 蓝 */ color: white; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; /* 鼠标变手指 */ } /* 鼠标悬停时按钮变深 */ button:hover { background: #0284c7; }
全屋覆盖 Mesh WiFi 系统
$199.99
.product-card — 点开头,表示"找 class 叫 product-card 的标签"
button — 没有点,表示"找所有 button 标签"
button:hover — 冒号表示"状态",这里是"鼠标悬停在按钮上时"
HTML 里写 class="price",CSS 里写 .price { font-size: 20px }。class 是两者之间的桥梁——HTML 给标签起名,CSS 按名字找到它并设置样式。一个 class 名可以同时用在多个标签上——比如全站所有价格都用 class="price",CSS 写一次样式就全部生效。
<div class="product-card"> <img src="deco-x50.jpg" alt="Deco X50"> <div class="card-body"> <!-- 促销标签 --> <span class="badge">限时特惠</span> <h3>Deco X50</h3> <p class="tagline">全屋覆盖 Mesh WiFi</p> <!-- 评分 --> <div class="rating">★★★★☆ 4.2 (128 条评价)</div> <!-- 规格 --> <div class="specs"> <div class="spec"> <strong>WiFi 6</strong> AX3000 </div> <div class="spec"> <strong>覆盖</strong> 5000sqft </div> </div> <!-- 价格(含原价划线) --> <p class="price"> $199.99 <span class="original">$249.99</span> </p> <button>加入购物车</button> </div> </div>
全屋覆盖 Mesh WiFi 系统
$199.99 $249.99
<span> 行内容器<div> 会独占一行,<span> 不会。用来给一行文字中的一部分加样式(如原价划线)。
<strong> 加粗强调语义上表示"重要",浏览器默认显示为加粗。和 CSS 的 font-weight: bold 效果一样,但有语义。
两个 <div class="spec"> 共享同一个 class,CSS 只写一次样式就同时作用于两个。
现在按钮点了没反应。加一段 JS 让它有交互:
<button onclick="addToCart()">加入购物车</button> <script> function addToCart() { // 1. 改按钮的文字和颜色 const btn = document.querySelector('button'); btn.textContent = '✓ 已加入'; btn.style.background = '#16a34a'; // 2. 2 秒后恢复原样 setTimeout(() => { btn.textContent = '加入购物车'; btn.style.background = '#0ea5e9'; }, 2000); } </script>
全屋覆盖 Mesh WiFi 系统
$199.99 $249.99
onclick 是一个事件属性——当用户点击这个按钮时,执行 addToCart() 函数。HTML 定义"这里有个按钮",CSS 定义"按钮是蓝色的",JS 定义"点按钮会发生什么"。三者各司其职。
到目前为止我们用了很多 <div>。但 HTML 有更具体的标签,能告诉搜索引擎和屏幕阅读器"这块内容是什么":
<!-- 改造前:全是 div --> <div class="product-card"> <div class="card-body"> <div class="price">$199.99</div> </div> </div> <!-- 改造后:语义化标签 --> <article class="product-card"> <section class="card-body"> <p class="price"> <time datetime="...">限时</time> $199.99 </p> </section> </article>
👁 = 👁
用户看到的页面没有任何区别
但 Google 爬虫和屏幕阅读器
能更好地理解页面结构
| 通用标签 | 语义化标签 | 告诉浏览器 |
|---|---|---|
<div> | <article> | "这是一个独立的内容块"(产品卡片、博客文章) |
<div> | <section> | "这是一个主题区域" |
<div> | <nav> | "这是导航链接" |
<div> | <header> | "这是页头" |
<div> | <footer> | "这是页脚" |
<div> | <main> | "这是页面主内容" |
<div> | <aside> | "这是侧边栏/附属内容" |
语义化标签对 SEO 有直接影响。Google 爬虫看到 <article> 就知道这是一个独立内容块(产品),看到 <nav> 就知道这是导航。用全是 <div> 的页面,Google 只能猜。在竞争激烈的关键词排名中,这些细节决定了你排第 3 还是第 13。
| # | 概念 | 一句话 | 对应步骤 |
|---|---|---|---|
| 1 | 标签 Tag | 用 <标签>内容</标签> 告诉浏览器内容的类型 | 步骤 1 |
| 2 | 属性 Attribute | 标签上的附加信息(图片地址、CSS 类名) | 步骤 2 |
| 3 | 嵌套 Nesting | 标签里套标签,形成树状结构 | 步骤 3 |
| 4 | class 类名 | 给标签起名,CSS 通过名字找到它设置样式 | 步骤 3-4 |
| 5 | CSS 选择器 | CSS 按标签名或 class 名定位目标元素 | 步骤 4 |
| 6 | 事件 Event | 用户操作(点击、悬停)触发 JS 函数 | 步骤 6 |
| 7 | 语义化标签 | 用 article/nav/main 替代无意义的 div,利好 SEO | 步骤 7 |