用 HTML + CSS +JavaScript 搭建网站
简单上手
前端三剑客
HTML、CSS、JavaScript 被称为前端三剑客,即网页的前端开发中构建网页的三种核心技术,纯前端开发足以满足以内容展示为主的网页搭建。
- HTML:超文本标记语言,将排版信息代码化,负责页面的结构和内容
- CSS:层叠样式表,定义各种样式名称和效果,在HTML文件中直接引用这些样式,负责页面的样式和布局
- JavaScript:脚本语言,实现网页的动态功能,如滚动、点击、输入等操作,负责页面的交互逻辑和动态行为
文件层级结构
一个完整的网页前端.html文件,按顺序为 CSS 样式表、HTML 信息、JavaScript 代码。这里写一个简单的页面,可以直接复制下来,新建一个 txt 文档,将内容粘贴进去保存后,将文档后缀改为html,用浏览器打开:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HOME</title> <style> body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: #000000; } h1 { font-size: 4rem; color: #ffffff; cursor: pointer; padding: 10px; border-radius: 5px; } h1:hover { background-color: #2f2f2f; } </style> </head> <body> <h1 id="home-title">HOME</h1>
<script>
const homeTitle = document.getElementById('home-title'); homeTitle.addEventListener('click', function() { location.reload(); }); </script> </body> </html>
|
这个网站的效果是,正中一个大大的HOME,黑底白字,鼠标悬停显示灰色背景,点击刷新页面。可以看到,三者的注释方式也不同。这是将CSS、JavaScript一起写在HTML中的样子,由于这里还是HTML的地盘,CSS用<style></style>包裹起来,JavaScript用<script></script>包裹起来。
我们命名这个文件为home.html。当然我们可以将CSS部分分离出来创建home.css文件,将JavaScript部分分离出来创建home.js文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: #000000; }
h1 { font-size: 4rem; color: #ffffff; cursor: pointer; padding: 10px; border-radius: 5px; }
h1:hover { background-color: #2f2f2f; }
|
1 2 3 4 5 6 7 8
| const homeTitle = document.getElementById('home-title');
homeTitle.addEventListener('click', function() { location.reload(); });
|
然后在HTML中原CSS和JavaScript处引用这些文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HOME</title> <link rel="stylesheet" href="home.css"> </head> <body> <h1 id="home-title">HOME</h1>
<script src="home.js"></script>> </body> </HTML>
|
这样将三个文件放在一起一个目录下时,便能实现一样的效果。分开管理css和js文件能够提高网站的可维护性,谁也不想在动辄几百上千行的html里找一个样式名称。
随着页面增多,我们可以按需创建global.css和global.js放一些通用的样式,不同页面的特定样式或交互逻辑,则放在如home.css、home.js、page2.css、page2.js等专有文件中。建立一个css文件夹放.css文件,建立一个js文件夹放.js文件,对应的之前引用文件的地址则改为:
1 2
| <link rel="stylesheet" href="css/home.css"> <script src="js/home.js"></script>>
|
一个健康的文件层级应该是:
css/ - 存放CSS样式文件
js/ - 存放JavaScript脚本文件
images/ - 存放图片资源
fonts/ - 存放自定义字体文件
pages/ - 存放除首页外的其他HTML页面
assets/ - 存放其他静态资源,如文档、下载文件等
index.html - 主入口HTML页面
README.md - 项目说明文档
一个html模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <!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="styles.css"> </head> <body>
<header> <h1>网站标题/Logo</h1> <nav> <ul> <li><a href="#">首页</a></li> <li><a href="#">关于我们</a></li> <li><a href="#">联系我们</a></li> </ul> </nav> </header>
<main> <section> <h2>区块标题</h2> <p>这里是内容段落...</p> </section> <article> <h2>文章标题</h2> <p>文章内容...</p> </article> </main>
<aside> <h3>侧边栏标题</h3> <p>侧边栏内容...</p> </aside>
<footer> <p>© 2023 公司名称 版权所有</p> </footer>
<script src="script.js"></script> </body> </html>
|
这个文档模板中出现的如nav、section等,都是容器的名称,即我在这个地方放置一个名为nav的容器,将导航链接这些元素放在这个容器里。这个容器的样式,以及容器内元素的样式则都在css文件中定义。
HTML:构建网页的骨架
HTML使用一系列标签来定义内容和结构。以下是一些常用标签:
常用HTML标签
- 标题:
<h1> 到 <h6>,重要性依次递减
- 段落:
<p>
- 链接:
<a href="url">链接文本</a>
- 图片:
<img src="image.jpg" alt="图片描述">
- 列表:
- 无序列表:
<ul> 和 <li>
- 有序列表:
<ol> 和 <li>
- 分区:
<div> (块级) 和 <span> (行内)
- 表单:
1 2 3 4 5 6
| <form> <input type="text" placeholder="请输入文本"> <input type="email" placeholder="请输入邮箱"> <input type="password" placeholder="请输入密码"> <button type="submit">提交</button> </form>
|
HTML5 语义化标签
HTML5引入了语义化标签,让结构更清晰,也利于SEO:
<header>: 页眉
<nav>: 导航栏
<main>: 主要内容
<article>: 独立文章
<section>: 文档中的节
<aside>: 侧边栏
<footer>: 页脚
尽量使用语义化标签,而不是全部用<div>。
CSS:为网页添加样式
CSS控制网页的表现形式,包括布局、颜色、字体等。
CSS的三种引入方式
- 内联样式:直接在HTML标签的
style属性中编写1
| <h1 style="color: blue; font-size: 24px;">标题</h1>
|
- 内部样式表:在HTML的
<style>标签中编写
- 外部样式表:在单独的
.css文件中编写,通过<link>引入(推荐)
CSS选择器
选择器用于指定要样式化的HTML元素:
- 元素选择器:
p { color: red; }
- 类选择器:
.className { font-size: 16px; } (在HTML中使用class="className")
- ID选择器:
#idName { background: yellow; } (在HTML中使用id="idName")
- 后代选择器:
div p { margin: 10px; } (选择<div>内的所有<p>)
盒模型
CSS盒模型是布局的基础,每个元素都被视为一个矩形盒子,包括:
- 内容:
width, height
- 内边距:
padding
- 边框:
border
- 外边距:
margin
1 2 3 4 5 6
| .box { width: 300px; padding: 20px; border: 5px solid black; margin: 10px; }
|
常用CSS属性
- 文本:
color, font-size, font-family, text-align, line-height
- 背景:
background-color, background-image
- 布局:
display (block, inline, inline-block, flex, grid), position (static, relative, absolute, fixed)
Flexbox 布局
Flexbox是一种一维布局模型,非常适合居中和对齐元素:
1 2 3 4 5 6
| .container { display: flex; justify-content: center; align-items: center; flex-direction: row; }
|
JavaScript:实现网页交互
JavaScript是一种动态编程语言,可以为网页添加复杂的交互行为。
基本语法
- 变量声明:
1 2
| let name = "张三"; const age = 25;
|
- 数据类型: String, Number, Boolean, Array, Object
- 函数:
1 2 3 4 5
| function greet(name) { return "Hello, " + name; }
const greet = (name) => "Hello, " + name;
|
- 条件语句:
1 2 3 4 5
| if (age >= 18) { console.log("成年人"); } else { console.log("未成年人"); }
|
- 循环:
1 2 3
| for (let i = 0; i < 5; i++) { console.log(i); }
|
DOM 操作
DOM(文档对象模型)是HTML文档的编程接口,JavaScript可以通过DOM动态修改页面:
- 选择元素:
1 2 3 4 5 6
| const title = document.getElementById('home-title'); const paragraphs = document.getElementsByTagName('p'); const boxes = document.getElementsByClassName('box');
const element = document.querySelector('#id'); const elements = document.querySelectorAll('.class');
|
- 修改内容:
1 2
| title.textContent = "新的标题"; title.innerHTML = "<em>强调的标题</em>";
|
- 修改样式:
1 2
| title.style.color = "red"; title.style.fontSize = "2rem";
|
- 添加/删除元素:
1 2 3 4 5 6 7
| const newParagraph = document.createElement('p'); newParagraph.textContent = "我是新段落!"; document.body.appendChild(newParagraph);
const oldElement = document.getElementById('old'); oldElement.remove();
|
事件处理
JavaScript可以响应用户的各种操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const button = document.getElementById('myButton');
button.addEventListener('click', function() { alert('按钮被点击了!'); });
const form = document.getElementById('myForm'); form.addEventListener('submit', function(event) { event.preventDefault(); const inputValue = document.getElementById('myInput').value; console.log('用户输入:', inputValue); });
|
实战:创建一个交互式待办事项列表
咱们创建一个简单的待办事项应用:
HTML (todo.html):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!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="css/todo.css"> </head> <body> <div class="container"> <h1>我的待办事项</h1> <form id="todo-form"> <input type="text" id="todo-input" placeholder="添加新任务..." required> <button type="submit">添加</button> </form> <ul id="todo-list"></ul> </div> <script src="js/todo.js"></script> </body> </html>
|
CSS (css/todo.css):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| body { font-family: Arial, sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; }
.container { max-width: 500px; margin: 0 auto; background: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
h1 { text-align: center; color: #333; }
#todo-form { display: flex; margin-bottom: 20px; }
#todo-input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 3px; }
button { padding: 10px 15px; background: #007bff; color: white; border: none; border-radius: 3px; cursor: pointer; margin-left: 10px; }
button:hover { background: #0056b3; }
ul { list-style: none; padding: 0; }
li { padding: 10px; border-bottom: 1px solid #ddd; display: flex; justify-content: space-between; align-items: center; }
li:last-child { border-bottom: none; }
.completed { text-decoration: line-through; color: #888; }
.delete-btn { background: #dc3545; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; }
|
JavaScript (js/todo.js):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| const todoForm = document.getElementById('todo-form'); const todoInput = document.getElementById('todo-input'); const todoList = document.getElementById('todo-list');
document.addEventListener('DOMContentLoaded', loadTodos);
todoForm.addEventListener('submit', function(event) { event.preventDefault(); const todoText = todoInput.value.trim(); if (todoText !== '') { addTodoItem(todoText); saveTodoToLocalStorage(todoText); todoInput.value = ''; } });
function addTodoItem(text, completed = false) { const li = document.createElement('li'); const span = document.createElement('span'); span.textContent = text; if (completed) { span.classList.add('completed'); } span.addEventListener('click', function() { this.classList.toggle('completed'); updateLocalStorage(); }); const deleteBtn = document.createElement('button'); deleteBtn.textContent = '删除'; deleteBtn.classList.add('delete-btn'); deleteBtn.addEventListener('click', function() { li.remove(); updateLocalStorage(); }); li.appendChild(span); li.appendChild(deleteBtn); todoList.appendChild(li); }
function saveTodoToLocalStorage(text) { let todos = getTodosFromLocalStorage(); todos.push({ text, completed: false }); localStorage.setItem('todos', JSON.stringify(todos)); }
function getTodosFromLocalStorage() { let todos = localStorage.getItem('todos'); return todos ? JSON.parse(todos) : []; }
function loadTodos() { let todos = getTodosFromLocalStorage(); todos.forEach(todo => { addTodoItem(todo.text, todo.completed); }); }
function updateLocalStorage() { let todos = []; document.querySelectorAll('#todo-list li').forEach(li => { const text = li.querySelector('span').textContent; const completed = li.querySelector('span').classList.contains('completed'); todos.push({ text, completed }); }); localStorage.setItem('todos', JSON.stringify(todos)); }
|
响应式设计
响应式设计确保网站在不同设备上都能良好显示。实现响应式的关键技术:
1. 视口设置
1
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
2. 媒体查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| .container { width: 100%; padding: 10px; }
@media (min-width: 768px) { .container { width: 750px; margin: 0 auto; } }
@media (min-width: 1024px) { .container { width: 980px; } }
|
3. 弹性布局
使用Flexbox或Grid布局,它们天生具有响应式特性。
调试技巧
- 浏览器开发者工具:按F12打开,可以检查元素、查看CSS、调试JavaScript
- Console:使用
console.log()输出变量值,帮助调试
- 断点调试:在开发者工具的Sources面板中设置断点,逐步执行代码
部署网站
完成网站开发后,你可以通过以下方式让其他人访问:
GitHub Pages(免费):
- 在GitHub上创建仓库
- 上传你的网站文件
- 在仓库设置中启用GitHub Pages
Netlify/Vercel(免费):
- 拖拽你的网站文件夹到上传区域
- 或连接GitHub仓库自动部署
传统虚拟主机:
进一步学习
掌握了HTML、CSS和JavaScript的基础后,可以继续学习:
- CSS预处理器:Sass/Less
- CSS框架:Bootstrap、Tailwind CSS
- JavaScript框架:Vue.js、React、Angular
- 版本控制:Git
- 构建工具:Webpack、Vite