前言

美化的时候需要修改网站的源文件、添加样式、js之类的,需要一点基础,可以参考

常用标签外挂效果

提示

个人博客下面的效果使用频率较高,还有一个引用链接的标签外挂,放在分栏里面会有 bug,不能正常显示,可以直接看博客的实例效果。

对了,我说的常用标签外挂效果是包括这个分栏的,分栏的代码也在示例源码里面。

这是一个折叠框

这是一个默认关闭的折叠框。

default标签

default 提示块标签

primary标签

primary 提示块标签

success标签

success 提示块标签

info标签

info 提示块标签

warning标签

warning 提示块标签

danger标签

danger 提示块标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{% tabs tab1 %}
<!-- tab 演示预览 -->

{% folding cyan, 这是一个折叠框 %}

这是一个默认关闭的折叠框。

{% endfolding %}

{% note default default标签 %}default 提示块标签{% endnote %}

{% note primary primary标签 %}primary 提示块标签{% endnote %}

{% note success success标签 %}success 提示块标签{% endnote %}

{% note info info标签 %}info 提示块标签{% endnote %}

{% note warning warning标签 %}warning 提示块标签{% endnote %}

{% note danger danger标签 %}danger 提示块标签{% endnote %}


<!-- endtab -->

<!-- tab 示例源码 -->
......(这里就是复制源码的,再写就套娃了)
<!-- endtab -->

{% endtabs %}

参考链接

基础标签外挂

在博客根目录 [blogRoot] 打开 git bash,运行以下指令

1
npm install hexo-butterfly-tag-plugins-plus --save

考虑到 hexo 自带的 markdown 渲染插件 hexo-renderer-marked 与标签外挂语法的兼容性较差,建议您将其替换成 hexo-renderer-kramed
1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

添加配置信息,以下为写法示例
在站点配置文件 _config.yml 或者主题配置文件 _config.butterfly.yml 中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# tag-plugins-plus
# see https://akilar.top/posts/615e2dec/
tag_plugins:
enable: true # 开关
priority: 5 #过滤器优先权
issues: false #issues标签依赖注入开关
link:
placeholder: /img/link.png #link_card标签默认的图标图片
CDN:
anima: https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css #动画标签anima的依赖
jquery: https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js #issues标签依赖
issues: https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/issues.js #issues标签依赖
iconfont: //at.alicdn.com/t/font_2032782_8d5kxvn09md.js #参看https://akilar.top/posts/d2ebecef/
carousel: https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js
tag_plugins_css: https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css

具体参数意义可看参考链接的第一项里面的内容。

直接在 markdown 文件里面使用即可,大部分会类似于 { % 函数名 参数A1 参数A2,参数B... % } 的形式,再不然就是 { % 函数名 参数A1 参数A2,参数B... % }一堆文字{ % end+函数名 % } 的形式(这里百分号和大括号之间空格,防止渲染问题,正常是不需要的)。

具体使用方法详见参考链接的第一项。

原样式,尤其是分栏框的样式着实惨不忍睹,于是要进行美化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*折叠框美化*/
details[open] > div.content {
background: var(--theme-color-green) !important;
border-radius: 10px;
border-top-right-radius: 0px !important;
border-top-left-radius: 0px !important
}
details.folding-tag summary {
border-radius: 10px !important;
}
details.folding-tag {
border-radius: 10px !important;
border: 1px solid rgba(27, 205, 252, 0.3) !important;
}
details.folding-tag[open] summary {
border-bottom-right-radius: 0px !important;
border-bottom-left-radius: 0px !important
}

details.folding-tag[cyan] > summary {
background: var(--button-dark-color) !important;
color: var(--text-color) !important;
}
/*因为cyan的配色与本站样式相符,因此着重美化了cyan的样式,其他的可以类似进行修改*/
[data-theme="dark"] details.folding-tag[cyan] > summary::marker {
color: #0F7D7F;
}
[data-theme="dark"] details.folding-tag[cyan] > summary:hover::marker,
[data-theme="dark"] details.folding-tag[open][cyan] > summary::marker {
color: #00C4B6;
}
[data-theme="light"] details.folding-tag[cyan] > summary::marker {
color: #2E4964;
}
[data-theme="light"] details.folding-tag[cyan] > summary:hover::marker,
[data-theme="light"] details.folding-tag[open][cyan] > summary::marker {
color: #446484;
}
details.folding-tag[cyan] > summary:hover {
background: var(--button-light-color) !important;
color: var(--text-color) !important;
}
details.folding-tag[open][cyan] > summary {
background: var(--button-light-color) !important;
}
[data-theme="dark"] details[cyan] > summary {
filter: brightness(1) !important;
}
#article-container .tabs {
border-radius: 12px;
overflow: hidden;
padding: 8px;
background: var(--theme-color-green);
border: 2.5px solid var(--border-color) !important;
margin: 1rem 0px !important;
}

