css.ChromaStyles
返回语法高亮器使用的 CSS 样式表。
(0.165.0 新增)
css.ChromaStyles 函数以 Resource 对象的形式返回语法高亮器使用的 CSS 样式表。当 noClasses 选项为 false 时需要这份样式表:它既可以在项目配置中作为全局默认值设置,也可以在使用下列任一功能时单独指定:
highlight短代码transform.Highlight函数transform.HighlightCodeBlock函数- Markdown 围栏代码块信息串中的高亮选项
Hugo 会缓存结果,因此用相同的选项多次调用该函数不会带来额外开销。
选项
css.ChromaStyles 函数需要一个选项映射。其中 targetPath 是唯一必填的选项。
classDark- (
string) 当modeSelector为true且mode为dark时,用于限定选择器作用域的 CSS 类名。默认是dark。 classLight- (
string) 当modeSelector为true且mode为light时,用于限定选择器作用域的 CSS 类名。默认是light。 highlightStyle- (
string) 高亮行的前景色与背景色,例如#fff000 bg:#000fff。默认取所选style定义的颜色。 lineNumbersInlineStyle- (
string) 行内行号的前景色与背景色,例如#fff000 bg:#000fff。默认取所选style定义的颜色。 lineNumbersTableStyle- (
string) 表格行号的前景色与背景色,例如#fff000 bg:#000fff。默认取所选style定义的颜色。 mode- (
string) 颜色模式,取light或dark。指定的样式必须支持该模式。省略这个选项时,Hugo 使用样式自身的默认模式。 modeSelector- (
bool) 是否把 CSS 选择器限定在顶层模式类之下。例如light模式的样式表会把选择器限定在.light之下,生成.light .chroma而不是.chroma。要生成配对使用的明暗两份样式表时,把它设为true。默认是false。 omitClassComments- (
bool) 是否在生成的样式表中省略 CSS 类注释前缀。默认是false。 style- (
string) 语法高亮样式。默认取项目配置中的style值。可用样式列表见语法高亮样式。 targetPath- (
string) 资源的目标路径,相对于publishDir。必填。
示例
前两个示例用 partials.IncludeCached 函数从 base 模板调用 partial 模板。两个示例都假定项目配置如下:
[markup.highlight]
noClasses = false
style = 'github'单一样式表
要使用项目配置中的 style 值生成并引入样式表:
{{ $opts := dict "targetPath" "css/highlight.css" }}
{{ with css.ChromaStyles $opts }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}明暗两份样式表
要为同时支持两种模式的样式生成并引入配对的明暗两份样式表:
{{ $opts := dict
"mode" "light"
"targetPath" "css/highlight-light.css"
}}
{{ with css.ChromaStyles $opts }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}
{{ $opts := dict
"mode" "dark"
"modeSelector" true
"targetPath" "css/highlight-dark.css"
}}
{{ with css.ChromaStyles $opts }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}浅色样式表不限定作用域,充当默认值。深色样式表的选择器限定在 dark 类之下,因此其中的规则只有在根元素带有该类时才生效。
完整示例
这个示例为站点加上浅色/深色/跟随系统的主题切换器,并用 css.Build 函数把生成的样式表打包进主 CSS 文件。
- 第 1 步
- 在项目配置中加入:
[markup.highlight] noClasses = false style = 'github' - 第 2 步
- 创建一个 CSS 入口文件,用
@import语句引入生成的样式表,并为页面其余部分写好浅色与深色规则:assets/css/main.css @import "./highlight-light.css"; @import "./highlight-dark.css"; html { background-color: #fff; color: #000; color-scheme: light; } a { color: #00e; } html.dark { background-color: #000; color: #fff; color-scheme: dark; } html.dark a { color: #6af; } - 第 3 步
- 创建一个 partial 模板来生成这些样式表,并把它们与 CSS 入口文件打包在一起:
layouts/_partials/css.html {{ $opts := dict "mode" "light" "targetPath" "css/highlight-light.css" }} {{ $highlightLight := css.ChromaStyles $opts }} {{ $opts := dict "mode" "dark" "modeSelector" true "targetPath" "css/highlight-dark.css" }} {{ $highlightDark := css.ChromaStyles $opts }} {{ with resources.Get "css/main.css" }} {{ $opts := dict "importContext" (slice $highlightLight $highlightDark) "minify" (cond hugo.IsDevelopment false true) "sourceMap" (cond hugo.IsDevelopment "linked" "none") }} {{ with . | css.Build $opts }} {{ if hugo.IsDevelopment }} <link rel="stylesheet" href="{{ .RelPermalink }}"> {{ else }} {{ with . | fingerprint }} <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} {{ end }} {{ end }} {{ end }}importContext选项让生成的样式表在css.Build解析 CSS 入口文件中的@import语句时可用。 - 第 4 步
- 创建一个 JavaScript 文件来控制主题切换器:把手动选择持久化到本地存储,并在访问者选择「跟随系统」时跟随操作系统的偏好:
assets/js/main.js const root = document.documentElement; const fieldset = document.getElementById('theme-switcher'); const mq = window.matchMedia('(prefers-color-scheme: dark)'); const applyTheme = (theme) => { if (theme === 'dark') { root.classList.add('dark'); } else if (theme === 'light') { root.classList.remove('dark'); } else { root.classList.toggle('dark', mq.matches); } fieldset.querySelector(`input[value="${theme ?? 'system'}"]`).checked = true; }; // Keep class in sync with system preference when no manual override is set. mq.addEventListener('change', () => { if (!localStorage.getItem('theme')) { root.classList.toggle('dark', mq.matches); } }); applyTheme(localStorage.getItem('theme')); fieldset.addEventListener('change', (e) => { const next = e.target.value === 'system' ? null : e.target.value; if (next === null) { localStorage.removeItem('theme'); } else { localStorage.setItem('theme', next); } applyTheme(next); }); - 第 5 步
- 创建一个 partial 模板来处理这段 JavaScript:
layouts/_partials/js.html {{ with resources.Get "js/main.js" }} {{ $opts := dict "minify" (cond hugo.IsDevelopment false true) "sourceMap" (cond hugo.IsDevelopment "linked" "none") }} {{ with . | js.Build $opts }} {{ if hugo.IsDevelopment }} <script defer src="{{ .RelPermalink }}"></script> {{ else }} {{ with . | fingerprint }} <script defer src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script> {{ end }} {{ end }} {{ end }} {{ end }} - 第 6 步
- 从 base 模板调用这两个 partial 模板,并加入主题切换器的标记。
head元素中的内联脚本会在首次绘制之前应用主题,避免深色主题的访问者加载页面时闪出浅色内容:layouts/baseof.html <!DOCTYPE html> <html lang="{{ site.Language.Locale }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{ site.Title }}</title> <script> const theme = localStorage.getItem('theme'); document.documentElement.classList.toggle('dark', theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)); </script> {{ partialCached "css.html" . }} {{ partialCached "js.html" . }} </head> <body> <header> <fieldset id="theme-switcher"> <legend>Color scheme</legend> <label><input type="radio" name="theme" value="light"> Light</label> <label><input type="radio" name="theme" value="dark"> Dark</label> <label><input type="radio" name="theme" value="system"> System</label> </fieldset> </header> <main> {{ block "main" . }}{{ end }} </main> </body> </html> - 第 7 步
- 要验证上述配置,在首页加入一个围栏代码块:
content/_index.md ```go func printGreeting(showGreeting bool) { if showGreeting { fmt.Println("Hello, World!") } } ```