一、回顾与本篇目标
从第一篇到第八篇,我们走完了一条完整的路径:
- HTML:你学会了页面的骨架——标题、段落、链接、图片、列表、容器、class 和 id。
- CSS:你学会了页面的皮肤——选择器、颜色、字体、盒模型、圆角阴影、flex 居中。
- JavaScript:你学会了页面的行为——变量、数据类型、函数、条件判断、操作元素、响应点击事件。
这些知识点就像一堆零件,现在我们要把它们组装成一个完整的作品。
本篇的目标:从零开始,一步步搭建一个带交互的个人名片页面。它会包含头像、姓名、标签、技能列表、联系方式,以及三个交互功能——切换主题颜色、展开/收起详情、切换在线状态。
这不是一个“教学玩具”,而是一个你改改内容就能拿去用的真实页面。
二、成品预览:我们要做什么
在动手之前,先明确目标。最终页面会有以下功能:
- 一张居中显示的卡片,包含个人头像、姓名、简介、技能标签、联系方式。
- 一个“展开详情”按钮,点击后显示更多信息,再次点击收起。
- 一个“切换状态”按钮,在“在线”和“忙碌”之间切换,状态标签颜色随之改变。
- 一个“切换主题”按钮,在浅色主题和深色主题之间切换。
- 点击头像,头像会放大再缩小。
所有这些交互,都只用一个 HTML 文件完成,不需要任何外部依赖。
三、第一步:搭建 HTML 骨架
先把结构写出来。我们一层一层来。
基础框架
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>个人名片</title>
<style>
/* CSS 稍后填充 */
</style>
</head>
<body>
<!-- 卡片内容稍后填充 -->
<script>
// JavaScript 稍后填充
</script>
</body>
</html>
卡片结构
在 <body> 里放入卡片容器:
<div class="card">
<!-- 头像 -->
<img id="avatar" src="https://via.placeholder.com/100" alt="头像">
<!-- 姓名 -->
<h2 id="userName">张三</h2>
<!-- 状态标签 -->
<span id="statusBadge" class="status online">在线</span>
<!-- 简介 -->
<p class="bio" id="shortBio">前端开发学习者 | 热爱编程 | 终身学习</p>
<!-- 技能标签 -->
<div class="tags">
<span class="tag">HTML</span>
<span class="tag">CSS</span>
<span class="tag">JavaScript</span>
<span class="tag">盒模型</span>
<span class="tag">Flex 布局</span>
</div>
<!-- 按钮组 -->
<div class="buttons">
<button id="toggleDetailBtn">展开详情</button>
<button id="changeStatusBtn">切换状态</button>
<button id="themeToggleBtn">切换主题</button>
</div>
<!-- 详情区域(初始隐藏) -->
<div class="detail" id="detail">
<div class="detail-item">
<strong>📍 所在地</strong>
<span>上海</span>
</div>
<div class="detail-item">
<strong>💼 职业</strong>
<span>前端开发工程师(成长中)</span>
</div>
<div class="detail-item">
<strong>🎯 目标</strong>
<span>成为一名全栈工程师</span>
</div>
<div class="detail-item">
<strong>📧 邮箱</strong>
<span>zhangsan@example.com</span>
</div>
</div>
<!-- 联系方式 -->
<div class="contact">
<a href="mailto:zhangsan@example.com">📧 邮件</a>
<span>|</span>
<a href="https://github.com">💻 GitHub</a>
<span>|</span>
<a href="#">🐦 Twitter</a>
</div>
</div>
结构说明:
- 整个卡片被
<div class="card">包裹,这是之前学过的块级容器。 - 头像、姓名、状态标签、简介、技能标签、按钮、详情、联系方式——每个区域都有明确的标签和 class/id,为 CSS 和 JS 留好钩子。
id用于 JS 获取元素(avatar、userName、statusBadge、shortBio、detail、toggleDetailBtn、changeStatusBtn、themeToggleBtn)。class用于 CSS 样式和状态切换(card、status、online、tags、detail等)。
四、第二步:编写 CSS 样式
接下来是完整的样式代码。我们先写基础样式,再写主题相关的样式。
全局与卡片基础样式
/* === 全局样式 === */
* {
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: #f0f4f8;
font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", sans-serif;
transition: background 0.5s;
}
/* === 卡片 === */
.card {
background: white;
width: 400px;
padding: 40px 30px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
text-align: center;
transition: background 0.5s, box-shadow 0.5s;
}
注意 box-sizing: border-box:这是 CSS 中一个重要的全局设置。默认情况下,width 只控制内容区宽度,加上 padding 和 border 后元素会变宽。设置 box-sizing: border-box 后,width 控制的是从 border 内侧到另一侧 border 内侧的总宽度,padding 和 border 会被包含在内。这让尺寸计算更直观。
头像
.card img {
width: 100px;
height: 100px;
border-radius: 50%;
border: 3px solid #e0e0e0;
margin-bottom: 16px;
cursor: pointer;
transition: width 0.3s, height 0.3s, border-color 0.3s;
}
姓名与状态
.card h2 {
margin: 0 0 8px 0;
color: #2c3e50;
font-size: 24px;
transition: color 0.5s;
}
.card .status {
display: inline-block;
padding: 4px 16px;
border-radius: 20px;
font-size: 13px;
font-weight: bold;
margin-bottom: 16px;
transition: background 0.3s, color 0.3s;
}
/* 在线状态 */
.card .status.online {
background: #e8f5e9;
color: #2e7d32;
}
/* 忙碌状态 */
.card .status.busy {
background: #fff3e0;
color: #e65100;
}
这里预先定义了两个状态类:.online 和 .busy。JS 切换状态时,只需要更换这个 class 即可,不需要直接操作 style。
简介与技能标签
.card .bio {
color: #666;
font-size: 14px;
line-height: 1.6;
margin: 0 0 20px 0;
transition: color 0.5s;
}
.card .tags {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 24px;
}
.card .tag {
background: #eef2ff;
color: #4a6cf7;
padding: 6px 14px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
transition: background 0.5s, color 0.5s;
}
按钮
.card .buttons {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.card button {
padding: 10px 20px;
background: #4a6cf7;
color: white;
border: none;
border-radius: 8px;
font-size: 14px;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}
.card button:hover {
background: #3b5de7;
transform: translateY(-2px);
}
.card button:active {
transform: translateY(0);
}
新知识点:transform: translateY(-2px)——让按钮在鼠标悬停时向上移动 2 像素,制造“浮起来”的微动效。:active 是鼠标按下时的状态。
详情区域
.card .detail {
display: none; /* 初始隐藏 */
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
text-align: left;
transition: background 0.5s;
}
.card .detail .detail-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid #eee;
font-size: 14px;
color: #555;
transition: border-color 0.5s, color 0.5s;
}
.card .detail .detail-item:last-child {
border-bottom: none; /* 最后一项没有底部边框 */
}
.card .detail .detail-item strong {
color: #333;
transition: color 0.5s;
}
新知识点::last-child——伪类选择器,选中父容器中的最后一个子元素。这里用来去掉最后一条详情的底部边框,避免多余的线条。
联系方式
.card .contact {
font-size: 14px;
color: #999;
transition: color 0.5s;
}
.card .contact a {
color: #4a6cf7;
text-decoration: none;
transition: color 0.3s;
}
.card .contact a:hover {
text-decoration: underline;
}
.card .contact span {
margin: 0 6px;
}
深色主题样式
这些样式在 <body> 拥有 dark-theme 类时生效:
/* === 深色主题 === */
body.dark-theme {
background: #1a1a2e;
}
body.dark-theme .card {
background: #16213e;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
}
body.dark-theme .card h2 {
color: #e0e0e0;
}
body.dark-theme .card .bio {
color: #a0a0a0;
}
body.dark-theme .card .tag {
background: #0f3460;
color: #84a9f7;
}
body.dark-theme .card .detail {
background: #0f3460;
}
body.dark-theme .card .detail .detail-item {
color: #b0b0b0;
border-bottom-color: #1a3a5c;
}
body.dark-theme .card .detail .detail-item strong {
color: #d0d0d0;
}
body.dark-theme .card .contact {
color: #888;
}
body.dark-theme .card .contact a {
color: #84a9f7;
}
body.dark-theme .card img {
border-color: #333;
}
CSS 部分完成。总共有约 200 行,但每个小块都很清晰:基础 → 头像 → 姓名状态 → 简介标签 → 按钮 → 详情 → 联系方式 → 深色主题覆盖。
五、第三步:编写 JavaScript 交互
JS 代码实现四个交互功能。我们一个个来。
获取元素
首先,把所有需要操作的元素一次性获取并存入变量:
// 获取元素
let avatarEl = document.getElementById('avatar');
let statusBadge = document.getElementById('statusBadge');
let shortBioEl = document.getElementById('shortBio');
let detailEl = document.getElementById('detail');
let toggleDetailBtn = document.getElementById('toggleDetailBtn');
let changeStatusBtn = document.getElementById('changeStatusBtn');
let themeToggleBtn = document.getElementById('themeToggleBtn');
功能一:展开/收起详情
// 功能一:展开 / 收起详情
toggleDetailBtn.onclick = function() {
if (detailEl.style.display === 'block') {
detailEl.style.display = 'none';
toggleDetailBtn.textContent = '展开详情';
} else {
detailEl.style.display = 'block';
toggleDetailBtn.textContent = '收起详情';
}
};
逻辑和之前学的完全一样:判断当前 display 状态,然后切换并修改按钮文字。
功能二:切换在线状态
// 功能二:切换在线状态
changeStatusBtn.onclick = function() {
if (statusBadge.classList.contains('online')) {
// 当前在线 → 切换到忙碌
statusBadge.classList.remove('online');
statusBadge.classList.add('busy');
statusBadge.textContent = '忙碌';
shortBioEl.textContent = '正在学习中... | 暂时无法回复';
} else {
// 当前忙碌 → 切换回在线
statusBadge.classList.remove('busy');
statusBadge.classList.add('online');
statusBadge.textContent = '在线';
shortBioEl.textContent = '前端开发学习者 | 热爱编程 | 终身学习';
}
};
关键方法:classList.contains('类名')——检查元素是否有某个类,返回 true 或 false。
这里通过切换 class(.online ↔ .busy)来改变标签的配色,同时修改标签内的文字和简介行。CSS 中已经预先定义了 .online(绿色)和 .busy(橙色)的样式。
功能三:切换主题
// 功能三:切换浅色/深色主题
let isDarkTheme = false;
themeToggleBtn.onclick = function() {
if (isDarkTheme) {
document.body.classList.remove('dark-theme');
themeToggleBtn.textContent = '切换主题';
isDarkTheme = false;
} else {
document.body.classList.add('dark-theme');
themeToggleBtn.textContent = '浅色主题';
isDarkTheme = true;
}
};
用一个变量 isDarkTheme 记录当前状态。通过给 <body> 添加或移除 dark-theme 类,CSS 中所有 body.dark-theme 开头的规则就会自动生效或失效。
核心思想:JS 只负责切换 class,具体的颜色变化全部由 CSS 管理。这是“关注点分离”的体现。
功能四:点击头像放大/缩小
// 功能四:点击头像放大 / 缩小
avatarEl.onclick = function() {
if (avatarEl.style.width === '130px') {
avatarEl.style.width = '100px';
avatarEl.style.height = '100px';
} else {
avatarEl.style.width = '130px';
avatarEl.style.height = '130px';
}
};
直接修改头像的行内样式。CSS 中设置了 transition: width 0.3s, height 0.3s,所以放大缩小是平滑过渡的。
六、完整代码
把所有部分拼在一起,就是完整的个人名片页面。下面是可直接运行的完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人名片 - 张三</title>
<style>
/* ==================== 全局样式 ==================== */
* {
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: #f0f4f8;
font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", sans-serif;
transition: background 0.5s;
}
/* ==================== 卡片 ==================== */
.card {
background: white;
width: 400px;
padding: 40px 30px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
text-align: center;
transition: background 0.5s, box-shadow 0.5s;
}
/* ==================== 头像 ==================== */
.card img {
width: 100px;
height: 100px;
border-radius: 50%;
border: 3px solid #e0e0e0;
margin-bottom: 16px;
cursor: pointer;
transition: width 0.3s, height 0.3s, border-color 0.3s;
}
/* ==================== 姓名 ==================== */
.card h2 {
margin: 0 0 8px 0;
color: #2c3e50;
font-size: 24px;
transition: color 0.5s;
}
/* ==================== 状态标签 ==================== */
.card .status {
display: inline-block;
padding: 4px 16px;
border-radius: 20px;
font-size: 13px;
font-weight: bold;
margin-bottom: 16px;
transition: background 0.3s, color 0.3s;
}
.card .status.online {
background: #e8f5e9;
color: #2e7d32;
}
.card .status.busy {
background: #fff3e0;
color: #e65100;
}
/* ==================== 简介 ==================== */
.card .bio {
color: #666;
font-size: 14px;
line-height: 1.6;
margin: 0 0 20px 0;
transition: color 0.5s;
}
/* ==================== 技能标签 ==================== */
.card .tags {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 24px;
}
.card .tag {
background: #eef2ff;
color: #4a6cf7;
padding: 6px 14px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
transition: background 0.5s, color 0.5s;
}
/* ==================== 按钮 ==================== */
.card .buttons {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.card button {
padding: 10px 20px;
background: #4a6cf7;
color: white;
border: none;
border-radius: 8px;
font-size: 14px;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}
.card button:hover {
background: #3b5de7;
transform: translateY(-2px);
}
.card button:active {
transform: translateY(0);
}
/* ==================== 详情区域 ==================== */
.card .detail {
display: none;
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
text-align: left;
transition: background 0.5s;
}
.card .detail .detail-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid #eee;
font-size: 14px;
color: #555;
transition: border-color 0.5s, color 0.5s;
}
.card .detail .detail-item:last-child {
border-bottom: none;
}
.card .detail .detail-item strong {
color: #333;
transition: color 0.5s;
}
/* ==================== 联系方式 ==================== */
.card .contact {
font-size: 14px;
color: #999;
transition: color 0.5s;
}
.card .contact a {
color: #4a6cf7;
text-decoration: none;
transition: color 0.3s;
}
.card .contact a:hover {
text-decoration: underline;
}
.card .contact span {
margin: 0 6px;
}
/* ==================== 深色主题 ==================== */
body.dark-theme {
background: #1a1a2e;
}
body.dark-theme .card {
background: #16213e;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
}
body.dark-theme .card h2 {
color: #e0e0e0;
}
body.dark-theme .card .bio {
color: #a0a0a0;
}
body.dark-theme .card .tag {
background: #0f3460;
color: #84a9f7;
}
body.dark-theme .card .detail {
background: #0f3460;
}
body.dark-theme .card .detail .detail-item {
color: #b0b0b0;
border-bottom-color: #1a3a5c;
}
body.dark-theme .card .detail .detail-item strong {
color: #d0d0d0;
}
body.dark-theme .card .contact {
color: #888;
}
body.dark-theme .card .contact a {
color: #84a9f7;
}
body.dark-theme .card img {
border-color: #333;
}
</style>
</head>
<body>
<div class="card">
<!-- 头像 -->
<img id="avatar" src="https://via.placeholder.com/100" alt="张三的头像">
<!-- 姓名 -->
<h2 id="userName">张三</h2>
<!-- 状态标签 -->
<span id="statusBadge" class="status online">在线</span>
<!-- 简介 -->
<p class="bio" id="shortBio">前端开发学习者 | 热爱编程 | 终身学习</p>
<!-- 技能标签 -->
<div class="tags">
<span class="tag">HTML</span>
<span class="tag">CSS</span>
<span class="tag">JavaScript</span>
<span class="tag">盒模型</span>
<span class="tag">Flex 布局</span>
</div>
<!-- 按钮组 -->
<div class="buttons">
<button id="toggleDetailBtn">展开详情</button>
<button id="changeStatusBtn">切换状态</button>
<button id="themeToggleBtn">切换主题</button>
</div>
<!-- 详情区域 -->
<div class="detail" id="detail">
<div class="detail-item">
<strong>📍 所在地</strong>
<span>上海</span>
</div>
<div class="detail-item">
<strong>💼 职业</strong>
<span>前端开发工程师(成长中)</span>
</div>
<div class="detail-item">
<strong>🎯 目标</strong>
<span>成为一名全栈工程师</span>
</div>
<div class="detail-item">
<strong>📧 邮箱</strong>
<span>zhangsan@example.com</span>
</div>
</div>
<!-- 联系方式 -->
<div class="contact">
<a href="mailto:zhangsan@example.com">📧 邮件</a>
<span>|</span>
<a href="https://github.com" target="_blank">💻 GitHub</a>
<span>|</span>
<a href="#">🐦 Twitter</a>
</div>
</div>
<script>
// ==================== 获取元素 ====================
let avatarEl = document.getElementById('avatar');
let statusBadge = document.getElementById('statusBadge');
let shortBioEl = document.getElementById('shortBio');
let detailEl = document.getElementById('detail');
let toggleDetailBtn = document.getElementById('toggleDetailBtn');
let changeStatusBtn = document.getElementById('changeStatusBtn');
let themeToggleBtn = document.getElementById('themeToggleBtn');
// ==================== 功能一:展开 / 收起详情 ====================
toggleDetailBtn.onclick = function() {
if (detailEl.style.display === 'block') {
detailEl.style.display = 'none';
toggleDetailBtn.textContent = '展开详情';
} else {
detailEl.style.display = 'block';
toggleDetailBtn.textContent = '收起详情';
}
};
// ==================== 功能二:切换在线状态 ====================
changeStatusBtn.onclick = function() {
if (statusBadge.classList.contains('online')) {
statusBadge.classList.remove('online');
statusBadge.classList.add('busy');
statusBadge.textContent = '忙碌';
shortBioEl.textContent = '正在学习中... | 暂时无法回复';
} else {
statusBadge.classList.remove('busy');
statusBadge.classList.add('online');
statusBadge.textContent = '在线';
shortBioEl.textContent = '前端开发学习者 | 热爱编程 | 终身学习';
}
};
// ==================== 功能三:切换浅色/深色主题 ====================
let isDarkTheme = false;
themeToggleBtn.onclick = function() {
if (isDarkTheme) {
document.body.classList.remove('dark-theme');
themeToggleBtn.textContent = '切换主题';
isDarkTheme = false;
} else {
document.body.classList.add('dark-theme');
themeToggleBtn.textContent = '浅色主题';
isDarkTheme = true;
}
};
// ==================== 功能四:点击头像放大/缩小 ====================
avatarEl.onclick = function() {
if (avatarEl.style.width === '130px') {
avatarEl.style.width = '100px';
avatarEl.style.height = '100px';
} else {
avatarEl.style.width = '130px';
avatarEl.style.height = '130px';
}
};
</script>
</body>
</html>
七、代码结构与设计思路回顾
这个页面虽然代码量是系列之最(约 260 行),但结构非常清晰。回顾一下整体的设计思路:
分层架构:
- HTML:定义页面有什么——卡片、头像、姓名、标签、按钮、详情、链接。每个需要被 JS 操作的元素都有明确的
id。 - CSS:定义页面长什么样——浅色主题的完整样式 + 深色主题的覆盖样式。CSS 中预定义了
.online和.busy两个状态类的颜色。 - JavaScript:只做三件事——获取元素、监听事件、切换 class 或修改 style。JS 不直接写颜色值(除了头像放大),颜色的变化交给 CSS 的 class 切换来完成。
状态管理:
isDarkTheme变量记录当前主题状态。.online/.busyclass 记录当前在线状态。detailEl.style.display记录详情展开状态。
这种“用变量或 class 记录状态,根据状态决定行为”的模式,是前端开发中最核心的编程范式。以后学 React、Vue 等框架时,你会发现它们本质上也是在帮你管理这些状态。
八、本篇动手练习
练习 1:个性化改造(必做)
把名片改成你自己的。修改以下内容:
- 把姓名改成你的名字。
- 把头像换成一个真实的网络图片链接(可以用你的 GitHub 头像或其他图片)。
- 修改技能标签,换成你正在学习或已经掌握的技能。
- 修改详情中的所在地、职业、目标、邮箱。
- 修改联系方式中的链接(GitHub、Twitter 等换成你自己的链接)。
练习 2:增加新功能——第三个状态
在“在线”和“忙碌”之外,增加第三个状态“离线”。需要修改:
- CSS:增加
.status.offline样式(灰色背景 + 灰色文字)。 - JS:修改
changeStatusBtn的点击逻辑,让它在三个状态间循环切换。
练习 3:增加新功能——随机换背景色
添加一个新按钮“随机背景”,点击后把 <body> 的背景色换成一个随机的柔和颜色。提示:
- 准备一个包含若干颜色值的数组:
let colors = ['#f0f4f8', '#fef9e7', '#fdedec', '#eaf2f8', '#f5eef8']; - 用
Math.floor(Math.random() * colors.length)随机选取一个。 - 把选中的颜色赋给
document.body.style.background。
练习 4:代码组织优化
尝试把 JS 中四个功能的代码分别封装成四个函数:toggleDetail()、toggleStatus()、toggleTheme()、toggleAvatarSize()。然后在按钮的 onclick 中调用对应的函数。对比封装前后的代码,体会函数带来的清晰度提升。
九、本篇小结
这一篇你完成了一个完整的个人名片页面,综合运用了:
- HTML:完整的页面结构,
id和class的合理命名。 - CSS:盒模型、flex 布局、圆角、阴影、过渡动画、伪类选择器(
:hover、:active、:last-child)、主题切换的样式组织方式。 - JavaScript:获取元素、事件监听、
classList操作、条件判断、状态变量的使用。 - 设计思想:关注点分离(HTML 结构 / CSS 样式 / JS 行为各司其职)、用 class 切换代替直接操作 style、用变量记录状态。
这个名片页面是你前端学习之路的第一个完整作品。虽然只有 260 行代码,但它包含了现代前端开发的核心模式。把这个页面吃透,改造成你自己的版本,甚至可以把它部署到网上,作为你的个人名片页。
系列小结与下一步
《前端圭臬·零基础入门专题》到此告一段落。 九篇文章,从一行代码都看不懂,到能写出一个带深色模式、状态切换、交互反馈的个人名片页面——你走完了一条完整的前端入门之路。
你学到了:
- HTML 的核心标签与页面结构
- CSS 的选择器、盒模型与 flex 布局
- JavaScript 的变量、函数、条件判断与 DOM 操作
- 事件驱动的交互编程模式
- HTML + CSS + JS 三者协作开发一个完整页面
接下来你可以做什么:
- 巩固基础:把九篇的练习都独立做一遍,不看代码,自己手写。
- 拓展技能:继续阅读《前端圭臬》主系列,深入学习 CSS 核心机制和 JavaScript 执行原理。
- 做项目:尝试做一个你自己的项目——比如个人博客首页、产品介绍页、相册展示页。用你学到的 HTML + CSS + JS 从零搭建。
- 学习框架:当你觉得原生 HTML/CSS/JS 已经能熟练运用时,可以开始学习 React 或 Vue 等前端框架,它们会让开发效率大幅提升。
前端的世界广阔而有趣。这九篇文章只是一个起点,但它们足够稳固——因为每一步都建立在对底层原理的理解之上,而不是对框架 API 的死记硬背。这正是《前端圭臬》系列的核心理念。
祝你在前端的路上越走越远。
前端·零基础入门专题,完。













暂无评论内容