☰
零基础HTML入门:用自我简介网页掌握语义化结构与常用标签
2026/10/2 5:16:48 网站建设 项目流程

做前端这些年,被问得最多的问题之一就是:零基础想入门HTML,第一个页面写什么比较合适。我的答案一直没变过——自我简介网页。原因很朴素,它体量小、需求明确、结果肉眼可见,而且几乎把HTML结构里最常用的那批标签都用上了。更关键的一点是,这个页面写完你能立刻发给朋友看,有正反馈,学起来不容易半途而废。所以这篇我把当年自己练手、后来带新人时反复在用的那套自我简介网页结构完整拆开讲一遍,从第一行doctype到最后一行footer,每一块为什么这么写、能不能换个写法、换了会出什么问题,都尽量说透。内容适合刚接触网页的朋友,也适合写了几年但一直是div堆到底、想回头补一补语义化结构的人。

1. 为什么我建议从自我简介网页入手练HTML结构

1.1 一个页面就能覆盖大半个基础标签体系

别看自我简介网页信息量小,它的覆盖面其实一点不小。一个人的信息无非几类:姓名、头像、一句话介绍、联系方式、教育或工作经历、技能清单、做过的项目。这几类信息拆到HTML标签上,正好对应标题标签h1到h3、段落p、图片img、超链接a、无序列表ul加li、有序列表ol、描述列表dl加dt加dd,再往下还能用上table做时间线、用section和article做分区、用footer放联系方式。也就是说,认认真真写完一个自我介绍页,等于把入门阶段该认识的标签一次性见了个遍。

我带新人的时候有个习惯,不让他们先去看那套又长又全的标签手册,而是直接扔一个需求:把你自己的信息组织成一个页面。人在写自己的东西时是有表达欲的,遇到"技能这块我想列成两栏""项目想按时间倒序排"这种具体诉求,会主动去查该用什么标签,记忆比死记硬背牢得多。等你把这个页面写顺了,再去看那些社区主页、文档站首页的结构,会发现骨架几乎是同一套。

还有一层好处是文件体量小。整个页面纯HTML也就一百多行,加上样式和脚本顶天两三百行,浏览器打开瞬间出结果,出错也好定位。比起一上来就啃一个几千行的项目模板,挫败感低太多。

1.2 结构先行的思路:先搭骨架再谈样式

很多新手的第一反应是"我要先把这个页面弄好看",于是一上来就写一堆颜色、圆角、阴影。结果样式越加越乱,最后连自己都搞不清哪个div是干什么的。我的做法一向是先把结构写死,再考虑视觉。

具体讲,就是把页面当成一份带层级的文档,而不是一堆盒子。先问自己:这块内容是页面的头部信息还是主体内容?头部信息包括姓名、职位、一句话简介,用header包起来;主体内容是按经历、技能、项目分块,用main包起来,块与块之间用section分隔;最后的联系方式用footer收尾。层级理清楚了,再去看每一块内部,标题用h几、正文用p还是li,基本就是顺着往下填。

这个顺序的好处在于,即使你完全不加样式,浏览器默认渲染出来的页面也是能读的:标题是标题的粗细,列表是列表的样子,段落之间有间距。结构对了,样式只是锦上添花;结构错了,样式再怎么堆都是在给烂地基刷墙。

提示:写完结构后先别急着写CSS,把浏览器默认样式下的页面截个图。这张图能直接看出你的层级关系对不对,也能看出有没有把该用标题的地方错误地用成了加粗段落。

1.3 三种常见写法的对比:div堆砌、语义化标签、表格布局

我刚学那会儿,网上还流传用table布局整页的做法,现在回头看当然是老黄历了,但这个对比对理解结构很有帮助。下面这张表是我总结的三种写法在自我简介网页上的实际差别。

