本文基于Hugo版本0.150.0,Stack版本3.31.0,部分代码使用AI完成
预览图


代码字体修改
使用了Fira Code字体(链接
)
<style>
@font-face {
font-family: 'mkty';
src: url({{ (resources.Get "font/mkty.ttf").Permalink }}) format('truetype');
}
@font-face {
font-family: 'Fira Code';
src:
url('/font/fira-code/FiraCode-Light.woff2') format('woff2'),
url('/font/fira-code/FiraCode-Light.woff') format('woff');
}
:root {
--base-font-family: 'mkty';
--code-font-family: 'Fira Code', 'mkty';
}
</style>其中mkty是我的主字体,我希望代码块里面的中文字体保持这个字体,于是:root{--code-font-family: 'Fira Code', 'mkty';}
Fira Code这个字体包下载完了有很多字体文件,网页用.woff和.woff2就够了,根据你喜欢的字重挑选相应的文件放到项目根目录\assets\font\下面即可
同时修改了样式:
// 代码块字体样式
code,
pre,
.highlight {
font-weight: 300 !important;
// font-size: 1.6rem;
}
//行内代码
.article-content code {
border: none;
border-radius: 4px ;
font-size: 0.85em ;
}代码块折叠展开
参考莱特雷的博客
我用了stack主题目录里自带的assets\icons\top.svg,复制了一张改了方向作为图标
主要在原代码基础上添加了折叠功能并修改了样式,java部分deepseek写的,目前电脑和平板上运行没发现问题,不保证不出问题
<style>
.highlight {
/* 你可以根据需要调整这个高度 */
max-height: 400px;
overflow: hidden;
}
.code-show {
max-height: none !important;
}
.code-more-box {
width: 100%;
padding-top: 78px;
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), to(var(--card-background)));
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
}
.code-more-btn, .code-less-btn {
display: block;
margin: auto;
width: 100%;
height: 78px;
background: none;
}
.code-less-btn {
position: absolute;
bottom: 0px;
left: 0px;
}
.code-more-img, .code-less-img{
display: block;
margin: auto;
padding-right: 1rem;
width: 60px;
position: absolute;
right: 2.5rem;
bottom: 30px;
}
.code-less-img {
bottom: 25px !important;
}
</style>
<!-- deepseek:代码折叠展开 -->
<script>
function initCodeMoreBox() {
// 新增代码开始
// 检测是否为移动端
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (isMobile) {
// 移动端直接移除所有高度限制
document.querySelectorAll('.highlight').forEach(block => {
block.style.maxHeight = 'none';
block.style.overflow = 'auto';
});
return;
}
// 新增代码结束
let codeBlocks = document.querySelectorAll(".highlight");
if (!codeBlocks || codeBlocks.length === 0) {
return;
}
codeBlocks.forEach(codeBlock => {
// 校验是否overflow
if (codeBlock.scrollHeight <= codeBlock.clientHeight) {
return;
}
// 保存初始位置
const originalPosition = codeBlock.getBoundingClientRect().top + window.pageYOffset;
// 创建 code-more-box
let codeMoreBox = document.createElement('div');
codeMoreBox.classList.add('code-more-box');
// 创建 code-more-btn
let codeMoreBtn = document.createElement('span');
codeMoreBtn.classList.add('code-more-btn');
// 创建 code-more-img
let moreImg = document.createElement('img');
moreImg.classList.add('code-more-img');
moreImg.src = {{ (resources.Get "icons/bottom.svg").Permalink }};
// 组装更多按钮
codeMoreBtn.appendChild(moreImg);
codeMoreBox.appendChild(codeMoreBtn);
codeBlock.appendChild(codeMoreBox);
// 点击更多按钮事件
codeMoreBox.addEventListener('click', function() {
// 隐藏更多按钮
codeMoreBox.style.display = 'none';
// 展开代码块
codeBlock.classList.add('code-show');
// 创建折叠按钮
let codeLessBox = document.createElement('div');
codeLessBox.classList.add('code-less-box');
let codeLessBtn = document.createElement('span');
codeLessBtn.classList.add('code-less-btn');
let lessImg = document.createElement('img');
lessImg.classList.add('code-less-img');
lessImg.src = {{ (resources.Get "icons/top-pre.svg").Permalink }};
// 组装折叠按钮
codeLessBtn.appendChild(lessImg);
codeLessBox.appendChild(codeLessBtn);
codeBlock.appendChild(codeLessBox);
// 点击折叠按钮事件
codeLessBox.addEventListener('click', function() {
// 移除折叠按钮
codeLessBox.remove();
// 隐藏展开状态
codeBlock.classList.remove('code-show');
// 显示更多按钮
codeMoreBox.style.display = 'block';
// 只在初始位置不在视口内时才滚动
scrollToInitialPositionIfNeeded(originalPosition, codeBlock);
// 触发resize事件
window.dispatchEvent(new Event('resize'));
});
// 触发resize事件
window.dispatchEvent(new Event('resize'));
});
});
}
function scrollToInitialPositionIfNeeded(originalPosition, codeBlock) {
// 获取当前视口信息
const viewportHeight = window.innerHeight;
const currentScroll = window.pageYOffset;
// 计算初始位置是否在视口内
const isOriginalPositionInViewport =
originalPosition >= currentScroll &&
originalPosition <= currentScroll + viewportHeight;
// 计算代码块当前是否在视口内
const codeBlockRect = codeBlock.getBoundingClientRect();
const isCodeBlockInViewport =
codeBlockRect.top >= 0 &&
codeBlockRect.top <= viewportHeight;
// 只有当初始位置不在视口内,且代码块也不在视口内时才滚动
if (!isOriginalPositionInViewport && !isCodeBlockInViewport) {
const header = document.querySelector('header');
let headerOffset = 0;
if (header) {
const headerHeight = window.getComputedStyle(header).getPropertyValue('height');
headerOffset = parseInt(headerHeight.replace('px', '')) || 0;
}
// 计算最终滚动位置(考虑header高度和一点边距)
const targetPosition = originalPosition - headerOffset - 20;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
console.log('触发滚动:初始位置不在视口内');
} else {
console.log('不触发滚动:初始位置或代码块在视口内');
}
}
// 初始化
document.addEventListener('DOMContentLoaded', function() {
initCodeMoreBox();
});
</script>用上述代码手机端会有不显示折叠展开功能相关按钮和样式的问题,用了比较极端的方法解决,即限制手机端禁用这个功能,改用限制代码块高度+滑动查看
/* 移动端禁用折叠,启用滚动并限制高度 */
@media (max-width: 768px) {
.highlight {
overflow: auto !important;
pre {
max-height: 17em !important;
&::-webkit-scrollbar {
display: flex;
}
}
}
.code-more-box,
.code-less-box {
display: none !important;
}
}此外如果自定义了鼠标光标样式,也要记得改,
我自定义鼠标光标样式的代码抄的莱特雷
由于添加的img属于.article-content这个类,要记得排除
// 【Stack主题鼠标样式写法】
// default光标图片
body,
html,
.article-content img:not(.code-less-img):not(.code-more-img), // 这里
.waline-container,
.wl-header label {
cursor: url(../mouse/default.png),
auto !important;
}
// pointer光标图片
a:hover,
button:hover,
.copyCodeButton:hover,
#dark-mode-toggle,
.wl-actions label,
.wl-actions a,
.wl-emoji-popup .wl-tab-wrapper button,
.wl-gif-popup img,
.wl-sort li,
.code-more-img, // 这里
.code-less-img { // 这里
cursor: url(../mouse/pointer.png),
auto !important;
}代码块显示标题
参考loyayz:Hugo 代码块显示标题
用ai改了一下,少创建一个类,自己写了css
{{- $lang := .Type | default "text" }}
{{- $title := .Attributes.title | default "" -}}
{{- if $title }}
<div class="highlight-with-title" data-title="{{ $title }}">
{{- end }}
{{ highlight .Inner $lang .Options }}
{{- if $title }}
</div>
{{- end }}// 代码块标题样式
.highlight-with-title {
position: relative;
margin: 1rem 0;
border-radius: 20px;
overflow: hidden;
}
.highlight-with-title .highlight {
padding-top: 4rem;
}
.highlight-with-title .copyCodeButton {
top: calc(var(--card-padding) + 1.5rem);
}
.highlight-with-title::before {
content: attr(data-title);
position: absolute;
left: 0;
right: 0;
color: var(--accent-color-text);
opacity: 0.5;
padding: 0 calc(2.5rem + 3em);
background-color: var(--accent-color);
font-size: 0.7em;
font-family: 'Fira code', 'mkty';
z-index: 1;
}```语法名 {title="标题内容"}
# code here其他样式更改
参照莱特雷的样式改了代码块圆角
// 代码块基础样式修改
.highlight {
max-width: 100% !important;
border-radius: 20px;
margin: 0 !important;
&:hover {
box-shadow: var(--shadow-l1) !important;
}
}禁用了滚动条
.article-content {
.highlight {
pre {
scrollbar-width: none;
/* Firefox */
&::-webkit-scrollbar {
display: none;
/* Chrome Safari */
}
}
}
}复制按钮圆角
// 代码块复制按钮
.article-content .copyCodeButton {
border-radius: 4px;
}一些代码块相关注意事项
行号不跟代码一起滚动的问题
做代码块折叠的话用不到,但如果希望限制代码块高度滚动查看代码的话,要想让行号跟着代码块一起滚动,记得改项目根目录\hugo.yaml(也可能是config.yaml 我记不清- -
markup:
highlight:
noClasses: false
codeFences: true
guessSyntax: true
lineNoStart: 1
lineNos: true
lineNumbersInTable: false
tabWidth: 4代码缩进长度不一致的问题
写博客的时候如果发现代码块里面缩进长度不一致的问题,可能是用了制表符Tab缩进导致的,解决办法:
- 在VS Code里把缩进改成使用空格缩进,把默认tab长度改成和
yaml文件里面写的tabWidth一致,我写的是4所以VS Code里我也改成4。这样改了之后按tab直接等于4个空格
VS Code里按 Ctrl+, 打开设置
搜索 "editor.insert spaces"
勾选 "Editor: Insert Spaces"
搜索 "editor.detect indentation"
勾选 "Editor: Detect Indentation"(自动检测)
或者设置 "Editor: Tab Size" 为 4
搜索 "editor.format on paste"
勾选 "Editor: Format On Paste"- 有时候遇到从别的文件粘贴过来的代码,粘贴到.md文件里还保留了制表符,需要全选并按Ctrl + K、Ctrl + F,可以把里面的制表符格式化成4个空格
- 注意你的.md文件里面所有缩进都得是4个空格(或者是你设置的其他数字)才能保持缩进长度一致,如果还是发现有不一致的问题就手动改一下