用纯html+css实现链接卡片,必须以语义化为外层容器并设有效href;内部用标题、描述、域名及带onerror兜底的加载favicon;css统一border-radius:8px,用box-shadow和font-weight实现hover反馈,并强制a:focus-visible{outline}保障可访问性。

怎么用纯 HTML + CSS 实现链接卡片基本结构
链接卡片本质是带标题、描述、域名和 favicon 的可点击容器,不需要 JS 就能渲染,但必须保证语义正确。核心是用 <a></a> 包裹整个卡片内容,而不是只包文字——否则屏幕阅读器和 SEO 会丢失上下文。
常见错误是把 <div> 当外层容器,再用 <code>onclick 模拟跳转,这会导致键盘用户无法 Tab 进入、右键菜单缺失“在新标签页打开”选项。
-
<a></a>必须有href属性,且值为有效 URL(不能是#或空字符串) - 内部标题用
<h3></h3>或<h4></h4>,别用<div class="title"> <li>描述文字用 <code><p></p>,域名区域建议用<span class="domain"></span>,便于样式隔离 - 避免在
<a></a>里嵌套其他可交互元素(如按钮、输入框),会触发浏览器兼容性警告 - 推荐用
box-shadow配合transition: box-shadow 0.2s实现轻量浮起效果 - 圆角统一用
border-radius: 8px,别设成12px 12px 0 0这类非对称值,移动端点击热区易出错 - 必须写
a:focus-visible { outline: 2px solid #007bff; },否则键盘用户找不到当前焦点 - 悬停时改字体粗细比改颜色更可靠(
font-weight: 600),避免色盲用户无感知 - 首选方案:用
https://www.google.com/s2/favicons?domain=example.com&sz=32这类公开 API(注意加referrerpolicy="no-referrer") - 必须设置
img的width/height为固定值(如16),否则加载中会塌陷布局 - 用
<img onerror="this.outerHTML=" class="initial">E"">做兜底,别用 CSS::after伪元素生成字母(无法被读屏软件识别) - 如果项目允许内联 SVG,把常用域名(github.com、twitter.com 等)的 favicon 转成 data URI 内联,彻底规避网络请求
- 静态卡片直接写死
href、data-title、data-description属性,用 CSS 变量控制主题色,零请求、零错误 - 若真需动态,用
<iframe sandbox="allow-scripts"></iframe>加载可信预览页,比自己解析 HTML 安全得多 - 禁止在
href里拼接用户输入(如javascript:alert(1)),必须用URL.canParse()校验后再渲染 - 移动端要注意
touch-action: manipulation加在卡片上,避免 300ms 点击延迟
CSS 如何控制卡片尺寸、圆角和 hover 效果
链接卡片的视觉反馈直接影响点击意愿。关键不是堆砌阴影或动画,而是确保对比度达标、焦点可见、悬停状态不破坏布局流。
容易踩的坑:用 transform: scale() 做 hover 放大,会导致文本重排、影响相邻卡片位置;或者用 opacity: 0.9 降低不透明度,让色弱用户难以识别变化。
如何安全加载 favicon 并 fallback 到域名首字母
直接 <img src="https://example.com/favicon.ico?x-oss-process=image/resize,p_40"> 会触发跨域请求失败、404 报错、甚至被浏览器屏蔽,尤其当目标站禁了 referrer 或开了 CSP。
真正可行的方案是绕过直接请求,用第三方服务代理或本地 fallback。不要依赖 rel="icon" 的自动解析逻辑,它不可控且不触发加载事件。
为什么不用 JavaScript 动态生成卡片反而更稳
很多人一上来就写 fetch() 抓 Open Graph 数据,结果卡在 CORS、超时、HTML 解析失败、XSS 过滤上。实际场景中,90% 的链接卡片数据是已知或可预置的。
动态预览只适合后台服务统一处理(如 Slack、Notion 的链接预览),前端硬做等于重复造轮子还更不可靠。
favicon 加载失败、跨域限制、键盘导航支持——这三个点最容易被跳过,但一旦出问题,卡片就从“增强体验”变成“阻断访问”。