写法类型典型结构优点问题适合场景
纯div堆砌全部用div加class样式控制自由无层级语义,屏幕阅读器读不出结构,后期维护靠猜class名复杂组件内部布局
语义化标签header/main/section/footer/p/ul结构自解释,利于无障碍与检索需要多想一步"这块是什么"内容型页面,首选
表格布局整页包在table里早期兼容性好语义完全错位,响应式极难处理真正需要行列数据时

这三种我在不同阶段都用过。现在的默认选择是第二种,但在某些具体场景下第一种依然合理——比如一个卡片内部为了做视觉对齐,那层纯粹是布局容器,用div反而比硬塞一个section更诚实。关键判断标准是:这块内容本身是不是一个独立的语义单元。是,就用语义标签;不是,纯粹为了排版,用div。

至于表格布局整页,只在一个地方还能看到它的合理性——就是真的在展示行列数据,比如"技能名称 / 熟练程度 / 使用年限"这种结构。这时候用table不是妥协,是正确选择。

2. 文档骨架:从doctype到body的每一行在干什么

2.1 第一行doctype不是标签,但它决定了后续一切

很多教程会一笔带过地说"第一行照抄就行",然后新手就真的照抄,抄了好几年也不知道那行在干什么。我说清楚一点:<!doctype html>不是一个HTML标签,它是给浏览器的一句声明,意思是"请用标准模式来渲染我这个页面"。

那不用标准模式会怎样?浏览器会进入一种叫"怪异模式"的兼容状态,此时它对盒模型的宽高计算、行内元素垂直对齐这些细节的处理,和现代标准是不一样的。你照着教程写的两栏布局,在别人电脑上莫名错位,很可能就是这一行漏了或者写错了。以前那串长得吓人的<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ...>就是旧标准的写法,现在统一用这个简短版本,大小写不敏感,但习惯上写成小写。

这条声明必须放在所有内容之前,连注释都不能在它前面。我踩过的坑是:某个编辑器模板会自动在文件头插一段版权注释,结果doctype被挤到第二行,页面在某些情况下渲染异常,查了半天才发现是这个原因。

2.2 html标签与lang="zh-cn"到底影响了什么

<html>是整个文档的根元素,所有内容都在它里面,这一点没什么争议。容易被忽略的是它上面的lang="zh-cn"。

这个属性和视觉效果没有任何关系,但它影响三件事。第一,屏幕阅读器会据此选择合适的语音引擎,读中文和读英文的发音规则完全不同,不标的话读出来会很怪。第二,浏览器在决定用哪种字体渲染、什么时候触发中日韩标点换行规则时,会参考这个值。第三,页面翻译类功能靠它判断原文语言,比如判断该不该弹"是否翻译成英文"的提示。

zh-cn表示简体中文。如果你写的是繁体内容,习惯上用zh-hant或者zh-tw。这个属性写错了不会报错,页面照样显示,所以很多项目里它是错的也没人发现。我自己的检查习惯是:新建文件时第一件事就把lang写上,别等到最后补。

2.3 head里的三件套:charset、viewport、title

<head>里可以塞很多东西,但对一个自我简介网页来说,下面三个是必须有的。

<meta charset="utf-8">决定了浏览器用什么编码去解析文件。写utf-8能覆盖绝大多数场景,包括中文、日文、各种符号。这个标签必须放在head里尽可能靠前的位置,一般紧跟在head开始标签之后。原因是浏览器在读到它之前,如果已经拿到了一段字节流,可能会先用默认编码猜一次;放得越靠前,猜错的机会越小。乱码问题的九成都出在这里或者文件本身的实际保存编码上,两个要一致。

<meta name="viewport" content="width=device-width, initial-scale=1">是针对移动端的。不写这一行,手机浏览器会默认按一个虚拟的宽屏(常见是980像素左右)来渲染页面,然后整体缩小给你看,结果就是字小得要点两下放大。写上去之后,页面宽度就等于设备实际宽度,布局才是你预期的样子。initial-scale=1表示初始不缩放,一般和width=device-width配合使用。

