HTML
HTML
介绍
历史
- 历史上使用过和正在讨论的网页构建方案很多,比如:单页面和多页面、前后端分离与不分离,这些方案各有优缺点,根据需求选择需要的构建方案很重要
浏览器工作原理
主要以谷歌文档和相关的文章为主,其他浏览器的原理和实现可能有不同之处
- 一个浏览器页面中有多个子线程处理页面渲染、插件执行、
GPU调度等功能,同时有一个浏览器主进程创建页面、插件进程来协调子线程,其中专门处理页面的线程一般有- 渲染主线程:早期文章中称为
GUI线程,渲染的工作(主要由blink、webkit这样的渲染内核完成)包括渲染页面,解析html和css,构建DOM和Render Tree,进行渲染布局和绘制,此线程同时负责调度执行js - 渲染的
impl线程:属于渲染进程的一部分,但不是主线程,也称为合成器线程Compositor Thread。生成位图图层,合成图层是由此线程完成的,会和GPU线程进行交互 GPU进程:处理3D绘制等调用GPU的情况- 显示合成线程:也称为
viz合成器线程(visuals),是可视化服务的一部分,负责最终画面合成
- 显示合成线程:也称为
- 事件触发进程:管理事件触发,将任务添加到
js的一个消息队列末尾,等待JS线程执行 - 定时器进程:管理定时任务,
js是单线程且可能被挂起,使用额外的浏览器线程确保时间准确,触发定时 - 网络请求进程:解析地址,请求对应的资源
- 渲染主线程:早期文章中称为
浏览器页面渲染
从
url被输入开始,浏览器执行的步骤(整个过程被称为关键路径)主要有:开启网络请求线程,将
url作为请求地址,进行http/https请求,包括地址解析、dns查询、tcp请求过程- 地址解析
https://example.com:443/page?id=1#id:包括协议头(https://)、地址(example.com)、端口号(:443)、目录路径(/center)、查询参数(?id=1)和页面锚点(#id)- 协议头告知浏览器通信方式
- 地址和端口号用于定位服务器位置和访问端口
- 目录路径和请求参数需要被发送给服务器
- 页面锚点一般不用发送给服务器,仅在浏览器处理
- 如果地址不是
ip地址,经过dns查询,得到服务器的ip地址- 过程中会先查询浏览器内部和系统缓存,如果缓存中存在,则直接返回缓存数据,否则才会向
DNS服务器查询 - 如果服务器使用了
CDN负载均衡,得到的是CDN服务器集群中响应用户最快的CDN服务器地址,CDN服务器会作为中间代理,代替用户请求,并缓存内容
- 过程中会先查询浏览器内部和系统缓存,如果缓存中存在,则直接返回缓存数据,否则才会向
- 进行
tcp请求,tcp是http协议的传输层协议,浏览器可能对同一域名的同时请求有最大连接数限制- 三次握手,建立连接
- 发送
http/https请求 - 在
http连接结束(有长连接和短连接)的时候四次握手,关闭连接
- 地址解析
服务器接收到请求,进行处理,最终包装回应
- 服务器内部负载均衡
- 服务器验证,如果不符合规则,比如
token验证失败,则拒绝请求Cookie校验:在互联网早期进行用户识别时使用的方式,查看cookie中的某个字段,识别用户身份等信息,存储的数据信息敏感session校验:在服务器生成一个用户会话信息,并返回给用户,用户下次请求时,会携带这个会话信息,服务器会通过会话信息验证用户信息,使用分布式服务器时难以跨服务器通信token校验:现在大规模使用的校验方法,使用token进行用户识别,用户识别成功后,会返回一个token,用户下次请求时,会通过请求头携带这个token,服务器会验证token
- 接受请求,并处理得到响应数据
浏览器对回应进行处理
- 根据
Set-Cookie头写入cookie - 查看响应状态码,将成功的响应数据
- 缓存:缓存的配置通过缓存头完成,缓存内容可以存储在浏览器
indexDB中- 强缓存:之前请求的状态
200,浏览器在判断未过期后直接使用 - 协商缓存:之前请求的状态
304,浏览器会发起请求,服务器认为数据没有在之后更新,让浏览器使用缓存
- 强缓存:之前请求的状态
- 将得到的结果提供给其他线程,比如渲染线程
- 根据
对获取到
html进行解析解析
html,生成DOM树,解析实际上是从字符开始的解析其中的
css样式,生成CSS样式树,过程和生成DOM树基本类似,只是最终得到的是CSSOM,在每个节点上挂载样式合并
DOM树和CSS样式树,生成渲染树Render Tree,此过程进行了真实样式计算
合并的 Render Tree 布局
Render Tree,计算各个元素节点的尺寸和位置信息,此过程可能因为回流重新触发绘制
Render Tree,创建绘制指令列表,现代浏览器通常通过渲染管线调度GPU来绘制,分阶段根据DOM树的背景、float、前景、outline等生成对应的指令列表,此过程也被称为栅格化准备阶段。经过这个阶段后得到的指令是矢量的描述,和设备像素等无关光栅化:光栅化是绘制后的步骤,光栅化开始,渲染主线程处理算是暂时结束了,在
impl线程中执行光栅化,将绘制指令转换为位图- 光栅化前首先需要进行内容同步,将绘制的渲染树通过
commit操作同步到impl线程,commit时主线程会被阻塞,之后光栅化会分块分图层的执行 - 光栅化分块得到的是小的光栅单元
tile,每个光栅单元可能只是256*256的小像素区域,多个单元的光栅化可以并行完成,也可以调用GPU加速这个过程,浏览器目前通常通过一个名为Skia的库调用OpenGL,当然也可以使用CPU完成 - 分层的目的是保留各层位图,不是所有的图层都会被修改,方便之后的帧中复用;分块是因为一个图层的数据量可能很大,分块可以更细粒度地复用位图,而且图层分块光栅化可以并行
- 光栅化过程还解码页面中的图片,调用合适的解码器进行解压缩
- 最终的位图包含了各像素点位的信息,存储在内存中,实际上现在像素点还未出现在屏幕上
- 光栅化前首先需要进行内容同步,将绘制的渲染树通过
合成:合成是在光栅化之后在
impl线程中进行的- 将各层的位图信息提交合并,分层可以方便确认要对那些内容进行变换,常见的变换包括动画、滚动和缩放,这些变换存储在专门的属性树中
- 这些树在
prepaint(绘制之前分析)时生成,在绘制完成后,一个提交线程会更新impl线程中的这些树副本,确保匹配主线程数据结构的状态 impl线程中有两个树的备份,因此它可以在绘制上一个提交的同时栅格化新提交的光栅单元impl线程可以对滚动、缩放这样的用户输入直接处理(无相关js事件监听),不必进入渲染主线程,提高流畅度。这些输入由浏览器的主线程分发
激活:将层树及其属性从待激活树推送到激活树,这部分是在
impl线程中完成的显示:在激活完成后,
impl线程需要利用GPU进程处理,将帧显示在浏览器视口上- 可能有多个帧同时被提交,因为页面中可以嵌入
iframe(当然出于安全考虑,嵌入内容和主内容使用的渲染线程不同,有隔离) - 显示过程需要经过
viz线程处理,经过这个线程调度skia,将内容显示在浏览器中
- 可能有多个帧同时被提交,因为页面中可以嵌入
解析过程流程图 加载优化
- 页面尤其是首页的加载快慢影响了用户对网站的认知,对用户留存和转化至关重要
- 为了更快地让用户看到页面内容,可以考虑以下优化
- 关键模块优先,其他内容都稍后加载,尽可能压缩文件数据大小
- 在可以异步加载的
js文件上使用async异步加载和defer延迟执行,甚至使用js请求完成 - 在用户开屏看不到的元素上使用
lazyload,比如使用注释的方式将它留在文件中,在需要被看见之前读取注释节点,将内容提供给父节点的innerHTML,甚至在用户鼠标交互之后再开启相关元素和样式内容的请求(使用js请求,获取元素内容字符串和对应的样式字符串,并缓存起来) - 其他图片等资源懒加载,资源信息尽可能压缩。资源放在同一域名下,减少
DNS解析事件 - 更好地利用
HTTP协议,合并CSS、js和图片资源请求,减少请求次数;使用http2开始支持的多路复用和头部压缩,提高传输效率;尽可能利用浏览器缓存,避免多次请求 - 使用
dns-prefetch,提前解析接下来可能访问的域名地址<link rel="dns-prefetch" href="//cdn.example.com"> - 使用
preconnect提前建立连接 /prefetch预加载资源 /prerender预渲染页面,提前访问/加载/渲染最有可能访问的其他页面地址,<link rel="preconnect" href="https://example.com">
帧更新
- life of a frame
- 帧更新过程
BeginFrame:由viz线程发起,基于屏幕垂直同步VSync信号,信号同时设置了一个截止时间Composite updates:Impl线程上的合成更新,例如滚动和缩放动画BeginMainFrame:发送信号给渲染主线程MainThreadUpdates:在渲染主线程上更新,例如处理输入事件、动画和样式布局更新Commit:渲染主线程提交更新给Impl线程,同页面渲染时的commit阶段wait for raster:等待光栅化activate:同页面渲染中的激活阶段- 如果光栅化在激活的截止时间前无法完成,过程将跳过,接下来将直接用待激活树
Composite updates操作可能直接触发这个阶段,比如不需要主线程处理的一些滚动更新
wait for deadline:等待截止时间submitCompositorFrame:将激活的更新作为合成帧提交给GPU进程,如果之前有任一步耗时过长,活动树不完整,则不会提交,导致丢帧GPU相关的显示操作AggregateSurfaces:viz线程在得到CompositorFrame后开始工作,将多层和多块内容进行聚合,并生成聚合的帧Draw Frame:在绘制帧过程中,显示合成器会遍历聚合合成帧中的四边形和渲染通道,并生成绘制命令RequestSwap:命令生成完成后提交给GPU主进程,发起SwapBuffers请求用来在屏幕上显示结果Wait until ready to draw:等待所有资源就绪Queueing delay:浏览器等待GPU进程处理GPU draw:执行绘制命令Swap:GPU已经处理完成,发出信号表示希望展示新帧
Presentation:显示完成,根据平台的不同,系统的合成器可能需要完成一些工作
其他渲染细节
- 解析过程中遇到外链资源的处理
- 遇到样式
link标签时CSS下载时异步,不会阻塞浏览器构建DOM树- 会阻塞渲染,也就是在构建
Render Tree时,会等到CSS下载解析完毕后才进行 - 使用
media属性的标签将仅在满足条件的情况下立刻请求,可以延迟加载甚至不加载,取值和CSS中的@media属性一致
- 遇到脚本
script标签时- 会暂停
DOM解析,把网页控制权交给js引擎,等待脚本执行完毕再继续渲染,如果脚本来自网络,还需要等待获取到脚本内容,现在v8引擎已经可以在后台使用流式资源StreamedSource接口在后台从接收到第一个代码块时开始解析编译,在执行前在渲染主线程中进行短暂的AST内部化(分配字面对象空间,嵌入地址)和字节码最终化(执行前的最后处理工作,确保数据完整无误)步骤 - 如果脚本中有操作
CSSOM,脚本会等待CSSOM解析完成,再执行 - 对于使用
async和defer属性的脚本<script async>,渲染将继续进行,defer表示等DOM树构建完毕,再按defer顺序执行脚本;async表示脚本下载是异步的,不会阻塞渲染,但脚本会在下载完成立刻执行,执行顺序不确定
- 会暂停
- 其他嵌入资源标签,如果布局不确定可能暂停当前元素渲染,等待资源获取完毕,再继续渲染当前标签,也可能估计渲染,在资源获取完毕后重新布局
- 遇到样式
- 在执行
js时,当js修改了元素内容和样式,会触发重新布局或渲染- 重新布局:也叫回流,一般认为这个元素的内容结构和位置发生了变化,需要重新计算样式和渲染树
- 渲染:即重绘,认为元素只是改变了外观,位置和大小都没有发生改变,只需要重新绘制单个元素
- 回流一般伴随重绘,一般可以通过减少回流次数,进行优化。毕竟浏览器绘制是按帧进行的,如果有部分绘制超过了浏览器的帧绘制时间,就会在下一帧绘制,造成卡顿。应该尽量减少重绘次数、减少重排次数、缩小重排的影响范围
- 减少逐项更改样式,最好一次性更改
style,或者将样式定义为class并一次性更新 - 避免在修改过程中多次读取元素布局信息,每次读取都会立刻完成之前的延迟计算,强制同步样式
- 避免循环操作不同的元素,最好先使用
absoulte分离需要大量修改尺寸布局的元素,修改完成后再还原元素
- 减少逐项更改样式,最好一次性更改
- 渲染都发生在一轮
js事件循环之后,当然不一定是每轮之后都渲染,浏览器渲染会与屏幕刷新周期同步 - 在渲染之前会先调用
requestAnimationFrame方法,在这里面的操作本质上是渲染同步操作- 不希望当前立即执行
- 希望在浏览器渲染前统一执行
- 避免中途的强制布局
DOM树
结构概述
一个
html文档解析之后会形成一个树结构,这个树结构就是DOM树,<!doctype html> <html lang="en-US"> <head> <meta charset="UTF-8" /> <title>My Document</title> </head> <body> <h1>Header</h1> <p>Paragraph</p> </body> </html>比如上面的代码经过解析后类似这样

