1. 引言
前端开发,绕不开三个核心技术:HTML、CSS、JavaScript。它们共同构成了浏览器中几乎所有网页的基础。
简单来说,三者的分工是:
- HTML 负责网页的结构与内容,回答「页面上有什么」。
- CSS 负责网页的表现与样式,回答「页面长什么样」。
- JavaScript 负责网页的行为与交互,回答「页面能做什么」。
如果把一个网页比作一栋房子:
- HTML 是房子的钢筋水泥与房间布局;
- CSS 是装修、配色与家具摆放;
- JavaScript 是电路、门窗开关、智能家居等让房子「动起来」的部分。
2. HTML:网页的结构
2.1 什么是 HTML
HTML 的全称是 HyperText Markup Language,即「超文本标记语言」。它并不是编程语言,而是一种用于描述网页结构的标记语言。
HTML 通过一系列**标签(Tag)**来组织内容。浏览器读取 HTML 文件后,会将其解析为一棵 DOM 树,并根据标签语义把内容渲染到页面上。
2.2 HTML 文档的基本结构
一个标准的 HTML 文档通常如下:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
</head>
<body>
<h1>欢迎来到我的网站</h1>
<p>这是一个段落。</p>
</body>
</html>
各部分的含义如下:
<!DOCTYPE html>:声明文档类型,告诉浏览器使用 HTML5 标准解析页面。<html>:整个 HTML 文档的根元素。<head>:头部区域,存放元信息,如字符编码、页面标题、样式表引用等,通常不直接显示在页面中。<body>:主体区域,所有可见内容都写在这里。
2.3 常见标签
2.3.1 标题标签
HTML 提供了 6 级标题,从 <h1> 到 <h6>,数字越小,标题级别越高、字号通常越大。
html
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
2.3.2 段落与文本标签
html
<p>这是一个段落。</p>
<span>这是一个行内文本。</span>
<strong>加粗强调文本</strong>
<em>斜体强调文本</em>
<br>
其中 <br> 是换行标签,它是一个自闭合标签。
2.3.3 列表标签
有序列表使用 <ol>,无序列表使用 <ul>,每一项使用 <li>:
html
<ul>
<li>前端</li>
<li>后端</li>
<li>数据库</li>
</ul>
<ol>
<li>第一步:学习 HTML</li>
<li>第二步:学习 CSS</li>
<li>第三步:学习 JavaScript</li>
</ol>
2.3.4 链接与图片
链接使用 <a> 标签,图片使用 <img> 标签:
html
<a href="https://www.example.com">访问示例网站</a>
<img src="./image.png" alt="示例图片">
href:链接目标地址。src:图片地址。alt:图片无法显示时给出的替代文本,对可访问性和 SEO 都很重要。
2.4 块级元素与行内元素
HTML 元素大致可以分为两类:
- 块级元素 :通常独占一行,可以设置宽高,如
<div>、<p>、<h1>、<ul>等。 - 行内元素 :不会独占一行,宽度由内容决定,如
<span>、<a>、<strong>等。
示例:
html
<div>我是一个块级元素</div>
<div>我是另一个块级元素</div>
<span>我是一个行内元素</span>
<span>我是另一个行内元素</span>
2.5 语义化标签
HTML5 引入了许多语义化标签,使页面结构更加清晰:
html
<header>页眉</header>
<nav>导航栏</nav>
<main>主要内容</main>
<article>文章内容</article>
<section>章节内容</section>
<aside>侧边栏</aside>
<footer>页脚</footer>
语义化标签不仅方便开发者阅读,也有利于搜索引擎优化和无障碍访问。例如,使用 <nav> 代替普通 <div>,可以让搜索引擎更容易识别导航区域。
3. CSS:网页的样式
3.1 什么是 CSS
CSS 的全称是 Cascading Style Sheets,即「层叠样式表」。它用于控制网页的布局、颜色、字体、间距等视觉表现。
CSS 的核心思想是选择器 + 声明。通过选择器选中 HTML 元素,然后通过声明设置样式。
3.2 CSS 的三种引入方式
3.2.1 内联样式
直接在 HTML 标签上使用 style 属性:
html
<p style="color: red; font-size: 16px;">这是红色文字。</p>
3.2.2 内部样式表
在 <head> 中使用 <style> 标签:
html
<head>
<style>
p {
color: red;
font-size: 16px;
}
</style>
</head>
3.2.3 外部样式表
将 CSS 写入独立文件,再通过 <link> 引入:
html
<head>
<link rel="stylesheet" href="style.css">
</head>
style.css 文件内容:
css
p {
color: red;
font-size: 16px;
}
实际开发中推荐使用外部样式表,便于维护和复用。
3.3 CSS 选择器
选择器用于指定样式作用于哪些元素。常见选择器如下:
css
/* 元素选择器 */
p {
color: blue;
}
/* 类选择器 */
.title {
font-size: 24px;
}
/* ID 选择器 */
#main {
width: 800px;
}
/* 后代选择器 */
div p {
line-height: 1.6;
}
/* 伪类选择器 */
a:hover {
color: orange;
}
常见选择器优先级从高到低大致为:
- 内联样式
- ID 选择器
- 类选择器、属性选择器、伪类选择器
- 元素选择器、伪元素选择器
如果优先级相同,则后定义的样式会覆盖先定义的样式。
3.4 盒模型
盒模型是 CSS 布局的基础。每一个元素在页面中都可以看作一个矩形盒子,由四部分组成:
- content:内容区域
- padding:内边距,内容与边框之间的空间
- border:边框
- margin:外边距,元素与其他元素之间的空间
示意图:
text
+---------------------------+
| margin |
| +---------------------+ |
| | border | |
| | +---------------+ | |
| | | padding | | |
| | | +---------+ | | |
| | | | content | | | |
| | | +---------+ | | |
| | +---------------+ | |
| +---------------------+ |
+---------------------------+
示例:
css
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid #333;
margin: 10px;
}
默认情况下,width 和 height 只作用于 content。如果希望 width 包含 padding 和 border,可以设置:
css
* {
box-sizing: border-box;
}
这样布局计算会更加直观,许多 CSS 框架都默认采用这种方式。
3.5 常见布局方式
3.5.1 传统流式布局
块级元素自上而下排列,行内元素自左向右排列。通过 display 属性可以改变元素的排版方式:
css
.box {
display: block; /* 块级 */
display: inline; /* 行内 */
display: inline-block; /* 行内块 */
display: none; /* 隐藏 */
}
3.5.2 Flexbox 弹性布局
Flexbox 是一维布局模型,非常适合处理单行或单列的排列、对齐与空间分配:
css
.container {
display: flex;
justify-content: space-between;
align-items: center;
}
常见属性:
justify-content:主轴对齐方式,如flex-start、center、space-between。align-items:交叉轴对齐方式,如stretch、center、flex-end。flex-direction:主轴方向,如row、column、row-reverse。
3.5.3 Grid 网格布局
Grid 是二维布局模型,可以同时控制行和列:
css
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr;
gap: 16px;
}
其中 1fr 表示占据剩余空间。Grid 适合处理更复杂的整体页面布局。
3.6 响应式设计
响应式设计让同一个网页在不同屏幕尺寸下都能有良好的显示效果。核心是媒体查询:
css
/* 屏幕宽度小于等于 600px 时生效 */
@media (max-width: 600px) {
.container {
flex-direction: column;
}
}
通过媒体查询,可以在手机端将横向排列的元素改为纵向排列,避免内容被压缩。
4. JavaScript:网页的行为
4.1 什么是 JavaScript
JavaScript 是一门运行在浏览器中的脚本语言,用于实现网页的动态效果与交互逻辑。它遵循 ECMAScript 标准,是目前前端开发的核心语言。
需要特别说明的是,JavaScript 与 Java 是完全不同的两门语言,两者只是名字相似。
4.2 在 HTML 中引入 JavaScript
4.2.1 内部脚本
在 HTML 中使用 <script> 标签:
html
<script>
console.log('Hello, JavaScript!');
</script>
4.2.2 外部脚本
将 JavaScript 写入独立文件,再通过 src 属性引入:
html
<script src="app.js"></script>
app.js 文件内容:
javascript
console.log('Hello, JavaScript!');
如果脚本会操作 DOM 元素,通常需要将 <script> 放在 <body> 底部,或使用 defer 属性,确保 HTML 元素已经加载完成。
4.3 基本语法
4.3.1 变量声明
现代 JavaScript 推荐使用 let 和 const 声明变量:
javascript
let name = 'Alice'; // 可变变量
const age = 25; // 不可变常量
const 声明后不能重新赋值,适合用来保存不会改变的值。
4.3.2 数据类型
常见数据类型包括:
- 字符串:
'hello' - 数字:
123 - 布尔值:
true、false - 数组:
[1, 2, 3] - 对象:
{ name: 'Alice', age: 25 } null与undefined
示例:
javascript
const message = 'Hello';
const count = 10;
const isLogin = true;
const list = ['HTML', 'CSS', 'JavaScript'];
const user = {
name: 'Alice',
age: 25,
};
4.3.3 函数
函数用于封装可复用的逻辑:
javascript
function greet(name) {
return 'Hello, ' + name + '!';
}
console.log(greet('Alice'));
也可以使用箭头函数:
javascript
const add = (a, b) => a + b;
console.log(add(1, 2)); // 3
4.3.4 条件与循环
javascript
const score = 85;
if (score >= 90) {
console.log('优秀');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
const fruits = ['苹果', '香蕉', '橙子'];
for (const fruit of fruits) {
console.log(fruit);
}
4.4 DOM 操作
DOM 是 Document Object Model 的缩写,即文档对象模型。JavaScript 可以通过 DOM API 获取、创建、修改和删除页面元素。
4.4.1 获取元素
javascript
const title = document.getElementById('title');
const items = document.querySelectorAll('.item');
const firstItem = document.querySelector('.item');
getElementById:通过 ID 获取元素。querySelector:通过 CSS 选择器获取第一个匹配元素。querySelectorAll:获取所有匹配元素。
4.4.2 修改内容与样式
javascript
const title = document.getElementById('title');
title.textContent = '新的标题';
title.style.color = 'red';
4.4.3 创建与添加元素
javascript
const list = document.getElementById('list');
const newItem = document.createElement('li');
newItem.textContent = '新项目';
list.appendChild(newItem);
4.4.4 事件处理
事件是用户与页面交互的入口。常见事件包括点击、输入、鼠标移动等:
javascript
const button = document.getElementById('btn');
button.addEventListener('click', function () {
alert('按钮被点击了!');
});
4.5 异步编程简介
JavaScript 是单线程语言,但可以通过异步机制处理耗时操作,例如网络请求、定时器等,避免阻塞页面。
4.5.1 setTimeout
javascript
setTimeout(() => {
console.log('2 秒后执行');
}, 2000);
4.5.2 Promise
Promise 用于表示一个异步操作的最终结果:
javascript
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据获取成功');
}, 1000);
});
};
fetchData().then((result) => {
console.log(result);
});
4.5.3 async / await
async 和 await 让异步代码看起来像同步代码:
javascript
async function loadData() {
const result = await fetchData();
console.log(result);
}
loadData();
4.6 ES6 常用新特性
4.6.1 模板字符串
使用反引号可以在字符串中嵌入变量:
javascript
const name = 'Alice';
const message = `你好,${name}!`;
console.log(message);
4.6.2 解构赋值
javascript
const user = { name: 'Alice', age: 25 };
const { name, age } = user;
const numbers = [1, 2, 3];
const [first, second] = numbers;
4.6.3 展开运算符
javascript
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
4.6.4 模块化
JavaScript 支持使用 import 和 export 组织代码:
javascript
// utils.js
export function sum(a, b) {
return a + b;
}
// main.js
import { sum } from './utils.js';
console.log(sum(1, 2));
5. 三者的协作关系
HTML、CSS 和 JavaScript 并不是彼此孤立的技术,而是通过浏览器紧密协作:
- 浏览器加载 HTML 文件。
- 解析 HTML 结构,构建 DOM 树。
- 加载并解析 CSS 文件,生成样式规则。
- 将样式应用到 DOM 上,完成页面渲染。
- 加载并执行 JavaScript,实现动态交互。
一个常见的协作流程如下:
#mermaid-svg-b0WknvlIPMhrGHDd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-b0WknvlIPMhrGHDd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-b0WknvlIPMhrGHDd .error-icon{fill:#552222;}#mermaid-svg-b0WknvlIPMhrGHDd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-b0WknvlIPMhrGHDd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-b0WknvlIPMhrGHDd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-b0WknvlIPMhrGHDd .marker.cross{stroke:#333333;}#mermaid-svg-b0WknvlIPMhrGHDd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-b0WknvlIPMhrGHDd p{margin:0;}#mermaid-svg-b0WknvlIPMhrGHDd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-b0WknvlIPMhrGHDd .cluster-label text{fill:#333;}#mermaid-svg-b0WknvlIPMhrGHDd .cluster-label span{color:#333;}#mermaid-svg-b0WknvlIPMhrGHDd .cluster-label span p{background-color:transparent;}#mermaid-svg-b0WknvlIPMhrGHDd .label text,#mermaid-svg-b0WknvlIPMhrGHDd span{fill:#333;color:#333;}#mermaid-svg-b0WknvlIPMhrGHDd .node rect,#mermaid-svg-b0WknvlIPMhrGHDd .node circle,#mermaid-svg-b0WknvlIPMhrGHDd .node ellipse,#mermaid-svg-b0WknvlIPMhrGHDd .node polygon,#mermaid-svg-b0WknvlIPMhrGHDd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-b0WknvlIPMhrGHDd .rough-node .label text,#mermaid-svg-b0WknvlIPMhrGHDd .node .label text,#mermaid-svg-b0WknvlIPMhrGHDd .image-shape .label,#mermaid-svg-b0WknvlIPMhrGHDd .icon-shape .label{text-anchor:middle;}#mermaid-svg-b0WknvlIPMhrGHDd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-b0WknvlIPMhrGHDd .rough-node .label,#mermaid-svg-b0WknvlIPMhrGHDd .node .label,#mermaid-svg-b0WknvlIPMhrGHDd .image-shape .label,#mermaid-svg-b0WknvlIPMhrGHDd .icon-shape .label{text-align:center;}#mermaid-svg-b0WknvlIPMhrGHDd .node.clickable{cursor:pointer;}#mermaid-svg-b0WknvlIPMhrGHDd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-b0WknvlIPMhrGHDd .arrowheadPath{fill:#333333;}#mermaid-svg-b0WknvlIPMhrGHDd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-b0WknvlIPMhrGHDd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-b0WknvlIPMhrGHDd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b0WknvlIPMhrGHDd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-b0WknvlIPMhrGHDd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b0WknvlIPMhrGHDd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-b0WknvlIPMhrGHDd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-b0WknvlIPMhrGHDd .cluster text{fill:#333;}#mermaid-svg-b0WknvlIPMhrGHDd .cluster span{color:#333;}#mermaid-svg-b0WknvlIPMhrGHDd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-b0WknvlIPMhrGHDd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-b0WknvlIPMhrGHDd rect.text{fill:none;stroke-width:0;}#mermaid-svg-b0WknvlIPMhrGHDd .icon-shape,#mermaid-svg-b0WknvlIPMhrGHDd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b0WknvlIPMhrGHDd .icon-shape p,#mermaid-svg-b0WknvlIPMhrGHDd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-b0WknvlIPMhrGHDd .icon-shape .label rect,#mermaid-svg-b0WknvlIPMhrGHDd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b0WknvlIPMhrGHDd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-b0WknvlIPMhrGHDd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-b0WknvlIPMhrGHDd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 浏览器加载 HTML
解析 HTML 构建 DOM 树
加载并解析 CSS
应用样式完成渲染
加载并执行 JavaScript
实现动态交互
6. 综合实例:一个待办事项列表
下面通过一个完整小例子,展示 HTML、CSS、JavaScript 如何配合工作。
6.1 HTML 结构
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>待办事项列表</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="container">
<h1>待办事项</h1>
<div class="input-area">
<input id="todo-input" type="text" placeholder="请输入待办事项">
<button id="add-btn">添加</button>
</div>
<ul id="todo-list"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
6.2 CSS 样式
css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f6fa;
display: flex;
justify-content: center;
padding-top: 60px;
}
.container {
width: 400px;
background: #ffffff;
padding: 24px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 22px;
margin-bottom: 16px;
}
.input-area {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
#todo-input {
flex: 1;
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 6px;
}
#add-btn {
padding: 8px 16px;
border: none;
border-radius: 6px;
background-color: #4c6ef5;
color: #ffffff;
cursor: pointer;
}
#todo-list {
list-style: none;
}
#todo-list li {
padding: 10px 12px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
#todo-list li.done {
text-decoration: line-through;
color: #999;
}
6.3 JavaScript 行为
javascript
const input = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const todoList = document.getElementById('todo-list');
function addTodo() {
const text = input.value.trim();
if (text === '') {
alert('请输入待办事项');
return;
}
const item = document.createElement('li');
item.textContent = text;
item.addEventListener('click', function () {
item.classList.toggle('done');
});
todoList.appendChild(item);
input.value = '';
input.focus();
}
addBtn.addEventListener('click', addTodo);
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
addTodo();
}
});
在这个例子中:
- HTML 搭建了输入框、按钮和列表等结构;
- CSS 负责整体外观、布局和交互状态样式;
- JavaScript 负责添加待办事项、标记完成状态等交互逻辑。
大家可以自己试一下,看看呈现出来的结果是什么样的。
7. 学习路径
前端学习通常可以遵循以下路径:
- 入门阶段:掌握 HTML 常用标签,能独立写出结构清晰的静态页面。
- 样式阶段:学习 CSS 选择器、盒模型、Flexbox 和 Grid,能还原常见页面布局。
- 交互阶段:学习 JavaScript 基础语法、DOM 操作和事件处理,能实现页面动态交互。
- 工程化阶段:接触 npm、构建工具、框架等内容,如 React、Vue、Webpack、Vite。
- 进阶阶段:了解浏览器工作原理、性能优化、网络请求、TypeScript 等。
对于初学者,建议先用纯 HTML、CSS、JavaScript 完成几个小项目,再逐步引入框架和构建工具,这样基础会更加扎实。