/*分栏美化*/
#article-container .tabs > .nav-tabs > .tab.active {
border-top: transparent;
background: var(--button-light-color);
border: transparent;
}
#article-container .tabs > .nav-tabs > .tab:not(.active) {
background: var(--button-dark-color);
border: transparent;
}
#article-container .tabs > .nav-tabs > .tab:not(.active):hover {
background: var(--button-light-color);
border: transparent;
}
#article-container .tabs > .nav-tabs {
display: flex;
background: var(--theme-color-green);
padding: 12px 16px;
justify-content: center;
}
#article-container .tabs > .nav-tabs > .tab {
flex: 1;
padding: 8px 18px;
margin: 0 8px;
border-radius: 8px;
transition: all 0.4s;
}

这个玩意还有一堆奇奇怪怪的 bug,尤其是分栏。

  • 分栏不能用下文的引用外链的样式
  • 分栏非默认的一栏不能正确处理代码块的折叠问题(超过限定行数不折叠)

对于第一个问题暂时不知道怎么处理,有佬会的可以在评论区给出解决方案,欢迎讨论。

对于第二个问题,我的方案是加入如下的 js 代码(引入的时候需要加上 data-pjax)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/***切换分栏重新判断代码是否需要折叠 */
document.addEventListener('pjax:complete', initTabCodeFold);
document.addEventListener('DOMContentLoaded', initTabCodeFold);
// 监听Pjax完成跳转后重新初始化(关键修复点)
document.addEventListener('pjax:complete', initTabCodeFold);

function initTabCodeFold() {
// 挂载重建方法
window.rebuildCodeHighlight = function () {
if (!window.refreshFn) return;
// 全局清空旧按钮,防止堆叠边框
document.querySelectorAll('figure.highlight').forEach(fig => {
fig.querySelector('.highlight-tools')?.remove()
fig.querySelector('.code-expand-btn')?.remove()
})
window.refreshFn()
}

document.querySelectorAll('.tab').forEach(btn => {
// 先移除旧监听,防止多次绑定堆积
btn.removeEventListener('click', handleTabClick)
btn.addEventListener('click', handleTabClick)
})
}

// 抽离点击处理函数,避免重复绑定
function handleTabClick() {
setTimeout(window.rebuildCodeHighlight, 220)
}

引用外链卡片

提示

引用外链卡片有一些 bug,在使用的时候最好上下空一行,然后如果需要引号最好用中文的引号,否则可能会出现渲染错误。

使用方法类似于

1
2
3
{% link 百度一下,你就知道,百度,https://www.baidu.com/ %}

{% link sxr1023’s Blog,一路寒风身如絮,命海沉浮客独行,http://sxr.wsq127.top/ %}

新建文件 [blogRoot]/themes/butterfly/scripts/tag/link.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function link(args) {
args = args.join(' ').split(',');
let title = args[0];
let sitename = args[1];
let link = args[2];

// 获取网页favicon
let urlNoProtocol = link.replace(/^https?\:\/\//i, "");
let imgUrl = "https://icon.bqb.cool/?url=" + urlNoProtocol;
return `<a class="tag-Link" target="_blank" href="${link}">
<div class="tag-link-tips">🔗 引用站外地址,请注意甄别</div>
<div class="tag-link-bottom">
<div class="tag-link-left" style="background-image: url(${imgUrl});"></div>
<div class="tag-link-right">
<div class="tag-link-title">${title}</div>
<div class="tag-link-sitename">${sitename}</div>
</div>
<i class="fa-solid fa-angle-right"></i>
</div>
</a>`
}

hexo.extend.tag.register('link',link, { ends: false })

// 新增站内链接标签函数
function innerlink(args) {
args = args.join(' ').split(',');
let title = args[0];
let sitename = args[1];
let link = args[2];

// 获取网页favicon
let urlNoProtocol = link.replace(/^https?\:\/\//i, "");
let imgUrl = "https://cdn.jsdmirror.com/gh/sxr1023/BlogImage/img/avatar2.webp";
return `<a class="tag-Link" target="_blank" href="${link}">
<div class="tag-link-tips">🏠 站内链接,放心访问</div>
<div class="tag-link-bottom">
<div class="tag-link-left" style="background-image: url(${imgUrl});"></div>
<div class="tag-link-right">
<div class="tag-link-title">${title}</div>
<div class="tag-link-sitename">${sitename}</div>
</div>
<i class="fa-solid fa-angle-right"></i>
</div>
</a>`
}
hexo.extend.tag.register('innerlink', innerlink, { ends: false })

新增 tag-link.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@charset  "UTF-8";

:root{
--sxr-white: #fff;
--sxr-gray: #999999;
--sxr-main: var(--sxr-theme);
--style-border: 1px solid var(--sxr-card-border);
--style-border-hover: 1px solid var(--sxr-main);

--sxr-theme: #425AEF;
--sxr-card-border: #e3e8f7;
--sxr-secondbg: #f1f3f8;
}

::selection {
background: var(--sxr-fontcolor);
color: var(--sxr-background);
}

[data-theme=light] {
--sxr-theme: #425AEF;
--sxr-card-border: #e3e8f7;
--sxr-secondbg: #f1f3f8;
--sxr-fontcolor: #363636;
--sxr-background: #f7f9fe;
}

[data-theme=dark] {
--sxr-theme: #0084FF;
--sxr-card-border: #336a71;
--sxr-secondbg: #30343f;
--sxr-fontcolor: #F7F7FA;
--sxr-background: #18171d;
}

@media screen and (max-width: 768px){
:root{
--style-border: 0px solid var(--sxr-card-border);
--style-border-hover: 0px solid var(--sxr-main);
}
}

#article-container .tag-Link {
background: var(--sxr-secondbg);
border-radius: 8px!important;
display: flex;
border: var(--style-border);
flex-direction: column;
padding: 0.5rem 1rem;
border-width: 1px!important;
margin-top: 1rem;
}

#article-container .tag-Link:hover {
border: var(--style-border-hover);
}

#article-container .tag-Link .tag-link-tips {
border-bottom: var(--style-border);
padding-bottom: 4px;
font-size: 0.6rem;
color: var(--sxr-gray);
font-weight: normal;
}

#article-container .tag-Link:hover .tag-link-tips {
color: var(--sxr-white);
}

