首页 / 资讯中心 / 文章详情

前端基本功:HTML语义化、表单与多媒体细节全解析

前端基本功:HTML语义化、表单与多媒体细节全解析 ★ FEATURED ARTICLE
干了十几年前端我面试过不少候选人也看过大量各式各样的项目代码。有个现象一直让我挺感慨很多人把HTML当成入门第一课觉得它无非就是一堆尖括号标签背完常用的那几十个就算出师了。可真到了写工程化页面、做SEO优化、做无障碍改造、解决奇怪的渲染问题时反而要回头翻HTML的文档——这时候才意识到基础扎实和知道标签名完全是两码事。这篇东西不讲框架、不碰构建工具就围绕前端基础的HTML展开聊聊我这些年实际用下来觉得真正重要的部分文档骨架、语义化、表单、多媒体以及代码评审中反复出现的问题。适合刚入门的前端新人也适合那些想回头看基础、却不想再啃枯燥文档的开发者。我会尽量用项目里的真实场景来拆解不整虚的。1. HTML从来不是简单的标记语言1.1 先回答一个送命题HTML到底算不算编程很多新手都会纠结这个问题。我的看法是HTML当然不是通用编程语言它没有变量、没有逻辑分支、没有循环但它是一种承载信息和结构的语言。你写的每一个标签都在告诉浏览器、搜索引擎、屏幕阅读器这里是什么东西它有多重要它和周围内容是什么关系。想清楚这一点你就不会把HTML当成背标签的学科而是当成表达信息结构的学科。同样的内容用不同的标签和层级去表达页面对用户、对搜索引擎、对辅助工具的友好程度是完全不同的。我举一个实际例子一份内容里有标题、列表、一段引用。如果全部用div包裹视觉上可能通过CSS做得跟标准结构一模一样但搜索引擎提取要点时只能靠猜屏幕阅读器朗读时也缺失了这是列表这是引用的语义提示。用户看着没差别但机器的理解成本高了一大截。1.2 HTML与CSS、JS的分工边界我在带新人时有一个习惯先让他们用纯HTML把一个页面的内容骨架搭出来不允许写任何CSS和JS。这个练习的目的是让他们明白三件事HTML负责结构和语义它决定页面里有什么内容、这些内容是什么类型CSS负责外观和布局它决定这些内容长什么样、排在什么位置JS负责行为和交互它决定用户操作之后页面如何响应。这个边界如果模糊了就会出现一堆问题比如用div模拟按钮、用表格做布局、用JS往页面里塞大量HTML字符串……这些东西不是不能做而是违背了各自的职责最终都会在维护期还债。我在实际项目里见过太多因为标签乱用导致的样式错乱和脚本失效根因都是没搞清楚分工。举个真实案例某次接手一个老项目页面顶部导航被写成了div classnav里面塞了一堆div classitem点击事件全靠JS绑定。后来要加SEO和无障碍支持只能一个个手动改成nav和ullia改完还要重新验证所有交互逻辑。如果当初写HTML时多花两分钟用对标签后面根本不用动这些。2. 文档骨架和元信息页面身份从这里确定2.1 DOCTYPE与文档模式每次新建HTML文件第一行一定是!DOCTYPE html。可别小看这一行它直接决定了浏览器用标准模式还是怪异模式来解析页面。如果漏了DOCTYPE老版本浏览器会用怪异模式渲染盒模型、字体、间距都可能偏离你的预期而且各个浏览器的表现还不一样排查起来非常痛苦。我建议所有项目都统一使用HTML5的短写法!DOCTYPE html html langzh-CN head meta charsetUTF-8 !-- 其他meta和资源引入 -- /head body !-- 页面内容 -- /body /html其中langzh-CN很重要它告诉屏幕阅读器按中文发音规则朗读也帮助翻译工具和搜索引擎更好地理解页面语言。这个属性经常被忽略但对可访问性来说它和标签本身一样重要。2.2 meta标签里藏着哪些门道很多人对head区域的理解停留在放title和引入CSS/JS其实meta标签的信息量非常大。我挑几个实际开发中最常用的说meta charsetUTF-8声明字符编码。不加这个页面上出现中文乱码的风险极高尤其是本地文件直接打开时。meta nameviewport contentwidthdevice-width, initial-scale1移动端适配的基础没有它手机浏览器会用默认宽度渲染页面然后整体缩放导致排版完全失控。meta namedescription content...页面的描述信息搜索引擎在结果页展示摘要时会参考它。虽然权重不如以前但它依然是每个页面都应该写的。另外还有针对社交分享的Open Graph标签比如og:title、og:description、og:image。如果你们的页面经常被分享到聊天工具或社交平台这些标签决定了分享卡片长什么样。我见过不少产品上线后才发现分享出去只有一行URL连标题都没有就是因为没写OG标签。2.3 一个值得借鉴的head模板我平时开新项目时head区域长这样!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1 title页面标题 - 站点名称/title meta namedescription content不超过150字的页面描述 meta propertyog:title content页面标题 meta propertyog:description content页面描述 meta propertyog:type contentwebsite link relicon href/favicon.ico /head这里面每个标签都有明确用途不需要每次都从零纠结。把它存成模板或者编辑器片段新建页面时直接套用省下的时间可以干更有价值的事。3. 语义化标签为什么老手总在强调别乱用div3.1 从结构到语义的进化HTML5之前我们用div、span这些无语义标签配合class来搭建页面class名起得什么都有header、footer、content、nav……这些名字只有人能看懂浏览器和搜索引擎完全不知道它们的含义。HTML5引入了一批语义化标签相当于把大家平时约定俗成的class名扶正成了标准标签。一个典型的页面骨架可以写成这样body header站点头部包含logo和导航/header nav主导航/nav main article h1文章标题/h1 p正文内容/p /article aside侧边栏/aside /main footer版权信息/footer /body这套结构清晰到什么程度哪怕把CSS全部去掉用户和搜索引擎也能从标签层级里判断出哪里是导航、哪里是正文、哪里是补充信息。这就是语义化的价值它让页面自解释。3.2 正确使用article与section语义化标签用起来最容易出问题的是article和section很多人分不清它们和div的区别。我的理解方式很简单div纯粹的容器没有语义只用来划分区域或配合样式。section一个主题相关的分组它内部通常有独立的标题h1-h6比如一个页面里的产品介绍团队介绍可以用section。article一个完整、独立的可复用内容单元比如一篇博客、一条新闻、一个评论。它强调脱离页面上下文也能独立理解。判断方法也简单如果把这段内容单独抽出来放到另一个页面它还能作为一篇完整的文章存在那它就更接近article如果它只是某个主题下的一段叙述那用section更合适如果它纯粹是布局需要、没有任何语义那就老老实实用div。我见过一个反面例子有人把整个博客首页的每篇摘要都用article包裹这本身没错但摘要里又嵌了一个article放链接。这种嵌套不仅没有语义价值反而让辅助工具的用户在浏览时产生困惑——到底有几个独立内容单元3.3 语义化对SEO和可访问性的实际影响这可能是语义化最实在的两个收益。对SEO来说搜索引擎爬虫在分析页面时会依赖标题层级和语义标签来理解内容结构。一个页面如果标题层级混乱比如h1下面直接是h3或者整页都是h2爬虫就很难判断内容的重点是什么。我建议一个页面只保留一个h1用于表达页面核心主题后面按内容层级依次用h2、h3。对可访问性来说屏幕阅读器用户可以通过语义标签快速跳转到页面各个区块。W3C的WAI-ARIA规范里推荐的地标导航正是建立在这些语义标签之上的。简单说你今天写的每一个nav、main都在帮助视觉障碍用户更方便地使用你的页面。4. 表单整个HTML里最容易被低估的重工业4.1 input类型与输入体验表单是HTML里交互最重的部分但很多项目对它的重视程度远不如对CSS框架和组件库的重视。结果就是用户输入体验差、数据校验混乱、手机端键盘不对、辅助工具无法朗读。HTML5给input增加了一批type正确使用它们能从底层改善输入体验typeemail手机端会调出带符号的键盘浏览器也能做基础格式校验。typetel手机端调出数字键盘。typenumber只允许数字输入配合min、max、step可以控制数值范围。typedate/typetime提供日期和时间的原生选择器。typesearch部分浏览器的输入框会带清除按钮。这些type改起来成本极低但对移动端用户来说体验提升非常明显。我见过不少项目从头到尾只用一个typetext用户填手机号都要手动切换数字键盘这就是典型的基本功没打牢。4.2 label与表单可访问性有个细节我几乎每次做代码评审都会提每个输入控件都必须有对应的label并且用for属性和控件的id绑定。原因是屏幕阅读器需要通过label来朗读控件的用途用户点击label标签时也应该能聚焦到对应的输入框。正确的写法是label forusername用户名/label input typetext idusername nameusername如果因为布局原因不想让label文字显示出来可以用CSS把它视觉隐藏而不是直接删掉。视觉隐藏label是合理做法完全没有label是不可接受的。比如搜索框旁边放一个放大镜图标很多人就不写label了但屏幕阅读器用户根本不知道那个输入框是干什么的。正确做法是写一个搜索label再用CSS把文字移出可视区域。4.3 表单校验与提交的数据流HTML5自带的表单校验属性比如required、minlength、maxlength、pattern能做的校验其实比很多人想象的多。举个例子input typetext namephone pattern1[3-9]\d{9} title请输入11位手机号 required这个输入框在没有JS的情况下就能完成必填格式两层校验。title属性会在校验失败时作为提示文字显示pattern用正则约束格式。但要注意HTML校验只是用户交互层的第一道关卡服务端必须做同样的校验。原因很简单用户的请求完全可以绕过浏览器直接发到服务端前端的校验挡不住恶意或非正常的提交。我建议的做法是前端用HTML属性做即时提示JS做增强交互比如自定义错误文案服务端做最终的数据合法性校验——三层各司其职安全性和体验才都有保障。5. 图片、链接与多媒体内容承载的细节功夫5.1 img标签的srcset与响应式图片图片是页面体积的大头也是导致加载慢的常见原因。srcset和sizes属性是响应式图片的标准方案根据屏幕宽度选择合适尺寸的图片img srcsetsmall.jpg 480w, medium.jpg 1024w, large.jpg 1920w sizes(max-width: 600px) 480px, (max-width: 1200px) 1024px, 1920px srcfallback.jpg alt产品实拍图浏览器会根据当前视口宽度和dpr从srcset里挑一张最合适的图片下载。相比移动端和桌面端各写一个img这种方案维护成本更低而且没有JS参与性能更稳。还有两个属性值得一提loadinglazy可以让非首屏图片延迟加载alt文本则既是SEO的一部分也是图片加载失败或用户使用屏幕阅读器时的替代信息。很多人在图片上不写alt这在可访问性评审里属于必改问题。尤其是一些功能性图标比如删除按钮上的图标alt应该写删除而不是空着这样辅助工具用户才能理解操作含义。5.2 a标签的安全属性链接标签看起来简单但有一个安全问题必须在每个项目里落地给新窗口打开的链接加上relnoopener noreferrer。原因是使用target_blank打开的新页面可以通过window.opener访问原页面的window对象进而利用钓鱼等手段影响原页面。加上noopener之后新页面拿不到原页面的引用这个风险就解除了。a hrefhttps://example.com target_blank relnoopener noreferrer外部链接/a现在的浏览器大多默认行为已经安全但为了兼容老旧环境这行属性建议养成肌肉记忆。代码评审里看到target_blank没有带rel我会直接打回。5.3 video与audio的基础配置对于多媒体标签容易踩的坑是格式兼容。video标签在不同浏览器里对编码格式的支持有差异建议同时提供MP4和WebM两种源video controls preloadmetadata posterposter.jpg source srcmovie.webm typevideo/webm source srcmovie.mp4 typevideo/mp4 您的浏览器不支持video标签。 /videocontrols属性决定是否显示原生控制条preloadmetadata表示只预加载元数据时长、尺寸等不预加载视频内容这对节省流量很有帮助。poster指定封面图否则用户会在视频加载前看到一个黑屏区域。标签之间的文字内容不是什么错误提示而是降级内容——当浏览器完全不支持video时显示给用户看的。这种降级思维在HTML里到处都用得上图片的alt、表单的placeholder、媒体的降级文案都是在极端情况下的兜底方案。6. 那些写在代码评审里的HTML教训6.1 嵌套与规范问题代码评审里最常见的HTML问题第一种是标签嵌套错误。比如p标签里面放div或者ul里面直接放div而不是li。这些写法在浏览器里可能碰巧能显示但已经违反了HTML的嵌套规则后续加样式、做解析都会出问题。比如ul的子元素只允许是li如果中间混入一个div浏览器在解析时往往会做错误修正把标签结构强行拆开。结果就是你写的结构是一套浏览器渲染出来的DOM是另一套CSS选择器和JS查询全都对不上。我排查过好几次这种问题最终都是因为嵌套不规范埋的雷。第二种是标题层级跳变。一个页面h1下面直接跳h4中间没有h2、h3这在内容结构上是不完整的。如果是为了控制字号而调整标题级别那应该用CSS解决而不是改标签级别。6.2 无障碍需求从来不是附加题接触过无障碍改造项目之后我对HTML的要求明显上了一个台阶。屏幕阅读器的用户和无障碍测试工具会严格检查内容的对比度、操作的键盘可达性、图片的alt、表单的label、语义标签的使用。这些能力在HTML层面就能做到七八成不需要额外引入任何库。我在实际改造中遇到一个典型场景一个自定义下拉组件用div模拟点击后展开选项。因为没加rolelistbox和键盘事件屏幕阅读器完全无法操作它。后来改成原生select或者补齐ARIA角色和键盘交互问题才解决。如果一开始就按原生语义实现根本不用返工。所以我现在写HTML的时候会默认把无障碍当成功能的一部分而不是附加要求。一个按钮如果不能用键盘触发它就还不算写完一个表单如果没有label它就还不算交付。6.3 我的几点实操建议最后说几条我多年下来的实操经验新建页面时先写HTML结构再写CSS和JS。顺序错了很容易在样式里补偿结构问题越写越乱。每写完一个区块用浏览器的检查工具看一下标签嵌套顺便跑一次页面朗读或者无障碍检测插件。这个习惯能省掉后面大量返工。不要为了简洁删掉带语义的标签。main、header、footer这些标签对搜索引擎和辅助工具的意义不是视觉上能看出来的。如果团队里有新同学把HTML代码评审当成常规流程执行。我在团队里一直坚持这一点效果比任何培训都好。我在带团队和做技术评审的过程中最大的体会是框架和工具一直在换但HTML的基本功是那个永远在底层的支柱。也许不用急着成为HTML专家但把本章提到的骨架、语义、表单、多媒体、嵌套规范这几点吃透就已经超过了大部分开发者的基础水平。希望这些内容对你有一点实际帮助。
阅读完成 · 觉得有帮助?
咨询建站