link 标签
<link> 元素用于在 HTML 文档与外部资源之间建立关联。它最常用于引入 CSS 样式表和网站图标(favicon),同时也支持多种资源提示(如预连接、预加载)。
前置知识
阅读本节前,建议先了解:base 基准 URL
基础概念
link 的作用
<link> 是一个空元素(自闭合标签),位于 <head> 中,用于定义当前文档与外部资源之间的关系。它本身不显示任何内容,但会告诉浏览器去加载或关联指定的资源。
html
<head>
<!-- 引入外部样式表 -->
<link rel="stylesheet" href="style.css">
<!-- 引入网站图标 -->
<link rel="icon" href="favicon.ico">
<!-- 预连接到第三方域名 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
</head>link 与 script/style 的区别
| 元素 | 位置 | 主要用途 | 是否自闭合 |
|---|---|---|---|
<link> | <head> | 关联外部资源(CSS、图标等) | 是 |
<style> | <head> | 内联 CSS 样式 | 否 |
<script> | <head> 或 <body> | 引入或内联 JavaScript | 视情况 |
语法
基本语法
html
<link rel="关系类型" href="资源URL" [其他属性]>核心属性
| 属性 | 必需 | 说明 |
|---|---|---|
rel | 是 | 定义当前文档与链接资源的关系 |
href | 视情况 | 资源的 URL |
type | 否 | 资源的 MIME 类型 |
media | 否 | 媒体查询条件 |
sizes | 否 | 图标尺寸(用于 icon) |
crossorigin | 否 | 跨域资源如何处理 |
integrity | 否 | 子资源完整性校验 |
as | 否 | 预加载时的资源类型 |
title | 否 | 样式表的标题(用于可选样式表) |
详细说明
rel 属性种类详解
rel(relationship)是 <link> 最核心的属性,它定义了当前文档与目标资源之间的关系。以下是常用的 rel 值:
样式表相关
| rel 值 | 说明 | 示例 |
|---|---|---|
stylesheet | 引入外部 CSS 样式表 | <link rel="stylesheet" href="style.css"> |
preload | 预加载关键资源 | <link rel="preload" href="font.woff2" as="font"> |
prefetch | 预取下一页面可能需要的资源 | <link rel="prefetch" href="next-page.js"> |
图标相关
| rel 值 | 说明 | 示例 |
|---|---|---|
icon | 网站图标(favicon) | <link rel="icon" href="favicon.ico"> |
apple-touch-icon | iOS 添加到主屏幕的图标 | <link rel="apple-touch-icon" href="apple-icon.png"> |
mask-icon | Safari pinned tab 图标 | <link rel="mask-icon" href="safari-pinned.svg" color="#0066cc"> |
网络相关(资源提示)
| rel 值 | 说明 | 示例 |
|---|---|---|
preconnect | 提前建立连接 | <link rel="preconnect" href="https://fonts.googleapis.com"> |
dns-prefetch | 提前解析 DNS | <link rel="dns-prefetch" href="https://cdn.example.com"> |
prerender | 预渲染下一页面(已废弃) | 不推荐使用 |
modulepreload | 预加载 ES 模块 | <link rel="modulepreload" href="app.mjs"> |
文档关联
| rel 值 | 说明 | 示例 |
|---|---|---|
canonical | 指定页面的规范 URL | <link rel="canonical" href="https://example.com/page"> |
alternate | 替代版本(语言、格式等) | <link rel="alternate" hreflang="en" href="en/page.html"> |
manifest | Web App Manifest | <link rel="manifest" href="/site.webmanifest"> |
prev / next | 分页导航 | <link rel="next" href="page-2.html"> |
amphtml | AMP 版本 | <link rel="amphtml" href="page.amp.html"> |
其他
| rel 值 | 说明 |
|---|---|
help | 帮助文档链接 |
author | 文档作者链接 |
license | 文档许可证链接 |
pingback | Pingback URL |
webmention | Webmention 端点 |
media 属性
media 属性允许你为不同的媒体类型或条件指定不同的样式表:
html
<!-- 默认样式(所有设备) -->
<link rel="stylesheet" href="style.css">
<!-- 仅打印时使用 -->
<link rel="stylesheet" href="print.css" media="print">
<!-- 仅屏幕宽度大于 768px 时使用 -->
<link rel="stylesheet" href="desktop.css" media="(min-width: 768px)">
<!-- 仅屏幕宽度小于等于 768px 时使用 -->
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">
<!-- 暗色主题 -->
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
<!-- 高对比度模式 -->
<link rel="stylesheet" href="high-contrast.css" media="(prefers-contrast: high)">性能优化
浏览器只会下载匹配当前媒体条件的样式表。这意味着 media="print" 的样式表不会在屏幕浏览时加载,可以减少不必要的网络请求。
sizes 属性
sizes 属性用于 <link rel="icon">,指定图标的不同尺寸:
html
<!-- 不同尺寸的图标 -->
<link rel="icon" href="favicon-16x16.png" sizes="16x16" type="image/png">
<link rel="icon" href="favicon-32x32.png" sizes="32x32" type="image/png">
<link rel="icon" href="favicon-192x192.png" sizes="192x192" type="image/png">
<!-- 使用 any 表示自适应尺寸(如 SVG 图标) -->
<link rel="icon" href="favicon.svg" sizes="any" type="image/svg+xml">type 属性
type 属性指定资源的 MIME 类型。对于 CSS 样式表,通常不需要显式指定(浏览器能自动推断),但在某些情况下(如引入非 CSS 资源时)很有用:
html
<!-- CSS 样式表(type 可省略) -->
<link rel="stylesheet" href="style.css" type="text/css">
<!-- SVG 图标需要指定 type -->
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<!-- Web App Manifest -->
<link rel="manifest" href="site.webmanifest" type="application/manifest+json">实战示例
完整的 link 标签配置
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>完整的 link 标签配置</title>
<!-- 规范链接(SEO) -->
<link rel="canonical" href="https://www.example.com/page">
<!-- 多语言替代链接 -->
<link rel="alternate" hreflang="zh-CN" href="https://www.example.com/zh/">
<link rel="alternate" hreflang="en" href="https://www.example.com/en/">
<link rel="alternate" hreflang="ja" href="https://www.example.com/ja/">
<link rel="alternate" hreflang="x-default" href="https://www.example.com/">
<!-- Favicon 图标 -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<!-- Web App Manifest(PWA) -->
<link rel="manifest" href="/site.webmanifest">
<!-- 资源提示(性能优化) -->
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<!-- 外部 CSS -->
<link rel="stylesheet" href="/css/style.css">
<!-- 打印样式 -->
<link rel="stylesheet" href="/css/print.css" media="print">
<!-- 分页导航 -->
<link rel="prev" href="/articles/page-2.html">
<link rel="next" href="/articles/page-4.html">
</head>
<body>
<h1>页面内容</h1>
</body>
</html>使用 JavaScript 动态添加 link 标签
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态 link 标签</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 0 20px;
}
button {
padding: 8px 16px;
margin: 5px;
cursor: pointer;
background: #0066cc;
color: white;
border: none;
border-radius: 4px;
}
.info {
background: #f5f5f5;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
font-family: monospace;
white-space: pre-line;
font-size: 14px;
}
</style>
</head>
<body>
<h1>动态管理 link 标签</h1>
<div>
<button id="btn-list">列出所有 link 标签</button>
<button id="btn-add">添加 preload</button>
<button id="btn-toggle-dark">切换暗色主题</button>
</div>
<div class="info" id="output"></div>
<script>
var output = document.getElementById('output');
// 列出所有 link 标签
document.getElementById('btn-list').addEventListener('click', function() {
var links = document.querySelectorAll('link');
var text = '共 ' + links.length + ' 个 link 标签:\n\n';
links.forEach(function(link, i) {
text += (i + 1) + '. rel="' + link.rel + '" href="' + (link.href || '(无)') + '"\n';
});
output.textContent = text;
});
// 动态添加 preload
document.getElementById('btn-add').addEventListener('click', function() {
var preload = document.createElement('link');
preload.rel = 'preload';
preload.href = 'https://fonts.googleapis.com/css2?family=Roboto&display=swap';
preload.as = 'style';
document.head.appendChild(preload);
output.textContent = '已添加 preload link 标签。';
});
// 切换暗色主题
var darkMode = false;
var darkStyleLink = null;
document.getElementById('btn-toggle-dark').addEventListener('click', function() {
darkMode = !darkMode;
if (darkMode) {
darkStyleLink = document.createElement('link');
darkStyleLink.rel = 'stylesheet';
darkStyleLink.href = 'data:text/css,body{background:%231a1a2e!important;color:%23e0e0e0!important;}';
darkStyleLink.id = 'dark-mode';
document.head.appendChild(darkStyleLink);
output.textContent = '已启用暗色模式。';
} else {
var el = document.getElementById('dark-mode');
if (el) el.remove();
output.textContent = '已关闭暗色模式。';
}
});
</script>
</body>
</html>国际化多语言链接
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>中文页面</title>
<!-- 告诉搜索引擎各语言版本的 URL -->
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh/">
<link rel="alternate" hreflang="zh-TW" href="https://example.com/tw/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="ja" href="https://example.com/ja/">
<link rel="alternate" hreflang="ko" href="https://example.com/ko/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
<!-- 规范链接 -->
<link rel="canonical" href="https://example.com/zh/">
</head>
<body>
<h1>中文页面</h1>
<!-- 语言切换链接 -->
<nav>
<a href="/en/" lang="en">English</a>
<a href="/ja/" lang="ja">日本語</a>
</nav>
</body>
</html>注意事项
1. link 与 a 标签的区别
html
<!-- link 标签:在 head 中,定义文档级关系,不显示内容 -->
<link rel="stylesheet" href="style.css">
<!-- a 标签:在 body 中,用户可点击的导航链接 -->
<a href="other.html">其他页面</a>2. rel="stylesheet" 是阻塞渲染的
外部 CSS 文件会阻塞页面的渲染(但不会阻塞 DOM 解析)。浏览器在 CSS 下载并解析完成之前,不会渲染页面内容。
3. link 标签必须在 head 中
虽然浏览器可以容错处理 <body> 中的 <link> 标签,但规范要求 <link> 只能出现在 <head> 中。
4. 避免过多的 DNS 预解析
html
<!-- 不推荐:过多的 dns-prefetch -->
<link rel="dns-prefetch" href="https://a.example.com">
<link rel="dns-prefetch" href="https://b.example.com">
<link rel="dns-prefetch" href="https://c.example.com">
<!-- ... 更多 -->
<!-- 推荐:只预解析关键的第三方域名 -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.example.com">最佳实践
1. CSS link 放在 head 中尽早加载
html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css"> <!-- 尽早加载 -->
<title>页面标题</title>
</head>2. 为第三方资源使用 preconnect
html
<!-- 使用 Google Fonts 时 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&display=swap">3. 为 favicon 使用 SVG 格式
html
<!-- 推荐:SVG 格式,矢量图标,清晰且文件小 -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<!-- 同时提供 PNG 备用(兼容旧浏览器) -->
<link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png">4. 使用 canonical 避免重复内容
html
<!-- 每个页面都应有 canonical 链接 -->
<link rel="canonical" href="https://www.example.com/page">5. 打印样式使用 media 属性
html
<!-- 打印样式不会在屏幕浏览时加载 -->
<link rel="stylesheet" href="print.css" media="print">下一节
继续学习:CSS 样式引入