<title>是标签页上显示的文字,也是收藏夹里的名字,还是搜索结果的标题。新手最常犯的错误是写个"我的网页"或者干脆不写。写成"张明的个人主页 - 前端方向"这种,信息量立刻不一样。

2.4 一份可以直接抄走的head模板

把上面说的几块拼起来,就是下面这个样子。我这几年的个人小页面基本都从这个模板改。

<!doctype html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>张明 - 个人简介</title> <meta name="description" content="前端方向从业者,主要做界面结构与交互实现。"> <meta name="author" content="张明"> <link rel="stylesheet" href="style.css"> </head> <body> <!-- 页面内容 --> </body> </html>

多说一句description和author这两个meta。它们不影响页面显示,但description的内容有可能被搜索结果引用,author是给文档留个署名信息。写不写都行,但既然成本是一行字,顺手写上没坏处。link rel="stylesheet"那行是引入外部样式表,下面第4章会细说样式该放哪。

3. 页面主体的语义化结构拆解

3.1 header区:名字、职位、一句话介绍

header这块要解决的是"你是谁"。最小的写法是h1加一行p。

<header> <h1>张明</h1> <p>前端方向 · 擅长把设计稿变成能跑的界面</p> <img src="avatar.jpg" alt="张明的头像" width="120" height="120"> </header>

这里有几个细节值得说。h1在一个页面里原则上只用一次,代表这个页面的主标题;自我简介页里最合适的就是你的名字。别为了好看把名字写成h3,然后用CSS调大字号——那是拿样式去掩盖结构问题。头像那个img标签,alt属性一定要写,它不只是给图片加载失败时显示的文字,也是屏幕阅读器读出来的描述。width和height写上,可以在图片还没加载完时先把位置占住,避免页面内容跳动。

注意:alt不是可有可无的装饰属性。纯装饰性图片可以写alt=""(空字符串),表示"这张图没有信息量,跳过",但绝不能直接省略alt,省略会让辅助工具去猜甚至读出文件名。

一句话介绍我建议手写,别用"本人性格开朗、乐于助人"这种模板句。写你做过的具体事情,比如"给公司内网做过一个数据看板",看的人立刻有画面。

3.2 main区:经历、技能、项目怎么分区

main表示这个页面的核心内容,一个页面理论上只有一个main,且它不应该包含那些在每个页面都重复的部分(比如全站导航、页脚版权)。这一点很多人会搞错,把导航也塞进main里。

main内部按内容主题切section,每个section自己带一个h2标题。

<main> <section> <h2>工作经历</h2> <ul> <li> <h3>某公司 · 前端开发</h3> <p>2021年至今,负责后台管理系统的界面结构与组件维护。</p> </li> <li> <h3>某工作室 · 实习</h3> <p>2020年到2021年,参与活动页面的静态页面制作。</p> </li> </ul> </section> <section> <h2>技能清单</h2> <dl> <dt>HTML</dt> <dd>能独立完成语义化结构,熟悉表单与无障碍基础属性。</dd> <dt>CSS</dt> <dd>熟悉常用布局方式,能处理常见的移动端适配问题。</dd> </dl> </section> </main>

这里我故意用了两种不同的标签:经历用无序列表,因为每条经历是并列关系,没有先后顺序的含义;技能用描述列表,因为技能名和说明之间是"术语—解释"的对应关系,dl正好表达这个。

标题层级也要留意:h1是名字,所以section的标题从h2开始,section内部的小标题用h3。跳级(比如h1直接到h3)在视觉上可能看不出问题,但会让依赖层级导航的工具读起来很混乱。

3.3 列表、表格、段落到底该选哪个

这是新手最纠结的部分,我给一个判断链条,按顺序问自己就行。

第一步,这些内容是不是并列的条目?是,用列表。列表内部条目之间如果有明确的先后(比如"第一步、第二步"),用ol;没有顺序含义的,用ul。

第二步,这些内容是不是"名称—描述"的配对?是,用dl。

