基本原理
- Hugo的stack主题提供了自定义样式的接口,主要在
layouts/partials/footer/custom.html和assets/scss/custom.scss中 - Hugo的文件可以实现文件覆盖。只要文件位置与
themes文件夹中的相同,就会先加载自定义文件。
页面布局
首页文章样式
在/assets/scss/custom.scss加入
1/*主页文章图片样式*/
2$image-scale: 1.2;
3.article-list article .article-image img {
4 width: 100%;
5 height: 150px;
6 object-fit: cover;
7 //不同显示器(手机,小屏幕电脑,大屏幕电脑)显示的图片高度大小
8 @include respond(sm) {
9 height: 305px;
10 }
11
12 @include respond(md) {
13 height: 305px;
14 }
15 @include respond(xl) {
16 height: 325px;
17 }
18}
19
20/*主页文章图片圆角*/
21.article-list article {
22 --card-border-radius: 24px;
23}
24
25/*文章标签圆角*/
26.article-category a, .article-tags a {
27 border-radius: 11px;
28}
29
30
31/*鼠标移动到文章图片放大*/
32.article-list article .article-image {
33 position: relative;
34 overflow: hidden; //不显示超出的部分
35}
36
37.article-list article .article-image img:hover {
38 transform: scale($image-scale); //放大尺寸
39}
40
41.article-list article .article-image img {
42 transition: transform 0.85s ease-in-out;//持续时间
43}
修改归档和友链界面
修改assets/scss/custom.scss文件,引入以下css样式代码:
1@media (min-width: 1024px) {
2 .article-list--compact {
3 display: grid;
4 // 目前是两列,如需三列,则后面再加一个1fr,以此类推
5 grid-template-columns: 1fr 1fr;
6 background: none;
7 box-shadow: none;
8 gap: 1rem;
9
10 article {
11 background: var(--card-background);
12 border: none;
13 box-shadow: var(--shadow-l2);
14 margin-bottom: 8px;
15 margin-right: 8px;
16 border-radius: 16px;
17 }
18 }
19}
代码块样式
代码块行标设置
在config.yaml中找到highlight部分:
1highlight:
2 noClasses: false
3 codeFences: true
4 guessSyntax: true
5 lineNoStart: 1
6 lineNos: true # 是否显示行号
7 lineNumbersInTable: false # 行号是否独立成列
8 tabWidth: 4
MacOS风格图标
- 准备一张macOS代码块的红绿灯图片放到
static/icons文件夹下,或者将以下代码写入code-header.svg文件中:
1<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="450px" height="130px">
2 <ellipse cx="65" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"/>
3 <ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"/>
4 <ellipse cx="385" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"/>
5</svg>
- 将以下代码复制进
assets/scss/custom.scss文件中。
1.highlight {
2 border-radius: var(--card-border-radius);
3 max-width: 100% !important;
4 margin: 0 !important;
5 box-shadow: var(--shadow-l1) !important;
6}
7
8.highlight:before {
9 content: "";
10 display: block;
11 // 这里填图片地址
12 background: url(../icons/macOS-code-header.svg) no-repeat 0;
13 background-size: contain;
14 height: 18px;
15 margin-top: -10px;
16 margin-bottom: 10px;
17}
复制不显示行号
在assets/ts/main.ts中找到copyButton项,修改为以下内容:
1copyButton.addEventListener('click', () => {
2 // 创建一个临时容器来克隆代码块的内容
3 const tempCodeBlock = codeBlock.cloneNode(true) as HTMLElement;
4
5 // 删除行号,行号的元素是 <span class="ln">
6 const lineNumbers = tempCodeBlock.querySelectorAll('.ln');
7 lineNumbers.forEach(lineNumber => lineNumber.remove());
8
9 // 获取没有行号的纯文本内容
10 const codeText = tempCodeBlock.textContent;
11
12 navigator.clipboard.writeText(codeText || '')
13 // navigator.clipboard.writeText(codeBlock.textContent)
14 .then(() => {
15 copyButton.textContent = copiedText;
16
17 setTimeout(() => {
18 copyButton.textContent = copyText;
19 }, 1000);
20 })
21 .catch(err => {
22 alert(err)
23 console.log('Something went wrong', err);
24 });
25});
可视化加载条
-
下载【文件 】,并将压缩包中的
topbar.min.js移动至assets/js中。 -
在
layouts/partials/footer/custom中加入以下代码:
1{{ with resources.Get "js/topbar.min.js" }}
2 <!-- 引入本地JS脚本 -->
3 <script src={{ .Permalink }}></script>
4{{ end }}
5<script>
6 // 修改进度条颜色
7 topbar.config({
8 barColors: {
9 '0': 'rgba(255, 255, 255, 1)', // 进度0%白色
10 '1.0': 'rgba(0, 149, 234, 1)' // 进度100%蓝色
11 }
12 })
13
14 document.addEventListener('pjax:send', () => {
15 // 显示顶部进度条
16 topbar.show();
17 })
18
19 document.addEventListener('pjax:complete', () => {
20 // 隐藏顶部进度条
21 topbar.hide();
22 })
23</script>
网页组件
若想在网页中加入自定义内容,一种方法是在模版中写入.html源码;另一种方法是将代码封装成组件(widget),再以链接的方式引入模板中。
后者可以方便地实现代码复用,对原模版的改动也最小。实际上,每个组件本质上就是一个网页文件(.html),然后放入模版文件中即可实现在网页上加载。
以下提供了几个示例,供您参考。
首页欢迎栏
- 在
/layouts/partial/widget/中新建文件welcome-bar.html,写入以下内容:
1<!-- 首页欢迎字幅 -->
2<div class="welcome">
3 <p style="font-size: 2rem; text-align: center; font-weight: bold">
4 <span class="shake">👋</span>
5 <span class="jump-text1" > Welcome</span>
6 <span class="jump-text2"> To </span>
7 <span class="jump-text3" style="color:#e99312">Wei Qi</span>
8 <span class="jump-text9" style="color:#e99312">Blog</span>
9 </p>
10</div>
11<!-- 首页欢迎字幅 -->
- 在
/assets/scss/custom.scss里加入:
1//首页欢迎板块样式
2.welcome {
3 color: var(--card-text-color-main);
4 background: var(--card-background);
5 box-shadow: var(--shadow-l2);
6 border-radius: 30px;
7 display: inline-block;
8}
9
10// 👋emoji实现摆动效果
11.shake {
12 display: inline-block;
13 animation: shake 1s;
14 animation-duration: 1s;
15 animation-timing-function: ease;
16 animation-delay: 0s;
17 animation-iteration-count: 1;
18 animation-direction: normal;
19 animation-fill-mode: none;
20 animation-play-state: running;
21 animation-name: shake;
22 animation-timeline: auto;
23 animation-range-start: normal;
24 animation-range-end: normal;
25 animation-delay: 2s;
26 @keyframes shake {
27 0% {
28 transform: rotate(0);
29 }
30 25% {
31 transform: rotate(45deg) scale(1.2);
32 }
33 50% {
34 transform: rotate(0) scale(1.2);
35 }
36 75% {
37 transform: rotate(45deg) scale(1.2);
38 }
39 100% {
40 transform: rotate(0);
41 }
42 }
43}
44
45// 实现字符跳动动画
46.jump-text1 {
47 display: inline-block;
48 animation: jump 0.5s 1;
49}
50.jump-text2 {
51 display: inline-block;
52 animation: jump 0.5s 1;
53 animation-delay: 0.1s;
54}
55.jump-text3 {
56 display: inline-block;
57 animation: jump 0.5s 1;
58 animation-delay: 0.2s;
59}
60.jump-text9 {
61 display: inline-block;
62 animation: jump 0.5s 1;
63 animation-delay: 0.9s;
64}
65
66@keyframes jump {
67 0% {
68 transform: translateY(0);
69 }
70 50% {
71 transform: translateY(-20px);
72 }
73 100% {
74 transform: translateY(0);
75 }
76}
实际上,这些
css代码也可以直接写在welcome-bar.html的<style></style>标签中,在以下组件中同理。
随机文字卡片
随机效果
随机效果依赖javascript脚本:
1// 获取并展示文字内容
2function showQuotes() {
3 // 随机文字
4 index = Math.floor(Math.random() * quotes.length);
5 const quote = quotes[index];
6
7 // 获取文字和作者信息
8 const textElement = document.querySelector(".quote-text");
9 const authorElement = document.querySelector(".quote-author");
10
11 textElement.innerText = quote.quote;
12 authorElement.innerText = `—— ${quote.author}`;
13
14 // 渲染数学公式(可选)
15 renderMathInElement(textElement, {
16 delimiters: [
17 {left: '$$', right: '$$', display: true},
18 {left: '$', right: '$', display: false},
19 {left: '\\[', right: '\\]', display: true},
20 {left: '\\(', right: '\\)', display: false}
21 ]
22 });
23};
完善实现事件还需要增加一个按钮,实现点击就能随机显示文字。
1<button id="new-quote">Random</button>
然后赋予其点击事件:
1<script>
2 document.querySelector("#new-quote").addEventListener("click", showQuotes);
3</script>
设置配置文件
如果将文字内容写在.html文件内部,可配置性不佳,而且会使代码臃肿。因此,可以将随机文字的内容写入json文件并放入static/文件夹中。
为什么放入
static文件夹?
static文件夹存放网页的静态内容,通俗点就是其中的内容就在站点目录之下。例如站点名为https://www.example.com,那么static/quotes.json就在https://www.example.com/quote.json处,在寻找时可以直接输入/quotes.json。
密码栏
在网页中显示组件
主页显示
在index.html中加入:
1<section class="article-list">
2 ...
3 {{ partial "widget/你的组件名.html" . }}
4 ...
5</section>
侧边栏
1page:
2 - type: toc
3 - type: 你的组件名