Material for MkDocs 页头定制完全指南:自动隐藏、公告栏与"标记已读"
【免费下载链接】mkdocs-materialDocumentation that simply works项目地址: https://gitcode.com/GitHub_Trending/mk/mkdocs-material
本篇指南围绕 Material for MkDocs 的页头(Header)展开,系统讲解如何在mkdocs.yml中开启页头自动隐藏、如何通过主题扩展添加公告栏(Announcement bar),以及如何让公告支持"标记已读"(Mark as read)并持久化用户偏好。文章不仅给出可直接复制运行的配置与模板代码,还深入仓库源码,说明这些功能在前端模板与 TypeScript 组件中的底层实现原理,帮助你既会用、也知其所以然。
页头里到底有什么
Material for MkDocs 的页头承担着站点导航的核心职责。从源码模板 src/templates/partials/header.html 可以看出,页头默认由以下部分组成:
- 站点 Logo 与首页链接:
config.extra.homepage或导航首页地址,点击 Logo 即可回到首页; - 移动端抽屉(drawer)开关按钮:用于在窄屏展开/收起导航;
- 页头标题:左侧显示
site_name,滚动切换时右侧会显示当前页面标题(header-title/header-topic两个组件负责切换动画); - 颜色主题切换按钮:配置了
theme.palette且为列表形式时渲染; - 站点语言切换器:配置了
config.extra.alternate时渲染; - 搜索框入口:启用
material/search插件后出现,其完整配置见 设置站点搜索; - Git 仓库入口:设置了
config.repo_url后显示,相关配置见 添加 Git 仓库。
在 src/templates/partials/header.html 中,页头的阴影状态由两个功能标志共同决定:
{% set class = "md-header" %} {% if "navigation.tabs.sticky" in features %} {% set class = class ~ " md-header--shadow md-header--lifted" %} {% elif "navigation.tabs" not in features %} {% set class = class ~ " md-header--shadow" %} {% endif %}也就是说,开启navigation.tabs.sticky(粘性标签页)时页头带阴影并被"抬起";未开启标签页时也会带阴影;而中间状态则由前端运行时动态管理(详见下文自动隐藏一节)。理解这些构成,是后续定制页头行为的基础。
配置一:页头自动隐藏(header.autohide)
页头在默认情况下始终固定在页面顶部。Material for MkDocs 自 6.2.0 起提供header.autohide功能标志:当用户向下滚动超过一定阈值时页头自动隐藏,为正文腾出更多阅读空间;一旦用户向上滚动,页头又会重新出现。
在mkdocs.yml中开启:
theme: features: - header.autohide这一功能标志同样被 docs/schema/theme.json 收录,因此使用支持 JSON Schema 的编辑器编辑mkdocs.yml时可以获得自动补全与校验提示。
底层实现:三个关键阈值
自动隐藏不是简单地"滚动就消失",其运行逻辑集中在 src/templates/assets/javascripts/components/header/_/index.ts 的isHidden函数中,从源码可以提炼出三个关键行为:
- 方向判定:组件通过
bufferCount(2, 1)连续采样两次滚动偏移量offset.y,比较前后两次大小得出滚动方向(向下或向上),见 isHidden 的方向计算; - 转折点(转向缓冲):只有滚动方向发生明显变化——即
Math.abs(y - offset.y) > 100——才允许切换隐藏状态,避免在临界点抖动闪烁,见 isHidden 的隐藏判定; - 起始阈值与搜索豁免:页头只有在下滑超过
400px之后才会进入隐藏流程;并且当搜索面板打开时(watchToggle("search")为真)绝不隐藏,确保用户随时能找到搜索入口,见 isHidden 的阈值与豁免逻辑。
最终,mountHeader在订阅时通过el.classList.toggle("md-header--shadow", active && !hidden)和el.hidden = hidden同时控制阴影与显隐,见 mountHeader 的状态管理。当页头隐藏时,正文区域会向上扩展,这正是该功能"为内容腾出空间"的实际效果。
配置二:公告栏(Announcement bar)
自 5.0.0 起,Material for MkDocs 内置了公告栏,用于在页头上方展示项目新闻、版本提醒等重要信息。与页头不同,公告栏不会一直停留:用户向下滚动经过页头后,公告栏会自动消失,不会长时间占用视口。
公告栏默认是空的,需要通过扩展主题来填充内容。首先在mkdocs.yml中启用主题自定义目录(具体流程见 扩展主题 与 覆盖模板块),然后在自定义目录中创建main.html,覆盖announce模板块:
{% extends "base.html" %} {% block announce %} <!-- Add announcement here, including arbitrary HTML --> <!-- 在此处添加公告内容,支持任意 HTML --> {% endblock %}由于announce块的内容会原样渲染为 HTML,你可以在其中自由放置链接、图标(twemoji)乃至内联样式。公告栏的实际渲染位置在 src/templates/base.html:外层容器带有data-md-component="announce"标记,内部使用.md-banner与.md-banner__inner.md-grid.md-typeset布局,因此公告内容会自动套用md-typeset排版样式,与正文视觉风格保持一致。
公告栏的视觉样式
从样式源码 src/overrides/assets/stylesheets/custom/layout/_banner.scss 可以看到,.md-banner默认使用页脚前景色系(--md-footer-fg-color--lighter)作为文字颜色,链接与strong标签会高亮为--md-footer-fg-color;内嵌的twemoji图标会被渲染为带圆环背景的圆形徽标,并在悬停时反色填充,适合用来摆放版本号、紧急通知等强调型内容。
与搜索、仓库入口的分工
公告栏位于页头之上,而页头内部还承载着 搜索栏 与 Git 仓库入口。三者分工明确:公告栏负责一次性、有时效性的信息广播;搜索与仓库入口负责常驻的导航与检索能力。如果你的站点启用了版本提示(config.extra.version),src/templates/base.html 还会在公告栏下方渲染一个md-banner--warning风格的旧版本警告条,两者互不干扰。
配置三:公告"标记已读"(announce.dismiss)
自 8.4.0 起(功能仍标记为experimental,即实验特性),Material for MkDocs 允许公告栏被用户"标记已读":公告内容右侧会出现一个关闭按钮,点击后当前公告立即消失,并且在公告内容发生变化之前不再显示。
在mkdocs.yml中开启:
theme: features: - announce.dismiss该标志同样被收录在 docs/schema/theme.json 中。开启后,src/templates/base.html 会在公告栏内渲染关闭按钮,按钮的图标取自config.theme.icon.close(默认回退到material/close),你可以通过theme.icon配置更换为其他图标。
底层实现:内容哈希与本地存储
"标记已读"的记忆机制非常精巧,其核心在 src/templates/assets/javascripts/components/announce/index.ts 的watchAnnounce与mountAnnounce两个函数中:
- 内容指纹:
mountAnnounce首次挂载时,若检测到announce.dismiss功能且公告栏非空,会计算公告内容 HTML 的哈希__md_hash(content.innerHTML),见 mountAnnounce 的初始化; - 哈希比对:如果该哈希与浏览器本地存储中的
__announce值一致,则直接设置el.hidden = true隐藏公告——这正是"不重复显示"的实现方式; - 点击持久化:
watchAnnounce监听关闭按钮的单击事件({ once: true },只触发一次),点击后同样计算当前内容哈希,并通过__md_set<number>("__announce", hash)写入localStorage,见 mountAnnounce 的持久化逻辑; - 模板侧兜底:非即时导航场景下,模板片段 src/templates/partials/javascripts/announce.html 会在页面加载时再次执行同样的哈希比对,将已读公告直接隐藏,确保刷新页面后记忆依然生效。
这套"内容哈希 + localStorage"的方案意味着:只要你在announce块中改动任何一个字符,哈希就会变化,公告便会重新对所有访客显示——无需手动清除缓存,也无需维护任何服务端状态。
与即时导航(Instant Navigation)的配合
mountAnnounce在源码中特别注释了"支持即时导航"(见 index.ts 第 85 行):在启用即时导航的站点中,页面切换不会触发整页刷新,因此组件在挂载时显式检查el.hidden并执行哈希比对,避免已读公告在切换页面后"复活"。这一细节说明该实验特性在主要使用场景下已做了充分的兼容处理。
组合使用示例与注意事项
把以上三项配置合并到一个典型的mkdocs.yml中:
theme: name: material features: - header.autohide # 向下滚动自动隐藏页头 - announce.dismiss # 公告栏支持标记已读(实验特性) icon: close: material/close # 可选:更换公告关闭按钮图标配合以下自定义main.html(放在theme.custom_dir指向的目录中):
{% extends "base.html" %} {% block announce %} <a href="https://example.com/release-notes"> 新版本 9.0.0 已发布,点击查看更新日志 </a> {% endblock %}实践中有几点值得注意:
announce.dismiss标注为实验特性,升级主题版本时留意 CHANGELOG 中的行为变更;- 公告内容请保持简洁,它位于页头之上、占用的首屏空间有限,且会随滚动自动消失;
- 若同时使用
header.autohide与navigation.tabs.sticky,滚动时页头整体(含标签页)会被隐藏,这是设计预期行为,符合"最大化内容空间"的目标; - 关闭按钮的可访问性(
aria-label)在 base.html 中已自动生成,自定义图标时无需额外处理。
至此,你已经掌握了页头自动隐藏、公告栏定制与"标记已读"三大能力的配置方法与源码级原理,可以按需组合,为你的文档站点打造更聚焦内容、更富时效信息的页头体验。
【免费下载链接】mkdocs-materialDocumentation that simply works项目地址: https://gitcode.com/GitHub_Trending/mk/mkdocs-material
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考