第三步,这些内容是不是二维的行列数据,比如"年份 / 项目 / 角色"?是,用table,表头用thead包th,内容用tbody包td。

第四步,以上都不是,就是一段叙述文字?用p。

自我简介页里最典型的需要table的地方,是做一条时间线:

<table> <thead> <tr> <th scope="col">时间</th> <th scope="col">项目</th> <th scope="col">我的角色</th> </tr> </thead> <tbody> <tr> <td>2023</td> <td>数据看板改版</td> <td>结构与样式实现</td> </tr> <tr> <td>2022</td> <td>活动落地页</td> <td>整页制作</td> </tr> </tbody> </table>

scope="col"这个属性是告诉辅助工具"这个表头管的是下面这一列",不是必填,但加了没坏处。

3.4 footer区:联系方式与版权

footer放的是页面收尾信息。对个人简介页来说,通常是联系方式、社交账号链接、版权说明。

<footer> <h2>联系我</h2> <ul> <li>邮箱:<a href="mailto:zhangming@example.com">zhangming@example.com</a></li> <li>主页:<a href="https://example.com" target="_blank" rel="noopener">个人作品集</a></li> </ul> <p><small>本页内容为个人介绍,转载请注明出处。</small></p> </footer>

邮箱链接用mailto:前缀,点击后会直接调起邮件的撰写界面,比让用户手动复制粘贴友好。外部链接加target="_blank"会在新标签页打开,配合rel="noopener"是个稳妥习惯——不加的话,新打开的页面在某些情况下能通过脚本访问原页面的引用,属于可以避免的小隐患。

底部那行版权我用small标签包了一下,它的语义是"附加说明、小字",和视觉上的"字小一点"正好对上,比用p加个class再调字号要正经。

4. 完整的自我简介网页代码实操

4.1 完整结构代码,可以直接拿去改

把前面几块拼起来,就是一份完整的页面骨架。我在关键位置都加了注释,方便你对照着改。

<!doctype html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>张明 - 个人简介</title> <meta name="description" content="前端方向的个人简介页面。"> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>张明</h1> <p>前端方向 · 把设计稿变成能跑的界面</p> <img src="avatar.jpg" alt="张明的头像" width="120" height="120"> <nav> <a href="#exp">经历</a> <a href="#skill">技能</a> <a href="#contact">联系</a> </nav> </header> <main> <section id="exp"> <h2>工作经历</h2> <ul> <li> <h3>某公司 · 前端开发</h3> <p>2021年至今,负责后台管理系统的界面结构与组件维护。</p> </li> <li> <h3>某工作室 · 实习</h3> <p>2020年到2021年,参与活动页面的静态页面制作。</p> </li> </ul> </section> <section id="skill"> <h2>技能清单</h2> <dl> <dt>HTML</dt> <dd>独立完成语义化结构,熟悉表单与无障碍基础属性。</dd> <dt>CSS</dt> <dd>熟悉常用布局方式,能处理常见移动端适配问题。</dd> <dt>JavaScript</dt> <dd>能做基础交互,例如页内平滑跳转、回到顶部。</dd> </dl> </section> <section> <h2>项目时间线</h2> <table> <thead> <tr> <th scope="col">时间</th> <th scope="col">项目</th> <th scope="col">我的角色</th> </tr> </thead> <tbody> <tr> <td>2023</td> <td>数据看板改版</td> <td>结构与样式实现</td> </tr> <tr> <td>2022</td> <td>活动落地页</td> <td>整页制作</td> </tr> </tbody> </table> </section> </main> <footer id="contact"> <h2>联系我</h2> <ul> <li>邮箱:<a href="mailto:zhangming@example.com">zhangming@example.com</a></li> <li>作品集:<a href="https://example.com" target="_blank" rel="noopener">example.com</a></li> </ul> <p><small>本页为个人介绍,内容仅供参考。</small></p> </footer> <script src="main.js"></script> </body> </html>

