ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

HTML文本与图片标签语义化:从基础到响应式图片优化实践

HTML文本与图片标签语义化:从基础到响应式图片优化实践 开始工作。我会严格按要求直接输出一篇结构独特、内容扎实、以从业者口吻写作的博文。正文从## 开始不添加任何元信息。1. 文本标签的语义价值为什么用对标签比用对样式更重要做了几年H5页面开发我带过不少新人最常看到的一个毛病是把HTML标签当成画样式用的工具。想要加粗就b想要斜体就i想要换行就来一串br想要缩进就硬敲空格。这种写法在刚入门的时候确实很爽因为页面长得好像也没啥问题。但一旦进入真正的项目协作、SEO优化、可访问性改造甚至只是隔了三个月回来看自己的代码这些问题全部会变成债。这篇是H5前端开发笔记的第06期聊两个最基础但最容易被用错的家族文本标签和图片标签。基础不代表简单——恰恰因为它们出现在每一个页面里出一丁点问题都会被放大。这一期我不打算只罗列标签长什么样而是把重点放在为什么一个标签该这么用、不该那么用看完你至少能少踩我当年踩过的几个坑。1.1 标题标签与段落从h1到p的骨架意识h1到h6是六级标题很多人以为它们的区别就是字体越来越大于是为了样式好看跳着选。比如页面主标题用h2因为h1默认太大或者一个页面上放四五个h1因为每个板块都觉得自己是主标题。这在浏览器里看着没事但对搜索引擎和读屏软件来说标题是一份页面的目录。爬虫会把h1理解为页面最高优先级的内容主题读屏用户会用标题快捷键在页面中跳转导航。一个页面塞了五个h1相当于一本书有五张封面谁都不信你是认真的。我自己的准则是一个页面只保留一个h1它一般就是页面最大的那个标题下面按层级依次用h2、h3可以跳过级别往下跳比如从h2直接到h4但绝不往上跳——你不可能把一个h4放在h3的上级。标题层级的正确顺序本质上就是在维护一份清晰的文档大纲。再说p。段落标签的问题比标题更隐蔽很多新手觉得p自带上下边距布局不好控制于是习惯用div包文字。这个习惯会让页面的语义完全丢失——读屏软件拿到一大片div时不知道哪里是段落、哪里是列表、哪里是导航。对SEO来说清晰的分段结构也有助于内容主题提取。我的建议是文字内容一律放进pdiv只负责结构性分区。段落里如果有一段更细的带样式文本用span包千万别本末倒置。1.2 格式化标签strong、b、em、i别再把语义当装饰文本标签里最容易混淆的就是两组strong和bem和i。从视觉上它们一模一样前者加粗后者斜体。但语义差别非常大标签视觉表现语义含义适用场景strong加粗内容很重要需要被强调警告文案、关键数字、重点段落b加粗无语义只是视觉上想加粗产品名、关键词装饰em斜体语气强调改变句子意思我说了和我说了的差别i斜体无语义表示特殊文本外来词、专有名词排版读屏软件对strong和em的处理方式是改变音调语速用户能感觉到这里重要但b和i就是纯粹的视觉样式读出来没有任何区别。如果你暂时分不清最简单的记忆方式就是strong和em是有感情的b和i是没感情的。HTML5之后还有一组非常实用的文本标签del表示删除内容浏览器渲染为删除线mark表示高亮标记自带黄色底ins表示插入内容。这三个标签在做版本对比、标注修改记录、搜索结果关键词高亮时特别好用而且语义非常明确。2. 掌握文本嵌套与排版规则内联、块级、换行的底层逻辑文本标签用错了最典型的结果不是页面崩掉而是浏览器帮你圆了过去。比如你在p里面又放了一个p浏览器不会直接报错它会悄悄把标签拆开最后渲染出来的DOM结构和你想的完全不一样。这种问题在开发者工具里能看到但新手常常被页面看起来还能用欺骗等到要改样式时才发现选择器根本选不中目标。2.1 内联元素与块级元素的边界决定了你能怎么嵌套HTML里的元素按显示方式分两大类块级元素和内联元素。块级元素像一个集装箱默认占满整行上下可以堆叠比如div、p、h1~h6、ul内联元素像货架上的盒子多个盒子可以排在同一行比如span、a、strong、em、img。嵌套规则基本可以总结成一句话内联元素可以放进块级元素里但块级元素不能随便放进内联元素里。尤其是p标签它内部不能放div、p、h1这类块级元素。HTML规范明确写了p的内容模型是短语内容。你如果真的写了一个p里面套div浏览器在解析时会把p自动闭合于是div就跑到p外面去了。这就是为什么很多人写完样式发现不对劲——不是CSS写错了而是HTML结构已经被浏览器悄悄改写了。2.2 br、hr、span在排版中的正确角色br也是一个被滥用极狠的标签。很多新手用它来做间距、做换行排版比如三段文字之间空一行就敲两个br。这个习惯很糟糕br的语义是在诗歌或地址中换行它不是排版工具用它在段落里做间距会导致屏幕阅读器一个词一个词地跳阅读体验极差。段落之间要用p间距用CSS的margin需要强制换行且确实没有语义的地方才用br。hr的情况类似。它原本是一条水平分割线HTML5里它的语义变成了段落级别的主题分隔。如果你只是想画一条好看的线请用CSS边框如果你是想表达上文结束开始另一个话题hr是语义上最正确的选择。我甚至见过有人为了让hr变细而把它包在div里加样式——完全没必要直接给hr写CSS样式就行它本质上也是一个元素。span则是文本标签里的万能兜底它是一个纯粹的内联容器不含任何语义专门用来给一段文字包样式。需要给某个词换个颜色、加个背景、做hover效果就用span包起来不要用strong去加粗再改样式——那样会给读屏软件一个错误的重要性提醒。2.3 文本源码里那些看不见的幽灵空格、换行与转义还有一个所有人都应该知道的基本规则HTML会把连续多个空格合并为一个空格换行符在正常文本流里也会被当作空格处理。很多新手在代码里看到自己写了空行以为页面上会出现距离结果却发现标签之间紧紧贴在一起然后又靠一堆br和nbsp;去撑间距。正确的做法是间距问题全部交给CSS不要在HTML里用大量空格做视觉效果。如果你要在页面上展示一个小于号直接写在文本里是会被浏览器当作标签起始符解析的。这时候必须用字符实体lt;代表gt;代表amp;代表。这个坑我在做代码展示类的页面时踩过太多次写示例代码忘了转义结果页面渲染出来的内容凭空消失了一块。3. 图片标签三大核心属性src、alt、title怎么用才算吃透图片标签img是所有网页里几乎一定会出现的元素。它的写法看着简单——一个src指路径一个alt写替代文案——但实际上关于图片标签的坑十个里面有八个来自这三个属性。先把最标准的骨架写出来img srcimages/poster.jpg alt活动主视觉海报 title查看活动详情 width640 height360这一行代码包含了5个关键属性但每个属性的正确含义和边界很多人并没有真正吃透。3.1 src路径的四种写法与常见路径坑src的取值范围是URL实际项目里常见的有四种写法相对路径images/logo.png、根相对路径/images/logo.png、绝对路径https://...、以及基于当前目录的../上跳。从维护性角度我强烈建议在组件化项目中优先使用根相对路径以站点根目录为基准无论当前文件在哪一层路径都不会因为位置变化而失效。但根相对路径有一个前提部署时你的页面确实在站点根目录下如果网站跑在二级目录比如https://example.com/shop/根相对路径的/images/logo.png会直接指到一级目录去图片全挂。这时候就得用相对路径或者带域名的绝对路径。最常见的路径坑就两种。一是层级算错页面在page/about/下图片在images/下你写images/logo.png浏览器会去找page/about/images/logo.png然后404。正确写法是../../images/logo.png。二是在本地用file://协议打开HTML时一切都正常一到服务器上因为路径分隔符或大小写问题全挂了。排查路径问题最快的办法就是按F12看Network面板404的请求会直接告诉你浏览器实际请求的完整URL人对一下马上就能看出来哪里写错了。3.2 alt属性加载失败时的替代文案也是SEO的通行证alt是图片标签里最容易被忽略、但对用户影响最大的属性。它的作用是当图片无法加载时在图片位置显示一段文字说明当用户使用读屏软件时这段文字会被读出来搜索引擎抓取图片时也是优先读取alt内容来理解图片是什么。实际项目里我总结了两条铁律承载信息的图片alt如实描述图片内容和作用。比如一张报名二维码就写扫码报名前端交流会不要写img123。纯装饰性图片alt留空字符串alt。这样读屏软件会直接跳过它而不是读出一堆文件名的噪音。很多人纠结到底要不要写alt。我的回答是装饰性图片可以空但属性本身必须有。一个页面里一堆img连alt都没写在可访问性审计里会被直接打个大红叉。另外不要用title来代替alt这两个属性的职能完全不同。3.3 title属性与width/height属性小细节里的大问题title属性是鼠标悬停时显示的提示文本。它的定位是额外信息不是必要信息——移动端根本没有hover桌面端也未必有人会特意把鼠标放上去。所以不要把关键说明塞进title那是alt和正文该干的事。width和height属性则是用来给图片预设占位尺寸的。很多人以为它们是用来缩放图片的实际上它们真正解决的问题是布局抖动CLS浏览器在图片还没加载出来的时候就能根据这两个值预留出宽高位置防止图片加载完成后把下面的文字内容猛地挤下去。不写这两个属性图片加载慢时页面内容会跳来跳去尤其影响移动端阅读体验。这里有个细节要注意如果只设置其中一个值另一个没设现代浏览器通常会按原图比例自动计算。但我建议始终把宽高都写上并且保持与原始图片等比。否则你写死了宽高去拉伸图片在小屏上会直接变形。真正想要自适应的图片应该交给CSS的max-width: 100%和height: auto处理而不是在HTML属性里写死固定像素。4. 响应式图片与懒加载图片适配不同屏幕的进阶方案前面的width和height只是占位真正让图片在不同屏幕上都清晰显示的是响应式图片方案。这个知识走过去属于进阶但现在H5项目里几乎必用尤其是移动端适配越来越精细之后。4.1 一张图片如何服务多种屏幕srcset与sizes假设你有一张1200像素宽的产品图在手机屏幕上其实只需要显示400像素宽。如果你直接给手机端下原图它会白白浪费流量如果你只给一张400像素的小图在桌面端它又会变得模糊。srcset和sizes就是为了解决这个矛盾的。img srcimages/product-800.jpg srcsetimages/product-400.jpg 400w, images/product-800.jpg 800w, images/product-1200.jpg 1200w sizes(max-width: 600px) 400px, 800px alt产品展示图srcset里列出图片候选和各自的真实宽度sizes告诉浏览器在什么屏幕宽度下页面实际会占用多少宽度浏览器会结合设备的DPR设备像素比自己挑一张最合适的图。这个方案在开发调试时非常方便打开DevTools的设备模拟器切换不同宽度Network面板里能看到浏览器请求的图片资源会跟着变化。如果不同屏幕需要的是不同裁剪比例的图片——比如手机端要竖构图电脑端要横构图——那就得用picture了。它可以基于media条件让浏览器选择不同的srcpicture source media(max-width: 600px) srcsetimg/banner-mobile.jpg source media(min-width: 601px) srcsetimg/banner-desktop.jpg img srcimg/banner-desktop.jpg alt活动横幅 /picture注意picture里必须放一个img作为兜底否则碰到不支持的浏览器时连图都不会显示。4.2 loadinglazy与图片加载的时机选择loadinglazy是HTML原生的懒加载属性。加上之后浏览器会等图片快滚动到视口时才发起加载请求能显著减少首屏加载时间。我一般会在以下场景加页面中下部的长图、内容列表里的缩略图、不重要的广告位图。但有一个关键点首屏图片不能加。首屏里的图如果加lazy滚动交互时会看到明显的加载过程体验反而变差。另外给图片加decode相关的异步解码属性在个别场景也有用但浏览器兼容性支持参差不齐我的建议是不要过度使用优先保证src、alt、width、height、loadinglazy这几个核心属性正确。还有一个和加载相关的经典问题图片加载失败的破图状态。默认情况下图片加载失败会显示一个破碎图标很丑。我的处理方式一般是配合JS监听error事件加载失败时替换成一张占位图const imgs document.querySelectorAll(img); imgs.forEach((img) { img.addEventListener(error, function handleError() { this.src images/placeholder.png; this.removeEventListener(error, handleError); }); });一个小细节在error处理函数里把src替换成占位图后一定记得移除事件监听否则占位图加载失败会陷入无限循环。4.3 图片格式选择POST到底该用什么存图HTML层面能控制的是标签属性但实际项目中图片格式选错性能问题会特别明显。现在主流格式里格式优点缺点推荐场景JPEG色彩丰富、体积小不支持透明照片、渐变背景、复杂画面PNG支持透明、无损体积大图标、简单图形、透明底图WebP体积小、支持透明和动图老浏览器不兼容现代H5项目的默认选择AVIF体积比WebP更小兼容性更差、编码慢图片量大且目标用户浏览器较新从开发效率角度我建议在项目中以WebP为默认格式JPEG/PNG作为回退兜底。前端判断浏览器是否能加载WebP的方法其实很简单动态创建Image对象设置src为一张极小的WebP图看onload是否触发。如果能加载就请求WebP版本否则请求降级版本。这个方案配合服务端的图片处理接口能省下肉眼可见的带宽成本。5. 真实项目里的高频陷阱文本与图片标签的排查经验这一节我想把日常开发和带新人过程中反复遇到的那些看似小但很折磨人的问题集中复盘一下。每个问题我都会给出现象、原因和解决办法你照着这个思路去排查比重新翻一遍文档快得多。5.1 文本标签的翻车现场标题失控与段落嵌套现象一页面刚写完时样式正常但后来某个按钮突然排版错乱检查半天发现是页面里某个p标签没写闭合导致后续所有内容都被浏览器当作那个p的内容样式全部被继承布局直接炸开。HTML标签写不闭合在很多情况下是容错的但这种容错只是推迟了问题的爆发时间。经验是开发周期里哪怕页面再简单写完最好也用一下IDE的自动格式化或者让构建工具的校验提前介入把未闭合的标签在提交前就拦下来。现象二团队协作时文案里的强调重点字样在不同页面里有的用了strong有的用了b有的甚至用span stylefont-weight: bold;。当产品要求对强调内容做统一样式时就会发现选择器根本写不统一只能全量替换。这就是标签语义不统一带来的维护成本。我现在只要看到有人在HTML里直接用style属性写字重样式就会提醒一句能归并成CSS类的地方就别写行内样式能统一成语义标签的地方就别每次重造轮子。5.2 图片标签的翻车现场几像素间隙与撑破容器图片相关的经典坑第一个是图片底部总有几像素空隙。原因在于img默认是内联元素它要跟文字基线对齐而基线到父元素底部之间的这段空白就会显示出来。解决方式有很多最简单的是给img设置display: block或者设置vertical-align: middle。这个坑几乎人人都遇到过但我发现很多人在网上搜到答案后也没搞懂为什么下次还会犯。搞懂了基线这个概念以后再遇到任何内联元素的间距问题你都能举一反三。第二个经典问题是移动端图片撑破容器。明明父盒子宽度只有375px图片却变成一长条超出屏幕。解决办法就一行CSSimg { max-width: 100%; height: auto; }max-width: 100%让图片最大宽度不超过父容器但又不强制拉伸小图height: auto让高度自适应。这个组合应该是所有响应式页面的默认底裤。比这更进一步的方案是用object-fit: cover做固定比例裁剪但那个属于CSS进阶用法这里不展开。第三个是首屏大图加载过慢。解决问题的路径不是压缩图片本身而是考虑是不是一定得用这么一张大图。有时候设计方案里的一张宽幅banner在手机端完全可以用一张裁剪后的窄图替换成两倍图配合srcset在不同端加载不同资源比统一加载一张2MB的图片好一百倍。5.3 文本与图片标签的自查清单我每次提交前都会扫一遍分享一份我一直在用的自查清单。代码提交之前按这个顺序过一遍基本能避免90%的低级问题页面里是否只有一个h1标题层级是否按顺序排列没有跳级所有文字段落是否用了p还是堆在div里strong、em是否真的表示语义强调还是只是想要加粗和斜体需要强调但纯视觉修饰的部分是否用了b和i装饰性图片的alt是否写成了alt信息类图片的alt是否如实描述了内容每个img是否都写全了width和height有没有直接用固定像素拉伸图片移动端样式的全局CSS里是否已经设置了img { max-width: 100%; height: auto; }页面中下方的大图是否加了loadinglazy首屏图片是否确认没有加这套清单特别适合刚接触前端开发的同学直接抄作业。HTML标签这件事看十遍文档不如在真实项目里碰一遍坑但有了清单至少能让你在还没有经验的时候就提前避开那些最消耗时间的低级问题。我自己写HTML时还有一个习惯写完一个页面的静态结构之后会强制自己打开浏览器无样式模式或者临时把CSS文件禁用掉看一眼。如果在这种状态下页面的大纲依然清晰、段落依然可读、图片都有合理的替代文字说明HTML本身是健康的。反过来如果无样式状态下页面一塌糊涂那即使CSS把页面画得再好看也只是在给脆弱的骨架打补丁。文本标签和图片标签是前端开发的地基看起来简单但地基稳不稳看的就是这些细节有没有被认真对待。
返回列表