写在前面
这是这个新博客的第一篇文章。
从 22 年至今,我已搭建过三次博客。每一次都是技术探索与折腾的过程:从 Typecho 到 Halo,从 LNMP 架构到 Docker 部署……经历了无数次配置调试与反复取舍。
一路走来,我的心态也在悄然发生变化:曾经执着于博客的技术架构与视觉效果,而现在,我更加重视写作本身的意义。
在一次一次的键盘敲击中,将思绪梳理成文字,将技术沉淀为知识。用合适的方式表达自我,输出有价值的内容。这才是 Blog 的意义所在。
这一次,我再次找回最初那份搭建博客的初心与动力,将这个新的博客搭建了起来。
希望这个博客能长久地运营下去吧。: )
花了半个月时间,参考了许多网上的优秀实践,并结合自己的需求进行了功能整合与定制,搭建了这么一个令我较为满意的博客。
在记忆尚新的当下,于此记录搭建博客的细节。这既是为自己留下的总结与备忘,也希望为后来者提供一些参考,少走一些弯路。
开发过程均已提交 Github:项目源码
为什么是 Hugo?
私以为,对于个人开发者而言,动态博客的一些复杂功能——如用户系统、权限管理,性能监控等——显得较为多余。毕竟,写作的核心在于内容本身。
Hugo 是一个 Go 语言编写、开源的静态网站生成器。它构建速度极快,语法简洁,功能丰富,社区活跃,具备高度的灵活性和可扩展性。这些特性使得它成为搭建个人博客的理想选择。
Hugo 入门
安装
从 Github Releases 内下载适用于你系统的软件包、二进制可执行文件,或直接直接从源码编译。(建议使用 Hugo Extended 以获得额外功能的支持。)
安装完成后,在终端内运行以下命令以验证是否安装成功 :
hugo version
# 输出示例:hugo v0.147.8-10da2bd765d227761641f94d713d094e88b920ae+extended linux/amd64 BuildDate=2025-06-07T12:59:52Z VendorInfo=gohugoio
主题选择
Hugo 官网的 主题页面 提供了许多不同用途的主题以供选择。
笔者选择了 PaperMod 主题,因其简洁现代的设计风格和良好的功能支持。
Hugo 新建站点
使用以下命令创建一个站点:
hugo new site test.io # 创建新站点
cd test.io/
git init # 创建 git 仓库,方便主题安装和后期管理
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod # 使用 git submodule 添加主题
echo "theme = 'PaperMod'" >> hugo.toml # 在配置文件中指定使用 PaperMod 主题
hugo server # 启动 Hugo 本地服务器
你会在终端中看到本地站点的 URL(通常为 http://localhost:1313)。通过浏览器访问即可看见 PaperMod 的默认页面效果:

站点结构
新建站点的结构:
test.io/
├── archetypes
│ └── default.md # 文章模板
├── assets # css、js等资源
├── content # 博客内容
├── data # 一些数据
├── hugo.toml # 网站配置文件
├── i18n # 多语言相关文件
├── layouts # 网站布局相关
├── public # 渲染后的 HTML 代码目录
├── static # 网站的字体和 favicons
└── themes # 主题文件夹
└── PaperMod
我的博客的结构:
.
├── archetypes
│ └── default.md
├── assets
│ └── css
│ ├── common
│ ├── core
│ └── extended
├── config # config 可以拆成多文件
│ └── _default
│ ├── hugo.toml
│ ├── languages.toml
│ ├── menu.en.toml
│ ├── menu.ja.toml
│ └── menu.zh.toml
├── content
│ ├── about # 三种语言的页面文档,下同
│ │ ├── _index.en.md
│ │ ├── _index.ja.md
│ │ └── _index.zh.md
│ ├── archives # 归档
│ ├── categories # 分类
│ │ ├── tech
│ │ └── test
│ ├── friends # 友链
│ ├── posts # 文章
│ │ ├── hugo-papermod-blog-guide
│ │ └── Test-Post
│ └── search # 搜索
├── data # 数据
│ ├── friends.toml
│ └── notice.toml
├── i18n # 多语言翻译
│ ├── en.yaml
│ ├── ja.yaml
│ └── zh.yaml
├── layouts # 部分自定义网络结构
│ ├── _default
│ │ ├── about.html
│ │ ├── friends.html
│ │ ├── _markup
│ │ └── terms.html
│ ├── partials
│ │ ├── comments.html
│ │ ├── extend_footer.html
│ │ ├── extend_head.html
│ │ ├── footer.html
│ │ ├── header.html
│ │ ├── math.html
│ │ ├── post_meta.html
│ │ └── toc.html
│ └── shortcodes
│ ├── collapse.html
│ ├── friends.html
│ ├── notice.html
│ ├── quote.html
│ ├── sidenote.html
│ └── social_icons.html
├── LICENSE
├── public
├── README.md
├── static # 字体和网站图标
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.png
│ ├── favicon.svg
│ └── fonts
└── themes
Hugo 的基础命令
使用 hugo new
根据文章模板在 content
文件夹中新增内容:
hugo new posts/Test-Post.md
结构如下:
content
content/
└── posts
└── Test-Post.md
使用 hugo
正式生成静态网页:
hugo
构建完成后,Hugo 会将所有内容输出到 public
目录下,结构如下:
public
public/
├── 404.html
├── assets
│ └── css
│ └── stylesheet.8fe10233a706bc87f2e08b3cf97b8bd4c0a80f10675a143675d59212121037c0.css
├── categories
│ ├── index.html
│ └── index.xml
├── index.html
├── index.xml
├── page
│ └── 1
│ └── index.html
├── posts
│ ├── index.html
│ ├── index.xml
│ └── page
│ └── 1
│ └── index.html
├── sitemap.xml
└── tags
├── index.html
└── index.xml
使用 hugo server
开启本地预览服务器
hugo server -D # -D 参数会生成草稿内容
然后你可以访问 http://localhost:1313 预览网站。
一些我常用的参数:
参数 | 含义 |
---|---|
--cleanDestinationDir | 清空输出目录 |
-D | 构建草稿内容 |
--bind 0.0.0.0 | 允许外部访问 |
-p 1313 | 指定端口号 |
--baseURL | 设置基础 URL |
Hugo 配置
Hugo 配置文件
一般为站点根目录下的单一配置文件 hugo.toml
或 hugo.yaml
、 hugo.json
文件。
笔者选择了 .toml
文件。
或是将配置拆分为多个文件,建立文件夹如下:
config/
└── _default
├── hugo.toml
├── languages.toml
├── menu.en.toml
├── menu.ja.toml
└── menu.zh.toml
详见 https://gohugo.io/configuration/introduction/#configuration-directory
笔者配置如下,供大家参考:
hugo.toml
baseURL = 'https://ruixi.top/' # 网站根地址
title = "Ruixi's Blog" # 网站标题
theme = 'PaperMod' # 使用的主题名称
languageCode = 'en-US'
defaultTheme = "dark" # 默认使用暗色背景主题
buildDrafts = false # 是否构建草稿
buildFuture = false # 是否构建未来发布的内容
buildExpired = false # 是否构建已过期的内容
defaultContentLanguage = "en" # 顶部首先展示的语言界面
enableRobotsTXT = true # 是否生成 robots.txt 文件
enableInlineShortcodes = true # 是否启用内联 shortcode
enableEmoji = true # 是否启用 Emoji 表情支持
defaultContentLanguageInSubdir = true # 是否要在地址栏加上默认的语言代码
[minify]
disableXML = true # 防止 XML 文件被压缩出错
minifyOutput = true # 启用压缩优化输出体积
[permalinks]
post = "/:slug/" # 自定义文章永久链接格式
[caches]
[caches.images]
dir = ':cacheDir/images' # 设置图片缓存目录
[outputs]
home = ["HTML", "RSS", "JSON"]
[markup]
[markup.highlight]
codeFences = false
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
[markup.goldmark.extensions]
typographer = false # 禁用goldmark符号替换
[services]
[services.googleAnalytics]
id = 'G-H5HDF4EPT6' # Google Analytics ID
[params]
author = "Ruixi" # 站点作者信息
defaultTheme = "dark" # 网站标题
math = true # 数学公式支持
comments = true # 评论功能
showToc = true # 显示文章目录(TOC)
tocOpen = true # TOC 是否默认展开
showPostNavLinks = true # 显示文章导航链接
showBreadCrumbs = true # 显示面包屑导航
showRssButtonInSectionTermList = true # RSS 相关按钮显示
showAllPagesInArchive = true # 在归档页面显示所有页面
showCodeCopyButtons = true # 显示代码块复制按钮
showWordCount = true # 显示文章字数统计
showLastMod = true # 显示最后修改时间
disableScrollToTop = false # 启用返回顶部按钮
displayFullLangName = true
fancyBox = true # 启用 Fancybox 灯箱效果
dateFormat = "2006/01/02" # 日期格式化
hideSummary = false
[params.assets]
favicon = "favicon.png"
[params.fuseOpts]
isCaseSensitive = false # 是否大小写敏感
shouldSort = true # 是否排序
location = 0
distance = 1000
threshold = 0.4
minMatchCharLength = 2 # limit = 20 # 限制返回的搜索结果数量
keys = ["title", "permalink", "summary", "content"]
includeMatches = true
language.toml
[en]
title = "Ruixi's Blog"
languageName = "English"
languageCode = "en"
[en.params.homeInfoParams]
Title = "Hi there. 👋"
Content = "This is Ruixi's cozy corner on the web."
[[en.params.socialIcons]]
name = "Github"
title = "Github"
icon = "Github"
url = "https://github.com/Ruixi-Cheng/"
[[en.params.socialIcons]]
name = "Bilibili"
title = "Bilibili"
icon = "Bilibili"
url = "https://space.bilibili.com/329971737"
[zh]
...
[ja]
...
menu.en.toml
[[main]]
name = "Posts"
title = "Posts"
pageRef = "/posts/"
weight = 1 # 权重值,决定先后顺序
[[main]]
name = "Categories"
title = "Categories"
pageRef = "/categories/"
weight = 2
[[main]]
name = "Tags"
title = "Tags"
pageRef = "/tags/"
weight = 3
[[main]]
name = "Archives"
title = "Archives"
pageRef = "/archives/"
weight = 4
[[main]]
name = "Search"
title = "Search"
pageRef = "/search/"
weight = 5
[[main]]
name = "Friends"
title = "Friends"
pageRef = "/friends/"
weight = 6
[[main]]
name = "About"
title = "About"
pageRef = "/about/"
weight = 7
文章元数据
在 archetypes/default.md
中,我们添加以下内容
+++
title = 'title'
slug = 'slug' # URL 标识符
date = 2025-06-22T18:20:00+08:00
lastmod = 2025-06-22T18:20:00+08:00 # 最后编辑时间
draft = true # 是否为草稿
categories = ["categories"] # 类别
tags = ["tags"] # 标签
+++
在用 hugo new
新建文章的时候,这些字段应会被自动添加在文件开头。如果自己在 post
目录下新建文章,请手动添加这些数据。
创建常用页面
在使用 Hugo 构建个人博客时,除了基本的文章发布功能外,我们通常还会创建一些额外的页面,如「归档」、「关于」和「友链」等。
「归档」页面
在 content
目录中创建 archive.md
文件,或是 archive
文件夹结构如下:
content/archives/
├── _index.en.md
├── _index.ja.md
└── _index.zh.md
archive.md:
+++
title = "Archives"
layout = "archives"
+++
在配置文件的 [[menu.main]]
添加如下字段即可:
name = "Archives"
title = "Archives"
pageRef = "/archives/" # 页面链接地址
weight = 4 # 菜单排序权重值
关于 toml
的结构,本文不做过叙述。
「关于」页面
添加 layouts/_default/about.html
文件。
{{- define "main" }}
<header class="page-header">
<h1>{{ .Title }}</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
<section>
<br>
{{ .Content }}
</section>
{{- end }}{{/* end main */}}
再如上文新增「归档」页面,创建 about.md
文件,或是 about
文件夹。
Markdown 内容如下:
+++
title = "About"
layout = "about"
+++
写你想写的内容
Hugo 配置文件添加相关菜单字段即可。
「友链」页面
添加 layout/shortcodes/friends.html
文件。
<div class="friends">
{{ range .Site.Data.friends.list.friends}}
<div class="friend-skeleton">
<a href="{{ .link }}" target="_blank">
<div class="friend">
<img class="friend-avatar" src="{{ .image }}" />
<div class="friend-content">
<div class="friend-name">{{ .title }}</div>
<div class="friend-description">{{ .intro }}</div>
</div>
</div>
</a>
</div>
{{ end }}
</div>
添加 assets/css/extended/friends.css
文件:
friends.css
.friends {
--link-count-per-row: 1;
}
@media screen and (min-width: 640px) {
.friends {
--link-count-per-row: 2;
}
}
.friends {
display: grid;
grid-template-columns: repeat(var(--link-count-per-row), 1fr);
grid-gap: 20px;
}
.friend-skeleton {
height: 100px;
/* 调整为合适的高度 */
display: inline-block;
position: relative;
}
.friend {
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: 0.67s cubic-bezier(0.19, 1, 0.22, 1);
border-radius: var(--radius);
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12) !important;
overflow: hidden;
display: flex;
align-items: center;
/* 垂直居中 */
padding: 16px;
background-color: var(--entry);
/* 可选背景色 */
}
.friend:hover {
transform: translateY(-8px);
box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2),
0 5px 8px 0 rgba(0, 0, 0, 0.14), 0 1px 14px 0 rgba(0, 0, 0, 0.12) !important;
}
.friend-avatar {
object-fit: cover;
width: 72px;
height: 72px;
border-radius: 50%;
/* 圆形头像 */
margin-right: 16px;
/* 和文字之间留点空隙 */
flex-shrink: 0;
/* 防止被压缩 */
border: 2px solid color-mix(in srgb, var(--primary) 48%, transparent);
}
.friend-content {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
overflow: hidden;
}
.friend-name {
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 4px;
}
.friend-description {
font-size: 0.9rem;
color: var(--secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
添加 layouts/_default/friends.html
文件:
{{- define "main" }}
<header class="page-header">
<h1>{{ .Title }}</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
<section>
<br>
{{ .Content }}
</section>
{{- end }}{{/* end main */}}
最后在 content
文件夹中新增 friends.md
或 friends
文件夹。
内容如下,这是一个和「关于」很类似的页面,只是多调用了 friends
Shortcode。
+++
title = "Friends"
layout = "friends"
+++
{{< friends >}}
友链数据储存在 data/friends.toml
[list]
[[list.friends]]
title = "张三的博客"
intro = "张三"
link = "https://zhangsan.github.io/"
image = "图片url"
[[list.friends]]
title = "李四的博客"
intro = "李四"
link = "https://lisi.top/"
image = "图片url"
「搜索」页面
「搜索」是 PaperMod 主题自带的页面
在 content
文件夹中新增 search.md
或对应的 search
文件夹。
+++
title = "Search"
layout = "search"
+++
在 Hugo 配置文件中按需修改相关参数,并添加相关菜单字段即可。
[params.fuseOpts]
isCaseSensitive = false # 是否大小写敏感
shouldSort = true # 是否排序
location = 0 # 匹配起始位置
distance = 1000 # 字符距离阈值
threshold = 0.4 # 匹配相似度阈值
minMatchCharLength = 2 # limit = 20 # 限制返回的搜索结果数量
keys = ["title", "permalink", "summary", "content"] # 搜索字段
includeMatches = true # 返回匹配项详情
「标签」界面
「标签」也是 PaperMod 自带的页面,直接添加 Hugo 配置文件的相关菜单字段即可。
不过我改动了许多的「标签」页面 CSS。
assets/css/extended/tag-cloud.css
/*标签云*/
.terms-tags {
text-align: center;
}
.terms-tags a {
font-size: 24px;
font-weight: 100;
color: var(--primary);
display: inline-block;
background: none;
border-radius: var(--radius);
transition: transform 0.5s;
}
.terms-tags a:hover {
background: color-mix(in srgb, var(--code-block-bg) 100%, transparent);
border-radius: var(--radius);
transform: scale(1.2);
transition: all 0.3s ease;
}
.dark.terms-tags a {
font-size: 24px;
font-weight: 100;
color: var(--primary);
display: inline-block;
background: none;
border-radius: var(--radius);
transition: transform 0.5s;
}
.dark .terms-tags a:hover {
background: color-mix(in srgb, var(--code-block-bg) 50%, transparent);
box-shadow: 0 0 15px var(--code-bg);
border-radius: var(--radius);
transform: scale(1.2);
transition: all 0.3s ease;
}
.terms-tags li {
margin: 5px;
}
「分类」页面
参考了 道与的不拆笔记 - PaperMod 主题自定义类别页面 (纸张合并本拟物风格) 。
将 themes/PaperMod/layouts/_default/terms.html
复制到 layouts/_default/terms.html
并对其进行修改。
修改后的 terms.html
{{- define "main" }}
{{- if .Title }}
<header class="page-header">
<h1>{{ i18n .Title | default .Title }}</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
{{- end }}
{{ if (eq .Type "categories") }}
<div class="container">
{{- $type := .Type }}
{{- range $key, $value := .Data.Terms.Alphabetical }}
{{- $name := .Name }}
{{- $count := .Count }}
{{- $maxCount := 5 }}
{{ $actualCount := 0 }}
{{ if lt $count $maxCount }}
{{ $actualCount = $count }}
{{ else }}
{{ $actualCount = $maxCount }}
{{ end }}
{{- with $.Site.GetPage (printf "/%s/%s" $type $name) }}
<a href="{{ .Permalink }}">
<div class="card" style="--cards: {{ $count }};">
<div class="child">
<h2>{{ i18n .Title | default .Title }}</h2>
{{ with .Page.Params.description }}
<span>{{ . }}</span>
{{ end }}
<p>{{ $count }} {{ i18n "category_articles_count" }}</p>
{{ if .Page.Params.image }}
<img src="{{ .Page.Params.image | relURL }}" alt="{{ .Page.Params.alt }}" />
{{ end }}
</div>
{{ range seq 1 $actualCount }}
<div class="child"></div>
{{ end }}
</div>
</a>
{{- end }}
{{- end }}
</div>
{{ else if (eq .Type "tags") }}
<ul class="terms-tags">
{{- $type := .Type }}
{{- range $key, $value := .Data.Terms.Alphabetical }}
{{- $name := .Name }}
{{- $count := .Count }}
{{- with site.GetPage (printf "/%s/%s" $type $name) }}
<li>
<a href="{{ .Permalink }}">{{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup> </a>
</li>
{{- end }}
{{- end }}
</ul>
{{ end}}
<style>
.container {
max-width: 900px;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
grid-gap: 48px;
margin: 0 auto;
}
.card {
cursor: pointer;
position: relative;
height: 0;
padding-bottom: 120%;
--offset-multiplier: 4px;
transition: transform 0.6s ease;
--translate: 0;
transform: translate(var(--translate), var(--translate));
}
.card:hover {
--offset-multiplier: 6px;
--translate: calc(-1px * (var(--cards) - 1));
transition: transform 0.3s ease, -webkit-transform 0.3s ease;
}
.child {
position: absolute;
width: 100%;
height: 100%;
padding: 8px 16px 8px 16px;
box-sizing: border-box;
background: var(--entry);
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1), 0px -4px 8px rgba(0, 0, 0, 0.1);
border-radius: 6px;
transition: inherit;
--translate: calc(var(--offset) * var(--offset-multiplier));
transform: translate(var(--translate), var(--translate));
z-index: 5;
font-family: 'LXGWWenKai', monospace !important;
color:rgba(var(--nordrgb4), 0.9);
}
.child p {
bottom: 1rem;
right: 1rem;
position: absolute;
color:rgba(var(--nordrgb4), 0.4);
font-family: 'NotoSansSC', monospace !important;
}
.child img {
position: absolute;
top: 60%;
left: 50%;
border-radius: var(--radius);
transform: translate(-50%, -50%);
width: auto;
height: auto;
max-width: 90%;
max-height: 90%;
z-index: -100;
opacity: 0.5;
}
.child:nth-child(1) {
--offset: 0;
z-index: 4;
}
.child:nth-child(2) {
--offset: 1;
z-index: 3;
}
.child:nth-child(3) {
--offset: 2;
z-index: 2;
}
.child:nth-child(4) {
--offset: 3;
z-index: 1;
}
.child:nth-child(5) {
--offset: 4;
z-index: 0;
}
.child:nth-child(6) {
--offset: 5;
z-index: -1;
}
.child:nth-child(7) {
--offset: 6;
z-index: -2;
}
.child:nth-child(8) {
--offset: 7;
z-index: -3;
}
.child:nth-child(9) {
--offset: 8;
z-index: -4;
}
.child:nth-child(10) {
--offset: 9;
z-index: -5;
}
@media (max-width: 768px) {
.container {
grid-gap: 16px;
padding: 0 24px;
max-width: 80%
}
.child p {
font-size: 0.85rem;
right: 0.5rem;
bottom: 0.5rem;
}
}
</style>
{{- end }}{{/* end main */ -}}
主要是为其增加了 categories
内容和相关 CSS 样式。
本博客的 CSS 中的颜色代码部分无法直接使用,请根据自身情况修改
在 content/categories/
内新建文件 类别名.md
content/categories/
└── test
├── _index.en.md
├── _index.ja.md
└── _index.zh.md
内容如下:
+++
title = "test"
description = "test"
image = "图片URL"
alt = "test Cover" # 封面图片的替代文本
caption = "A brief description of the image" # 封面图片的标题或描述
+++
This is the test category page.
这样就新增了一个类别。效果如图:

博客样式优化
修改字体
我们可以为博客应用自定义字体,以提升阅读体验和整体视觉风格。。
笔者的博客用了以下三种字体:
NotoSansSC
:作为正文字体FiraCode Nerd Font
:作为代码字体霞鹜文楷
(LXGWWenKai):作为点缀
为了减少网页加载时间并适配现代浏览器,我们可以将本地字体文件转换为更高效的 woff2
格式。
用 Google 开源的 woff2
工具进行压缩:
./woff2_compress FiraCodeNerdFont-Regular.ttf
将压缩后的字体文件放入 Hugo 的静态资源目录 static/fonts
文件夹:
static/fonts/
├── FiraCodeNerdFont-Regular.woff2
├── LXGWWenKai-Regular.woff2
└── NotoSansSC-Regular.woff2
为了让浏览器提前加载关键字体资源,提高首次渲染性能,可以在 layouts/partials/extend_head.html
文件中添加如下 <link>
标签:
<link rel="preload" href="{{ "fonts/FiraCodeNerdFont-Regular.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ "fonts/NotoSansSC-Regular.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ "fonts/LXGWWenKai-Regular.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
再添加 assets/css/extended/fonts.css
文件
/* 自定义字体 */
@font-face {
font-family: 'NotoSansSC';
src: url('/fonts/NotoSansSC-Regular.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'FiraCodeNerdFont';
src: url('/fonts/FiraCodeNerdFont-Regular.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'LXGWWenKai';
src: url('/fonts/LXGWWenKai-Regular.woff2') format('woff2');
font-display: swap;
}
/* 应用于整个网站 */
body {
font-size: medium !important;
font-family: 'NotoSansSC', sans-serif !important;
}
/* 应用于代码块 */
code, pre {
font-family: 'FiraCodeNerdFont', monospace !important;
}
如果希望对某些特定元素使用不同的字体,可以直接在对应的 CSS 类中调用:
示例:对分类的 .child 组件应用霞鹜文楷
.child {
position: absolute;
width: 100%;
height: 100%;
padding: 8px 16px 8px 16px;
box-sizing: border-box;
background: var(--entry);
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1), 0px -4px 8px rgba(0, 0, 0, 0.1);
border-radius: 6px;
transition: inherit;
--translate: calc(var(--offset) * var(--offset-multiplier));
transform: translate(var(--translate), var(--translate));
z-index: 5;
font-family: 'LXGWWenKai', monospace !important;
color:rgba(var(--nordrgb4), 0.9);
}
修改博客整体配色
将 themes/PaperMod/assets/css/core/theme-vars.css
文件复制到 assets/css/core/theme-vars.css
并自行更改。
笔者根据 Nord 配色,对博客颜色主题进行了深度定制:
Nord 配色
:root {
--gap: 24px;
--content-gap: 20px;
--main-width: 720px;
--nav-width: 1280px;
--article-width: 640px;
--toc-width: 320px;
--header-height: 60px;
--footer-height: 60px;
--radius: 8px;
--nord0: #2e3440;
--nord1: #3b4252;
--nord2: #434c5e;
--nord3: #4c566a;
--nord4: #d8dee9;
--nord5: #e5e9f0;
--nord6: #eceff4;
--nordw: #ffffff;
--nord7: #8fbcbb;
--nord8: #88c0d0;
--nord9: #81a1c1;
--nord10: #5e81ac;
--nord11: #bf616a;
--nord12: #d08770;
--nord13: #ebcb8b;
--nord14: #a3be8c;
--nord15: #b48ead;
--nordrgb0: 46, 52, 64;
--nordrgb1: 59, 66, 82;
--nordrgb2: 67, 76, 94;
--nordrgb3: 76, 86, 106;
--nordrgb4: 216, 222, 233;
--nordrgb5: 229, 233, 240;
--nordrgb6: 236, 239, 244;
--nordrgbw: 255, 255, 255;
--nordrgb7: 143, 188, 187;
--nordrgb8: 136, 192, 208;
--nordrgb9: 129, 161, 193;
--nordrgb10: 94, 129, 172;
--nordrgb11: 191, 97, 106;
--nordrgb12: 208, 135, 112;
--nordrgb13: 235, 203, 139;
--nordrgb14: 163, 190, 140;
--nordrgb15: 180, 142, 173;
/* Light mode colors using Nord */
--theme: var(--nordw);
--entry: var(--nord6);
--primary: var(--nord1);
--secondary: var(--nord3);
--tertiary: var(--nord6);
--content: var(--nord2);
--code-block-bg: var(--nord6);
--code-bg: var(--nord6);
--border: var(--nord4);
}
.dark {
--theme: var(--nord0);
--entry: var(--nord1);
--primary: var(--nord6);
--secondary: var(--nord4);
--tertiary: var(--nord1);
--content: var(--nord5);
--code-block-bg: var(--nord1);
--code-bg: var(--nord1);
--border: var(--nord3);
}
你可以根据自己的喜好修改配色文件。
修改代码高亮样式
本博客使用了 highlight.js
插件来实现代码高亮,而不是 Hugo 自带的 Chroma
渲染器。至于为何选择 highlight.js
,笔者一时也记不清具体原因了 ToT。
首先,在 Hugo 配置文件中将 Chroma
禁用,避免冲突:
[markup]
[markup.highlight]
codeFences = false
然后在 layouts/partials/extend_footer.html
文件内添加 highlight.js
插件。
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
document.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
});
</script>
最后将你希望使用的代码高亮样式文件(.css
)放在 assets/css/extended
文件夹下即可。可以在 https://cdnjs.com/libraries/highlight.js
下载你喜欢的高亮样式主题。
以下是一个简单的 CSS 示例,可以为明暗模式分别设置不同的代码高亮样式:
.hljs {
color: #383a42;
background: #fafafa
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic
}
...
body.dark {
.hljs {
background: #2e3440
}
.hljs,
.hljs-subst {
color: #d8dee9
}
...
}
本博客采用的代码高亮样式为:
- 明亮模式:
Atom One Light
- 黑暗模式:
Nord
本博客代码高亮样式:assets/css/extended/hljs.css
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em !important
}
code.hljs {
padding: 3px 5px
}
/*
Atom One Light by Daniel Gamage
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
base: #fafafa
mono-1: #383a42
mono-2: #686b77
mono-3: #a0a1a7
hue-1: #0184bb
hue-2: #4078f2
hue-3: #a626a4
hue-4: #50a14f
hue-5: #e45649
hue-5-2: #c91243
hue-6: #986801
hue-6-2: #c18401
*/
.hljs {
color: #383a42;
background: #fafafa
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #a626a4
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e45649
}
.hljs-literal {
color: #0184bb
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string {
color: #50a14f
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #986801
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #4078f2
}
.hljs-built_in,
.hljs-title.class_,
.hljs-class .hljs-title {
color: #c18401
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: bold
}
.hljs-link {
text-decoration: underline
}
body.dark {
.hljs {
background: #2e3440
}
.hljs,
.hljs-subst {
color: #d8dee9
}
.hljs-selector-tag {
color: #81a1c1
}
.hljs-selector-id {
color: #8fbcbb;
font-weight: 700
}
.hljs-selector-attr,
.hljs-selector-class {
color: #8fbcbb
}
.hljs-property,
.hljs-selector-pseudo {
color: #88c0d0
}
.hljs-addition {
background-color: rgba(163, 190, 140, .5)
}
.hljs-deletion {
background-color: rgba(191, 97, 106, .5)
}
.hljs-built_in,
.hljs-class,
.hljs-type {
color: #8fbcbb
}
.hljs-function,
.hljs-function>.hljs-title,
.hljs-title.hljs-function {
color: #88c0d0
}
.hljs-keyword,
.hljs-literal,
.hljs-symbol {
color: #81a1c1
}
.hljs-number {
color: #b48ead
}
.hljs-regexp {
color: #ebcb8b
}
.hljs-string {
color: #a3be8c
}
.hljs-title {
color: #8fbcbb
}
.hljs-params {
color: #d8dee9
}
.hljs-bullet {
color: #81a1c1
}
.hljs-code {
color: #8fbcbb
}
.hljs-emphasis {
font-style: italic
}
.hljs-formula {
color: #8fbcbb
}
.hljs-strong {
font-weight: 700
}
.hljs-link:hover {
text-decoration: underline
}
.hljs-comment,
.hljs-quote {
color: #4c566a
}
.hljs-doctag {
color: #8fbcbb
}
.hljs-meta,
.hljs-meta .hljs-keyword {
color: #5e81ac
}
.hljs-meta .hljs-string {
color: #a3be8c
}
.hljs-attr {
color: #8fbcbb
}
.hljs-attribute {
color: #d8dee9
}
.hljs-name {
color: #81a1c1
}
.hljs-section {
color: #88c0d0
}
.hljs-tag {
color: #81a1c1
}
.hljs-template-variable,
.hljs-variable {
color: #d8dee9
}
.hljs-template-tag {
color: #5e81ac
}
.language-abnf .hljs-attribute {
color: #88c0d0
}
.language-abnf .hljs-symbol {
color: #ebcb8b
}
.language-apache .hljs-attribute {
color: #88c0d0
}
.language-apache .hljs-section {
color: #81a1c1
}
.language-arduino .hljs-built_in {
color: #88c0d0
}
.language-aspectj .hljs-meta {
color: #d08770
}
.language-aspectj>.hljs-title {
color: #88c0d0
}
.language-bnf .hljs-attribute {
color: #8fbcbb
}
.language-clojure .hljs-name {
color: #88c0d0
}
.language-clojure .hljs-symbol {
color: #ebcb8b
}
.language-coq .hljs-built_in {
color: #88c0d0
}
.language-cpp .hljs-meta .hljs-string {
color: #8fbcbb
}
.language-css .hljs-built_in {
color: #88c0d0
}
.language-css .hljs-keyword {
color: #d08770
}
.language-diff .hljs-meta,
.language-ebnf .hljs-attribute {
color: #8fbcbb
}
.language-glsl .hljs-built_in {
color: #88c0d0
}
.language-groovy .hljs-meta:not(:first-child),
.language-haxe .hljs-meta,
.language-java .hljs-meta {
color: #d08770
}
.language-ldif .hljs-attribute {
color: #8fbcbb
}
.language-lisp .hljs-name,
.language-lua .hljs-built_in,
.language-moonscript .hljs-built_in,
.language-nginx .hljs-attribute {
color: #88c0d0
}
.language-nginx .hljs-section {
color: #5e81ac
}
.language-pf .hljs-built_in,
.language-processing .hljs-built_in {
color: #88c0d0
}
.language-scss .hljs-keyword,
.language-stylus .hljs-keyword {
color: #81a1c1
}
.language-swift .hljs-meta {
color: #d08770
}
.language-vim .hljs-built_in {
color: #88c0d0;
font-style: italic
}
.language-yaml .hljs-meta {
color: #d08770
}
}
修改表格样式
参考了 https://yunpengtai.top/posts/hugo-journey/#%e8%a1%a8%e6%a0%bc 。
PaperMod 主题自带的表格样式不是很好看,笔者对其进行了修改。
效果如下:

表格样式-修改前
表格样式-修改后
添加 assets/css/extended/table.css
文件即可:
table.css
table,
.dark table {
border-collapse: collapse;
display: table;
margin-bottom: 1rem;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
thead th {
text-align: center;
vertical-align: middle;
border-bottom: 2px solid var(--code-bg);
}
td,
th {
text-align: center;
vertical-align: middle;
border-top: 1px solid var(--code-bg);
border-bottom: 1px solid var(--code-bg);
}
tbody tr:hover {
background-color: var(--code-bg);
}
tbody tr:nth-of-type(2n + 1) {
background-color: var(--code-bg);
}
tr:last-of-type {
border-bottom: 2px solid var(--code-bg);
}
}
侧边悬浮目录
参考了 https://yunpengtai.top/posts/hugo-journey/#%e4%be%a7%e8%be%b9%e6%82%ac%e6%b5%ae%e7%9b%ae%e5%bd%95 。
功能增强
giscus 评论系统集成
基础集成
参考了 意琦行的个人博客 - Hugo 博客引入 Giscus 评论系统 。
本博客的评论系统为 giscus ,允许访客通过 GitHub 账号发表评论和互动。
利用 GitHub Discussions 实现的评论系统,让访客借助 GitHub 在你的网站上留下评论和反应吧!本项目深受 utterances 的启发。
- 开源。🌏
- 无跟踪,无广告,永久免费。📡 🚫
- 无需数据库。所有数据均储存在 GitHub Discussions 中。
- 支持自定义主题!🌗
- 支持多种语言。🌐
- 高可配置性。🔧
- 自动从 GitHub 拉取新评论与编辑。🔃
- 可自建服务!🤳
摘自 giscus 官网。
在其官网上填写你的仓库信息和你想要的配置,你会得到如下的 HTML 代码:
<script src="https://giscus.app/client.js"
data-repo="[ENTER REPO HERE]"
data-repo-id="[ENTER REPO ID HERE]"
data-category="[ENTER CATEGORY NAME HERE]"
data-category-id="[ENTER CATEGORY ID HERE]"
data-mapping="specific"
data-term='posts/{{ .Params.slug }}'
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="transparent_dark"
data-lang="zh-CN"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>
将上述代码保存至 layouts/partials/comments.html
文件,并在 Hugo 配置文件中启用评论功能:
[params]
comments = true
至此,即可完成 giscus 的基础集成。
实现多语言支持
本博客实现了评论系统的多语言支持。
笔者对 comments.html
进行了修改,使其根据当前页面的语言自动切换 giscus 的界面语言。
修改后的 comments.html
{{ $giscusLang := "en" }} {{ if eq site.Language.Lang "zh" }} {{ $giscusLang =
"zh-CN" }} {{ else if eq site.Language.Lang "zh-tw" }} {{ $giscusLang = "zh-TW"
}} {{ else if eq site.Language.Lang "zh-hk" }} {{ $giscusLang = "zh-HK" }} {{
else if eq site.Language.Lang "ar" }} {{ $giscusLang = "ar" }} {{ else if eq
site.Language.Lang "be" }} {{ $giscusLang = "be" }} {{ else if eq
site.Language.Lang "bg" }} {{ $giscusLang = "bg" }} {{ else if eq
site.Language.Lang "ca" }} {{ $giscusLang = "ca" }} {{ else if eq
site.Language.Lang "cs" }} {{ $giscusLang = "cs" }} {{ else if eq
site.Language.Lang "da" }} {{ $giscusLang = "da" }} {{ else if eq
site.Language.Lang "de" }} {{ $giscusLang = "de" }} {{ else if eq
site.Language.Lang "el" }} {{ $giscusLang = "gr" }} {{ else if eq
site.Language.Lang "eo" }} {{ $giscusLang = "eo" }} {{ else if eq
site.Language.Lang "es" }} {{ $giscusLang = "es" }} {{ else if eq
site.Language.Lang "eu" }} {{ $giscusLang = "eu" }} {{ else if eq
site.Language.Lang "fa" }} {{ $giscusLang = "fa" }} {{ else if eq
site.Language.Lang "fr" }} {{ $giscusLang = "fr" }} {{ else if eq
site.Language.Lang "he" }} {{ $giscusLang = "he" }} {{ else if eq
site.Language.Lang "hu" }} {{ $giscusLang = "hu" }} {{ else if eq
site.Language.Lang "id" }} {{ $giscusLang = "id" }} {{ else if eq
site.Language.Lang "it" }} {{ $giscusLang = "it" }} {{ else if eq
site.Language.Lang "ja" }} {{ $giscusLang = "ja" }} {{ else if eq
site.Language.Lang "km" }} {{ $giscusLang = "kh" }} {{ else if eq
site.Language.Lang "ko" }} {{ $giscusLang = "ko" }} {{ else if eq
site.Language.Lang "nl" }} {{ $giscusLang = "nl" }} {{ else if eq
site.Language.Lang "pl" }} {{ $giscusLang = "pl" }} {{ else if eq
site.Language.Lang "pt" }} {{ $giscusLang = "pt" }} {{ else if eq
site.Language.Lang "ro" }} {{ $giscusLang = "ro" }} {{ else if eq
site.Language.Lang "ru" }} {{ $giscusLang = "ru" }} {{ else if eq
site.Language.Lang "th" }} {{ $giscusLang = "th" }} {{ else if eq
site.Language.Lang "tr" }} {{ $giscusLang = "tr" }} {{ else if eq
site.Language.Lang "uk" }} {{ $giscusLang = "uk" }} {{ else if eq
site.Language.Lang "uz" }} {{ $giscusLang = "uz" }} {{ else if eq
site.Language.Lang "vi" }} {{ $giscusLang = "vi" }} {{ end }}
<script src="https://giscus.app/client.js"
data-repo="[在此输入仓库]"
data-repo-id="[在此输入仓库 ID]"
data-category="[在此输入分类名]"
data-category-id="[在此输入分类 ID]"
data-mapping="specific"
data-term='posts/{{ .Params.slug }}'
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="transparent_dark"
data-lang="{{ $giscusLang }}"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>
效果示例:


通过以上配置,即可在 Hugo 博客中实现评论系统的多语言适配。
多语言共享评论区
若希望多个语言版本的文章共享同一评论区,需要确保所有语言版本使用相同的 slug
。
为此,在 Hugo 配置文件中设置链接规则:
[permalinks]
post = "/:slug/"
这样,每篇文章的 URL 格式变为 https://[你的域名]/[语言代码(如果配置了多语言)]/posts/[文章的 slug]
。
例如,本篇博文的元数据如下:
+++
title = 'Hugo 博客搭建指南'
slug = 'hugo-blog-guide'
date = 2025-06-22T18:20:00+08:00
lastmod = 2025-06-25T15:50:00+08:00
draft = false
categories = ["Blog"]
tags = ["hugo","blog","tinker"]
+++
则其 URL 为: http://ruixi.top/zh/posts/hugo-blog-guide/
。
在 comments.html
中设置了如下参数:
data-mapping="specific"
data-term='posts/{{ .Params.slug }}'
这些参数会使 giscus 以文章的 posts/[:slug]
为关键字去匹配 GitHub Discussions 中的评论话题,从而实现跨语言共享评论区。
折叠块功能
参考 https://yunpengtai.top/posts/hugo-journey/ 。
这是一个非常实用的小功能,能在博客内折叠隐藏较长或非核心内容(长代码块、文字等),提升页面整洁度与阅读体验。
效果展示:
这是折叠的代码
#include <stdio.h>
int main()
{
printf("Hello, World!");
return 0;
}
为此,需新增 layouts/shortcodes/collapse.html
文件:
{{ if .Get "summary" }}
{{ else }}
{{ warnf "missing value for param 'summary': %s" .Position }}
{{ end }}
<p><details {{ if (eq (.Get "openByDefault") true) }} open=true {{ end }}>
<summary markdown="span">{{ .Get "summary" | markdownify }}</summary>
{{ .Inner | markdownify }}
</details></p>
使用也很方便,参考下图:

支持两个参数:
summary
:用于设置折叠面板的标题(必填)openByDefault
:布尔值,控制面板是否默认展开(可选)
Fancybox 图片灯箱效果
参考了 人生筆記簿 - hugo-使用-fancybox-实现图片灯箱-放大功能 。
添加 layouts/_default/_markup/render-image.html
文件:
{{if .Page.Site.Params.fancybox }}
<div class="post-img-view">
<a data-fancybox="gallery" href="{{ .Destination | safeURL }}" data-caption="{{ .Text }}">
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}" {{ end }} />
</a>
</div>
{{ end }}
修改 Hugo 配置文件,以启用灯箱效果:
[param]
fancyBox = true
在 layouts/partials/extend_footer.html
中增加:
{{if .Page.Site.Params.fancybox }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js"></script>
{{ end }}
盘古之白
受到 🏄♂️ 不入流的人生解决方案 - 不入流的文体|关于「盘古之白」和「直角引号」 的启发。
在中文与英文、数字或符号混排时,应适当加入一个空格,这能让文字之间的界限更清晰,视觉上也更舒适。
漢學家稱這個空白字元為「盤古之白」,因為它劈開了全形字和半形字之間的混沌。
另有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。
與大家共勉之。
本博客在写作过程中尽量遵循「盘古之白」的排版原则。不过为了以防万一,也引入了一个 JS 插件自动处理这个问题。
在 layouts/partials/extend_footer.html
内新增以下代码来引入 pangu.js
。
<script src="https://cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.js"></script>
<script>
pangu.spacingPage();
</script>
更优雅的引用
语句引用
参考了 https://yunpengtai.top/posts/hugo-journey/#blockquote ,并结合自己的需求进行了增强。
在博客中引用名人名言时,使用自定义的 quote
短代码让内容更美观。
e.g.: 莎士比亚引用
{{< quote author="William Shakespeare" >}}
To be, or not to be, that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take Arms against a Sea of troubles,
And by opposing end them: to die, to sleep
{{< /quote >}}
渲染效果如下:
To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take Arms against a Sea of troubles, And by opposing end them: to die, to sleep
实现方式
创建短代码模板文件 layouts/shortcodes/quote.html
,内容如下:
<blockquote class="quote">
{{- $content := .Inner -}}
{{- if not (strings.HasPrefix $content "<p>") -}}
<p style="white-space: pre-line">{{ .Inner }}</p>
{{- else -}}
{{ $content }}
{{- end -}}
{{- with .Get "author" -}}
<footer class="blockquote-footer text-right">
— {{ . }}
</footer>
{{- end -}}
</blockquote>
添加样式文件 assets/css/extended/quote.css
,内容如下:
/* 公共样式提取 */
blockquote.quote{
position: relative;
margin: 1em auto;
padding-left: 2.5em !important;
border: none;
font-style: italic; /* 统一引用文字风格 */
line-height: 1.6;
background: var(--theme) !important;
color: var(--secondary);
}
/* 引号统一样式 */
blockquote.quote::before{
content: "\"";
position: absolute;
left: 0;
top: 0;
font-size: 3em;
font-weight: bold;
font-style: italic;
line-height: 1;
color: var(--secondary); /* 可根据主题色设置颜色 */
}
blockquote.quote footer.blockquote-footer {
margin-top: 1rem;
font-size: 0.9em;
color: var(--secondary);
text-align: right;
}
居中引用
参考了 荷戟独彷徨 - 自定义 Hugo Shortcodes 简码
笔者认为非常适合用来引用诗词。
十里青山远,潮平路带沙 数声啼鸟怨年华 又是凄凉时候,在天涯 白露收残月,清风散晓霞 绿杨堤畔问荷花 记得年时沽酒,那人家
这样使用:
{{< quote-center >}}
十里青山远,潮平路带沙
数声啼鸟怨年华
又是凄凉时候,在天涯
白露收残月,清风散晓霞
绿杨堤畔问荷花
记得年时沽酒,那人家
{{< /quote-center >}}
实现方式
先加入短代码模板文件 layouts/shortcodes/quote-center.html
内容如下:
<blockquote class="quote-center">
{{- $content := .Inner -}}
{{- if not (strings.HasPrefix $content "<p>") -}}
<p style="white-space: pre-line">{{ .Inner }}</p>
{{- else -}}
{{ $content }}
{{- end -}}
</blockquote>
再加入 CSS 文件 assets/css/extended/quote-center.css
,笔者这里使用了 霞鹜文楷
字体:
.quote-center {
font-family: 'LXGWWenKai', sans-serif !important;
position: relative;
background: none !important;
border-inline-start: 0 !important;
border-left: none;
padding-left: 0;
border-top: 1px solid var(--code-bg);
border-bottom: 1px solid var(--code-bg);
p{
text-align: center !important;
margin-top: 1.5em;
margin-bottom: 1.5em;
}
&::before {
position: absolute;
left: 0;
content: '“';
color: var(--code-bg);
font-size: 3em;
font-weight: bold;
margin-top: -0.25em;
}
&::after {
position: absolute;
right: 0;
content: '”';
color: var(--code-bg);
font-size: 3em;
font-weight: bold;
margin-top: -0.6em;
}
}