有几个地方我特意做了示范。header里放了个nav做页内锚点跳转,href的值对应各个section的id,这是最省力的导航实现方式,不用写任何脚本就能点。script标签放在body最后,原因在4.3节细说。

4.2 CSS放哪里:外链、内联、行内的取舍

样式有三种放法,各有各的适用场合,我按推荐顺序排一下。

外部样式表是首选。在head里用<link rel="stylesheet" href="style.css">引入一个单独的文件。它的好处是这个文件会被浏览器缓存,页面多了以后不用重复下载,改样式也只改一个地方。个人简介页虽然只有一个页面,我依然推荐外链,因为这是养成好习惯的起点。

head里的style标签适合临时调试或者单页小项目。写起来方便,但页面结构和样式混在一个文件里,行数一多就难找。

行内style属性,也就是直接写在标签上的style="color:red",我的建议是尽量别用。它优先级高、不好覆盖,还会让结构代码变得又长又乱。唯一合适的场景是那种由脚本动态计算出来的、每秒钟都在变的值。

/* style.css */ body { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; line-height: 1.7; max-width: 720px; margin: 0 auto; padding: 24px 16px; color: #222; } h1 { font-size: 1.8rem; margin-bottom: 4px; } h2 { font-size: 1.25rem; margin-top: 36px; border-bottom: 1px solid #ddd; padding-bottom: 6px; } h3 { font-size: 1rem; margin-bottom: 4px; } img { border-radius: 50%; display: block; } nav a { margin-right: 12px; }

那段font-family里的system-ui是个省事的写法,让页面直接用系统自带的界面字体,中文环境下会落到系统默认的中文字体上,比自己硬指定一款字体要稳。max-width加margin auto这个组合是经典的居中方式,比用定位写要简单得多。

4.3 JS什么时候需要,什么时候不需要

自我简介页本质上是个内容页,绝大部分需求用HTML加CSS就够了。真正需要脚本的场景我数了数,大概只有三类。

第一类是"回到顶部"。页面长了之后,用户滚到底部想回去,有个按钮会舒服很多。实现思路是监听滚动距离,超过一定高度就把按钮显示出来,点击时让页面平滑滚回顶部。核心就两行:用window.scrollY判断距离,用window.scrollTo({top: 0, behavior: 'smooth'})做平滑滚动。这里behavior: 'smooth'是关键参数,不加它就是瞬间跳回去,体验差不少。

第二类是导航高亮。滚到某个section时,上方对应的导航项变色。这个用现代浏览器提供的观察接口来做会比监听滚动事件干净,代码十来行。

第三类是数据驱动的部分。比如你的项目列表想从一份数据文件里读出来渲染,而不是写死在HTML里。这种场景在个人页上不多见,真需要的时候再上脚本也不迟。

对应的取舍原则是:能用HTML和CSS表达的,就不要用JavaScript。锚点跳转能用href解决的,别写scrollTo;纯展示的折叠内容能用details标签解决的,别写点击展开的逻辑。脚本引入的方式上,我在页面底部用<script src="main.js"></script>,好处是脚本执行时DOM已经解析完毕,不需要再包一层"等页面加载完成"的回调。

4.4 几个容易被忽略但很实用的属性细节

第一,锚点跳转的平滑效果现在可以纯CSS实现。给html标签加一句scroll-behavior: smooth;,所有页内锚点跳转都会变成平滑滚动,连JS都不用写。这是我这几年最喜欢的一个小改动,一行顶十几行。

第二,链接的rel="noopener"前面提过,值得再说一遍。凡是target="_blank"的外部链接,加上它。

第三,表单类的联系方式。如果你想让访客直接留言,可以放一个简单的表单,注意input都要有关联的label。

<form action="/message" method="post"> <label for="name">你的称呼</label> <input id="name" name="name" type="text" required> <label for="msg">留言内容</label> <textarea id="msg" name="msg" rows="4" required></textarea> <button type="submit">提交</button> </form>

label里的for要等于input的id,点击文字就能聚焦到输入框,这个细节对手机用户尤其友好。required是浏览器自带的必填校验,省得自己写脚本。

5. 常见问题与排查技巧实录

5.1 中文乱码,八成是这两个原因

乱码是新手遇到的第一个拦路虎,我把它拆成两种情况。

第一种,meta charset写了utf-8,但文件本身是按别的编码保存的。比如在某个编辑器里默认保存成了GBK,浏览器却按utf-8解析,中文就变成方块或问号。解决办法是在编辑器的保存设置里确认编码是UTF-8,注意有些编辑器区分"UTF-8"和"UTF-8 with BOM",网页文件建议用不带BOM的那个。

第二种,文件编码是对的,但meta标签位置太靠后,或者干脆忘了写。浏览器在没拿到编码声明之前,可能已经按默认编码解了前面一小段。所以这个标签要放在head的最前面。

排查方法很直接:右键查看页面源码,如果源码里中文显示正常,但页面上是乱码,说明文件编码没问题,是声明的问题;如果源码里就已经是乱码,那就是文件本身的编码存错了。

5.2 标签没闭合,浏览器为什么不报错

HTML和编程语言不太一样,它对错误的容忍度非常高。你漏掉一个</p>,浏览器会自动帮你补上,页面看起来一切正常。这种"宽容"是好事也是坑。

好事在于新手不会因为一个笔误就白屏。坑在于错误被掩盖了,等到页面变复杂,某天突然布局全乱,排查起来毫无头绪。

我的建议是养成两个习惯。一是写完一段就缩进对齐,标签成对出现,开一个立刻补上闭合的。二是把浏览器的开发者工具用起来,按F12打开,看元素面板里的实际结构——浏览器解析后的真实结构,和你写的文件可能有差别,差别的地方往往就是问题所在。

一个高频错误是块级元素嵌套不当,比如把div直接放在ul里面(合法位置是li里),或者p里面套p,浏览器会自动断开前一个p,结构就和你预期的不一样了。这类问题在元素面板里一眼就能看出来。

5.3 移动端显示不对,先检查这三处

手机上打开自己写的页面,最常出现的两个症状是"字太小要放大"和"有横向滚动条"。前者基本是漏了viewport那行meta。后者通常是某个元素宽度超出了屏幕。

超出屏幕的元素排查有个小技巧:在开发者工具里给所有元素临时加一句outline: 1px solid red;,然后一层层找哪个红框超出了边界。常见元凶是固定宽度的图片、加了padding但没做宽度修正的块、以及表格内容太宽。图片可以加max-width: 100%;,表格可以套一层可横向滚动的容器。

5.4 常见问题速查表

下面这张表是我这些年被问得最多的几个问题,直接按症状找原因。

症状最可能的原因处理方式
中文显示为乱码文件编码与charset声明不一致,或meta位置靠后统一保存为UTF-8,meta charset放head首位
手机上看字很小漏写viewport meta补上width=device-width, initial-scale=1
页面出现横向滚动条某元素宽度超出视口图片加max-width:100%,定位元素检查偏移量
图片位置在加载时跳动img没写宽高补上width和height属性
点击锚点跳转很生硬没有平滑滚动设置html加scroll-behavior: smooth
新标签页打开有隐患外部链接缺rel加rel="noopener"
标题层级被工具读乱跳级用h标签从h1顺延,不跳级
样式改了没生效缓存或选择器优先级强制刷新,检查选择器权重

提示:这个表建议打印出来贴在手边。新手阶段八成的报错都在这八条里,遇到问题先扫一遍表,比漫无目的地搜要快得多。

我在实际带人的过程中发现,最容易反复踩的其实是最后一条——样式改了没生效。十次里有七次是浏览器缓存了旧的CSS文件,强制刷新(Windows上是Ctrl+F5)就好;剩下三次是选择器优先级问题,比如想覆盖一个行内样式却发现怎么写都不生效。这种情况下,与其一路加!important,不如回头把样式的位置理顺。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询