DOM 树 空白符:可以看出其中包含了整个文档的所有节点,并包含了空白符和文本内容
会有一些空白文本节点,确保编译器保留文档的格式,有些节点只包含空白,有些节点会在开头和结尾处留有空白
内联节点间的空白符会参与行内排版:相邻的
inline内联节点(含所有用display: inline-*;展示的节点)之间换行和空格等不可见符号就会在渲染的元素之间显示出明显的空白<!-- 渲染结果:1 2 (包含一个空格) --> <span>1</span> <span>2</span> <!-- 渲染结果:1 2 --> <span>1</span> <span>2</span>需要以下方法消除内联节点之间的空白符
- 直接去除空白符,比如同行书写
- 使用注释连接
- 为父容器设置
font-size: 0;,然后为子元素设置应有的字体大小 - 避免行尾断行,使用标签结尾
>作为下一行开头 - 使用其他
display格式
<!-- 直接去除空白符 --> <span>1</span><span>2</span> <!-- 使用注释连接 --> <span>1</span><!-- --><span>2</span> <!-- 使用 font-size --> <div style="font-size: 0;"> <span style="font-size: 16px;">1</span> <span style="font-size: 16px;">2</span> </div> <!-- 避免行尾断行 --> <span>1</span ><span>2</span>CSS中定义了white-space表明如何处理文档中文本人为添加的文本节点内的空白符,见white-spacejs能够读取到节点开头和结尾的空白,当然也提供了默认忽略这些空白的方法,见获取节点元素
DOM节点类型
- 在
HTML中会遇到的DOM节点类型有七种,如果读取nodeType会获取到不同的值DOCUMENT_NODE(9): 文档节点,表示整个文档DOCUMENT_TYPE_NODE(10): 文档类型节点,比如<!DOCTYPE html>Elenement_NODE(1): 元素节点,网页上各种HTML标签节点ATTRIBUTE_NODE(2): 属性节点,比如id="id"TEXT_NODE(3): 文本节点,标签之间和标签内的文本内容COMMENT_NODE(8): 注释节点,比如<!-- 注释 -->DOCUMENT_FRAGMENT_NODE(11): 通过代码创建,创建时不是文档树的一部分,可以减少操作带来的重排和重绘,适合批量插入节点之后再移动到文档树上,移动后本身下面的所有子节点都会被转移到节点树,只留下一个空的片段
其他的还有
CDATA_SECTION_NODE(4)(一个CDATA节<!CDATA[[]]>,只在XML有效);XML的预声明PROCESSING_INSTRUCTION_NODE(7)
页面元信息
<meta>标签用于在 HTML 文档的<head>中提供页面元信息(metadata)。这些信息不会直接显示在页面上,但浏览器、搜索引擎、社交媒体、设备都可能会用到
这部分内容几乎是必须写的
charset:定义网页的字符编码,确保文本正确显示,必须放在<head>最前面- 可选值:
UTF-8:推荐编码,支持全世界文字,兼容性最好ISO-8859-1:西欧语言编码GBK:中文编码,兼容老网站
- 示例:
<meta charset="UTF-8">
- 可选值:
http-equiv="X-UA-Compatible":设置IE浏览器的渲染模式,保证页面在不同IE版本下正确显示- 可选值:
IE=edge:使用最新IE标准模式(推荐)IE=7:使用IE7兼容模式IE=8:使用IE8兼容模式chrome=1:如果安装了Chrome Frame插件,强制IE使用Chrome内核渲染页面(现在几乎不用,插件已停止支持),这个值可以出现在上述值之后,使用,分隔,比如IE=edge,chrome=1
- 示例:
<meta http-equiv="X-UA-Compatible" content="IE=edge">
- 可选值:
name="renderer":指定浏览器渲染内核,提升页面显示一致性- 可选值:
webkit:使用 Webkit 内核渲染(推荐)ie-comp:使用兼容模式内核(部分浏览器支持)
- 示例:
<meta name="renderer" content="webkit">
- 可选值:
http-equiv="Content-Type":指定文档类型和字符集- 可选值:包括内容类型和编码,使用
;分隔text/html;charset=UTF-8:HTML文档,UTF-8编码(推荐)text/html;charset=GBK:HTML文档,GBK编码
- 示例:
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
- 可选值:包括内容类型和编码,使用
viewport:控制移动端视口缩放和布局,适配不同屏幕和用户缩放行为- 可选值(可多值,用逗号
,分隔):width=device-width:视口宽度自适应设备屏幕,值也可以是一个具体的数字,表示视口的具体宽度像素height=device-height:视口高度自适应设备屏幕,一般不用initial-scale=1.0:初始缩放比例,数字必须在0.0-10.0之间minimum-scale=1.0:最小缩放比例maximum-scale=1.0:最大缩放比例user-scalable=no:禁止缩放(iOS可能不支持),yes表示允许缩放viewport-fit=cover:适配刘海屏
- 示例:
<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover">
移动端渲染
默认的渲染机制是尽可能将所有的内容展示在移动端视口内,这会导致媒体查询
@media得到的虚拟视口大小不会是预先设计的低像素大小,比如640px或更小,这导致媒体查询创建响应式界面失效<meta name="viewport" ...>可以缓解这一问题- 可以将视口设置为限定大小,比如具体像素值或
device-width,这样媒体查询就能正确识别 - 可以设置初始缩放比例为
1,确保内容正确显示,能清晰看见 - 必要时可以拒绝缩放,设置最大最小比例和禁止缩放
- 可选值(可多值,用逗号
refresh:定时刷新页面或跳转到指定 URL- 可选值:
time;url格式,time为秒数,url可选,表示跳转目标 - 示例:
<meta http-equiv="refresh" content="5;url=https://example.com">
- 可选值:
expires:指定页面过期时间,用于缓存控制- 可选值:HTTP 格式时间字符串,如
Wed, 26 Oct 2025 11:00:00 GMT - 示例:
<meta http-equiv="expires" content="Wed, 26 Oct 2025 11:00:00 GMT">
- 可选值:HTTP 格式时间字符串,如
cache-control:控制页面缓存策略,类似HTTP头- 可选值:
no-cache:不使用缓存,需向服务器验证no-store:不存储缓存must-revalidate:必须重新验证缓存- 可组合使用,用逗号
,分隔
- 示例:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
- 可选值:
Cache-Control/no-transform:防止代理服务器对内容进行修改(如图片压缩或广告插入),保证页面原样传输- 可选值:
no-transform - 示例:
<meta http-equiv="Cache-Control" content="no-transform">
- 可选值:
pragma:旧版HTTP缓存控制,主要兼容早期浏览器。主要作用是告诉浏览器不要缓存页面- 可选值:
no-cache - 示例:
<meta http-equiv="Pragma" content="no-cache">
- 可选值:
applicable-device:声明网页适用的设备类型- 可选值:
pc:桌面端mobile:移动端tablet:平板
- 示例:
<meta name="applicable-device" content="pc">
- 可选值:
no-siteapp:阻止某些移动浏览器(主要是国内浏览器)自动生成“适配移动端”的网页- 可选值:
no-siteapp - 示例:
<meta http-equiv="Cache-Control" content="no-siteapp">
- 可选值:
虽然有很多属于
http-equiv的元标签,但功能独立,http-equiv的内容也不同,需要分开作为多个写
搜索引擎优化 SEO 是一种透过了解搜索引擎的运作规则来调整网站,以及提高目的网站在有关搜索引擎内排名的方式
description:提供网页的摘要信息,显示在搜索结果中- 可选值:任意文本,通常控制在
150-160个字符以内 - 示例:
<meta name="description" content="description text">
- 可选值:任意文本,通常控制在
keywords:定义页面关键字,用于搜索引擎索引(很多现代搜索引擎会忽略)- 可选值:逗号分隔的关键字列表,例如
k1, k2, k3 - 示例:
<meta name="keywords" content="k1, k2, k3">
- 可选值:逗号分隔的关键字列表,例如
robots:控制搜索引擎对页面的索引行为- 可选值:多值可以用逗号分隔组合,如
index,follow,noarchiveall/none:快捷方式,all等同于index,follow,none等同于noindex,nofollowindex/noindex:是否收录页面follow/nofollow:是否爬取页面链接noarchive:禁止搜索引擎缓存副本
- 示例:
<meta name="robots" content="index,follow">
:::: import SEO 优化
- 虽然元数据可以定义搜索引擎爬取的内容和逻辑,但一个网站的内容和体验才是核心
- 现代搜索引擎主要靠内容主题相关性、用户点击率与停留时间、网站权威度和
E-E-A-T(专业性、经验、可信度)判别排名优先级,搜索引擎已经重内容主题关联性,而不是查看堆砌的关键词 - 良好的加载速度和移动端访问性
- 使用
HTTPS确保数据安全 - 有清晰的结构化标题层级,有丰富的列表、图片等资源,提升可读性
- 好的内链互通及外链建设,内容之间自然互链
- 现代搜索引擎主要靠内容主题相关性、用户点击率与停留时间、网站权威度和
- 还应该考虑方便搜索引擎检索,整体思路如下
在根目录配置
robots.txt,配置抓取和网站地图User-agent: * Allow: / Disallow: /admin/ Sitemap: https://example.com/sitemap.xml创建网站地图
sitemap.xml,并考虑在百度站长平台和Google等平台提交,不应该包含404等无关页面,具体配置项见sitemaps.org<?xml version="1.0" encoding="UTF-8"?> <!-- 网址列表 --> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <!-- 子网址 --> <loc>https://example.com/</loc> <!-- 更新时间 --> <lastmod>2025-11-03</lastmod> <!-- 更新频率 --> <changefreq>weekly</changefreq> <!-- 搜索展示优先级 --> <priority>1.0</priority> </url> <sitemap> <!-- 子 sitemap --> <loc>https://example.com/sub_sitemap.xml</loc> </sitemap> </urlset>如果是用户可见的
sitemap.xml,可以直接使用表格等展示,搜索引擎应该也能理解添加
JSON-Ld(可能不太重要,很多大网站没加)<script type="application/ld+json"> { "@context": "http://schema.org", "@type": "Organization", "name": "您的公司名称", "url": "https://www.yourwebsite.com", "logo": "https://www.yourwebsite.com/logo.png" } </script>
::::
- 可选值:多值可以用逗号分隔组合,如
og是一个国际的社交分享标准,官网在The Open Graph protocol,国内外大量社交平台都支持此标准
og:title:指定社交平台分享时的标题- 可选值:任意文本,用作分享标题
- 示例:
<meta property="og:title" content="网页标题">
og:description:指定社交平台分享时的描述内容- 可选值:任意文本,用作分享摘要
- 示例:
<meta property="og:description" content="页面简介">
og:image:指定分享时显示的缩略图- 可选值:图片
URL - 示例:
<meta property="og:image" content="https://example.com/img.jpg">
- 可选值:图片
og:url:指定分享页面的URL- 可选值:页面完整
URL - 示例:
<meta property="og:url" content="https://example.com">
- 可选值:页面完整
og:type:指定分享页面的类型- 可选值:
article、website等 - 示例:
<meta property="og:type" content="article">
- 可选值:
twitter:card:指定Twitter分享卡片类型- 可选值:
summary:显示小图和文本摘要summary_large_image:显示大图和文本摘要app:显示应用信息卡片player:嵌入视频/音频卡片
- 示例:
<meta name="twitter:card" content="summary_large_image">
- 可选值:
theme-color:设置移动浏览器工具栏或地址栏的颜色- 可选值:任意有效颜色值,如
#RRGGBB或rgba() - 示例:
<meta name="theme-color" content="#0d6efd">
- 可选值:任意有效颜色值,如
application-name:设置 Web 应用名称,用于浏览器书签或 PWA 显示- 可选值:任意文本
- 示例:
<meta name="application-name" content="MyApp">
apple-mobile-web-app-capable:是否允许 iOS Safari 全屏显示网页- 可选值:
yes:允许全屏显示no:不允许全屏显示(默认)
- 示例:
<meta name="apple-mobile-web-app-capable" content="yes">
- 可选值:
apple-mobile-web-app-status-bar-style:设置 iOS 全屏网页的状态栏样式- 可选值:
default:默认样式black:黑色状态栏black-translucent:半透明黑色状态栏
- 示例:
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
- 可选值:
format-detection:禁止 iOS 自动识别电话号码、地址等- 可选值:
telephone=no:禁止自动识别电话号码address=no:禁止自动识别地址email=no:禁止自动识别邮箱
- 示例:
<meta name="format-detection" content="telephone=no">
- 可选值:
referrer:控制浏览器发送的Referer头信息- 可选值:
no-referrer:不发送 Refererorigin:仅发送源域名strict-origin-when-cross-origin:跨域时仅发送源域名(默认推荐)
- 示例:
<meta name="referrer" content="no-referrer">
- 可选值:
Content-Security-Policy(CSP):控制网页资源加载策略,防止 XSS 或其他恶意注入- 可选值:由多个指令组成,每个指令定义允许加载的资源类型和来源
- 常用指令:
default-src:默认允许的资源来源,所有未明确指定类型的资源遵循该规则script-src:允许加载的 JavaScript 来源style-src:允许加载的 CSS 来源img-src:允许加载的图片来源connect-src:允许的 AJAX/WebSocket 等连接来源font-src:允许加载的字体来源media-src:允许加载的音视频来源frame-src:允许加载的 iframe 来源
- 来源值:
'self':本域名'none':不允许任何来源- URL 或域名,如
https://example.com 'unsafe-inline'/'unsafe-eval':允许内联脚本或 eval(不推荐)
- 常用指令:
- 示例:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://example.com">
- 可选值:由多个指令组成,每个指令定义允许加载的资源类型和来源
Permissions-Policy:控制浏览器 API 权限,允许或禁止页面使用摄像头、麦克风、地理位置等- 可选值:列出 API 名称及允许值,多个 API 用逗号分隔
- 常用 API:
camera:摄像头访问microphone:麦克风访问geolocation:地理位置访问fullscreen:全屏 APIpayment:支付 API
- 值:
():禁止该 API'self':仅允许本域名- URL 列表:允许指定来源
- 常用 API:
- 示例:
<meta http-equiv="Permissions-Policy" content="camera=(),microphone=(),geolocation='self'">
- 可选值:列出 API 名称及允许值,多个 API 用逗号分隔
DNT/Do Not Track:告知浏览器或第三方服务用户是否开启“拒绝跟踪”- 可选值:
1:用户选择不被追踪0:用户允许追踪
- 示例:
<meta http-equiv="DNT" content="1">
- 可选值:
Strict-Transport-Security(HSTS):强制浏览器使用 HTTPS 访问网站- 可选值:
max-age=SECONDS:强制HTTPS的持续时间includeSubDomains:应用到子域名preload:加入HSTS预加载列表
- 示例:
<meta http-equiv="Strict-Transport-Security" content="max-age=31536000; includeSubDomains">
- 可选值:
X-Content-Type-Options:防止浏览器MIME类型嗅探- 可选值:
nosniff:禁止MIME类型嗅探
- 示例:
<meta http-equiv="X-Content-Type-Options" content="nosniff">
- 可选值:
X-Frame-Options:防止网页被嵌入iframe,减少点击劫持风险- 可选值:
DENY:禁止任何域嵌入SAMEORIGIN:仅允许同源嵌入
- 示例:
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN">
- 可选值:
X-XSS-Protection:启用或禁用浏览器XSS过滤- 可选值:
0:禁用1:启用1; mode=block:启用并阻止渲染被检测的脚本
- 示例:
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
- 可选值:
自定义元标签
有的时候,可能需要自定义标签,用于用户行为统计,匿名分析,可以添加自定义的元标签
<!-- 和一般标签一样 --> <meta name="custom-meta" content="custom-value"> <!-- 类似社交平台分享标签 --> <meta property="custom-meta" content="custom-value"> <script> var meta1 = document.querySelector('meta[name="custom-meta"]'); // 通过 property 获取标签内容 var meta2 = document.querySelector('meta[property="custom-meta"]'); // 获取标签内容 console.log(meta1.content, meta2.content); // 设置标签内容 meta1.content = 'new-value'; meta2.content = 'new-value'; </script>
元素标签
script
- 如果希望在
script中的字符串中写入</script>,需要使用转义字符<\/script>或进行字符串拼接'</' + 'script>',也可以动态创建script标签对象
表单控件
input
- 限制
- 长度限制:maxlength
- 输入正则限制:pattern
- 类型限制:type
- 数字范围限制:min、max、step
嵌入标签
嵌入标签的属性和css样式的优先级
在这里介绍了许多嵌入标签的属性,这些宽高属性可以帮助浏览器在渲染过程中预先留下空间,避免内容加载完成导致页面重新布局,但这些属性的优先级低于CSS样式
其他
可自闭合的标签
HTML 规范里,可自闭合的标签void elements是固定的一组,比如:<br>、<img>、<hr>、<input>、<meta>、<link> 等,这些标签本身没有内容,所以自闭合是合法的,但有些标签比如textarea标签要求必须有内容,所以不能自闭合
强行自闭合会导致浏览器渲染分析出错,觉得应该是漏写了结尾标签,从而把之后页面内容都作为标签内的信息