#article-container .tag-Link .tag-link-bottom {
display: flex;
margin-top: 0.5rem;
align-items: center;
justify-content: space-around;
}

#article-container .tag-Link .tag-link-bottom .tag-link-left {
width: 60px;
min-width: 60px;
height: 60px;
background-size: cover;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right {
margin-left: 1rem;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right .tag-link-title {
font-size: 1rem;
line-height: 1.2;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right .tag-link-sitename {
font-size: 0.7rem;
color: var(--sxr-gray);
font-weight: normal;
margin-top: 4px;
}

#article-container .tag-Link:hover .tag-link-bottom .tag-link-right .tag-link-sitename {
color: var(--sxr-white);
}

#article-container .tag-Link .tag-link-bottom i {
margin-left: auto;
}

/*上面的洪佬的原生样式,下面的是我根据自诩需要进行额外添加的样式*/
.tag-Link {
background: var(--theme-color2) !important;
border: 2px solid var(--theme-color) !important;
}
[data-theme="light"] .tag-Link:hover {
background: oklch(from var(--theme-color2) calc(l * 0.9) c h) !important;
box-shadow: 0 0 15px var(--theme-color);
}
[data-theme="dark"] .tag-Link:hover {
background: oklch(from var(--theme-color2) calc(l * 1.2) c h) !important;
box-shadow: 0 0 15px var(--theme-color);
}

note效果美化

原生的效果我觉得不太符合预期,于是从网上找了找方案进行美化。

修改[blogRoot]\themes\Butterfly\scripts\tag\note.js

记得需自行去阿里巴巴矢量图标库添加图标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'use strict'

function postNote(args, content) {
const typeIcons = {
info: 'iconfont icon-info',
primary: 'iconfont icon-plus',
default: 'iconfont icon-right',
warning: 'fa-regular fa-circle-dot',
danger: 'fa-regular fa-circle-xmark',
success: 'fa-regular fa-circle-check'
}
const noteType = args[0] || 'note'
const remainingArgs = args.slice(1)
let [title, ...styleArgs] = remainingArgs[0]?.startsWith('fa-')
? ['', ...remainingArgs]
: [remainingArgs[0], ...remainingArgs.slice(1)]

return `<div class="note note-${noteType} ${styleArgs.join(' ')}">
<div class="note-header">
<i class="note-icon ${typeIcons[noteType]}"></i>
${title ? `<span class="note-title">${title}</span>` : ''}
</div>
<div class="note-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div>
</div>`
}

hexo.extend.tag.register('note', postNote, {ends: true})
hexo.extend.tag.register('subnote', postNote, {ends: true})

新增 note.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*这部分是在对图标进行操作*/
.iconfont {
font-family: "iconfont" !important;
font-size: 1em;
/* 可以定义图标大小 */
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}

/* note标签外挂 */
.note {
--note-color: #5bc0de;
--gradient-position: 4em -23em;
--gradient-size: 30em;

border-radius: 12px;
border: 1px solid transparent;
position: relative;
margin: 0 0 20px;
padding-left: 15px !important;
background-color: var(--june-card-bg);
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
transition: all .3s ease;
}

.note[class*="note-"] {
background-image:
radial-gradient(circle at var(--gradient-position), var(--note-color), transparent var(--gradient-size)),
linear-gradient(var(--note-color) -1000%, transparent);
}

.note:hover {
border-color: var(--note-color);
}

.note.note-warning { --note-color: #f0ad4e; }
.note.note-success { --note-color: #5cb85c; }
.note.note-danger { --note-color: #d9534f; }
.note.note-info { --note-color: #5bc0de; }
.note.note-primary { --note-color: #6f42c1; }
.note.note-default { --note-color: #777; }

.note .note-header {
display: flex;
align-items: center;
font-weight: 700;
margin-bottom: 10px;
font-size: 1em;
color: var(--note-color);
}

.note .note-header i.note-icon {
margin-right: 10px;
color: inherit;
}

.note .note-content p {
margin: 0 !important;
}