2025-06-27 23:43:00

黑夜模式适配

!important覆盖项与 [BlogRoot]\node_modules\hexo-theme\butterfly\source\css\_mode\darkmode.styl 中相对应即可修改对应的颜色。

比如把卡片的背景色改浅一点,在 custom.css 中加入:

1
2
3
[data-theme='dark'] {
--card-bg: #1e1e20 !important;
}

偷懒.jpg

黑夜模式下部分深色社交图标和黑色背景完全融为一体了,所以覆写css单独为部分图标更换为浅色系以增加可读性:

1
2
3
4
5
6
7
8
9
10
11
[data-theme='dark'] {
/* X图标颜色适配 */
.fa-brands.fa-x-twitter {
color: #fff !important;
}

/* Github图标颜色适配 */
.fab.fa-github {
color: #bcbcbc !important;
}
}

别的深色图标也是同理,这样一来黑夜模式下右侧社交图标依然保持清晰可见。

按钮背景色,修改 darkmode.styl

1
--btn-bg: lighten(#262626, 5)

新样式下分类磁贴颜色区分度变得不足,重新适配两个配色方案:

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
/* magnet分类磁贴浅色模式适配 */
/* 浅色模式一般状态 */
.magnet_link_context {
background: #ededed;
border-radius: 7px;
}
/* 浅色模式鼠标悬浮状态 */
.magnet_link_context:hover {
background: #ff7242;
border-radius: 7px;
}

/* magnet分类磁贴黑夜模式适配 */
/* 黑夜模式一般状态 */
[data-theme="dark"] .magnet_link_context {
background: #282828;
color: antiquewhite;
border-radius: 7px;
}
/* 黑夜模式鼠标悬浮状态 */
[data-theme="dark"] .magnet_link_context:hover {
/* background: #3ecdf1; */
background: darkviolet;
color: #f2f2f2;
border-radius: 7px;
}

组件背景半透明样式

对于每个单独的近期文章卡片用 #recent-posts > .recent-post-items > .recent-post-item{} 才能获取,因为主题给外面还套了一层div,单独 #recent-posts > .recent-post-items{} 设定的是外面那层,因此这样指定只会对首页 recent-post-items 中所挂载的分类磁贴生效。

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
:root {
--trans-light: rgba(255, 255, 255, 0.88);
/* --trans-dark: rgba(25, 25, 25, 0.88); */
--trans-dark: rgba(31, 31, 31, 0.88);
--border-style: 1px solid rgb(169, 169, 169);
/* --backdrop-filter: blur(5px) saturate(150%); */
--backdrop-filter: none;
}

/* 首页文章卡片 */
#recent-posts > .recent-post-item {
background: var(--trans-light);
backdrop-filter: var(--backdrop-filter);
/* border-radius: 25px; */
border: var(--border-style);
}
#recent-posts > .recent-post-items > .recent-post-item {
background: var(--trans-light);
backdrop-filter: var(--backdrop-filter);
/* border-radius: 25px; */
border: var(--border-style);
}

/* 首页侧栏卡片 */
#aside-content .card-widget {
background: var(--trans-light);
backdrop-filter: var(--backdrop-filter);
/* border-radius: 18px; */
border: var(--border-style);
}

/* 文章页、归档页、普通页面 */
div#post {
background: rgba(255, 255, 255, 0.94)
}
[data-theme="dark"] div#post {
background: rgba(31, 31, 31, 0.94)
}

/* div#post, */
div#page,
div#archive {
background: var(--trans-light);
backdrop-filter: var(--backdrop-filter);
border: var(--border-style);
/* border-radius: 20px; */
}

/* 导航栏 */
#page-header.nav-fixed #nav {
background: rgba(255, 255, 255, 0.75);
backdrop-filter: var(--backdrop-filter);
}

[data-theme="dark"] #page-header.nav-fixed #nav {
background: rgba(0, 0, 0, 0.7) !important;
}

/* 夜间模式遮罩 */
[data-theme="dark"] #recent-posts > .recent-post-item,
[data-theme="dark"] #aside-content .card-widget,
[data-theme="dark"] div#post,
[data-theme="dark"] div#archive,
[data-theme="dark"] div#page {
background: var(--trans-dark);
}

/* 夜间模式页脚页头遮罩透明 */
/* 直接选择class太过粗暴 已被废弃 */
/*[data-theme="dark"] #footer::before {
background: transparent !important;
}
[data-theme="dark"] #page-header::before {
background: transparent !important;
}*/

阅读模式配色调整

对于阅读模式,浅色模式借鉴Typora的Newsprint背景色,黑夜模式避免颜色过深并保证文章各种内容的可读性。调整后阅读模式下各种背景色RGB各通道的差值不超过15,保留区分度并保持简洁的配色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 浅色模式下的阅读模式 */
.read-mode #aside-content .card-widget {
background: rgba(242, 232, 238, 1) !important;
}
.read-mode div#post {
background: rgba(242 ,242, 238, 1) !important;
}

/* 夜间模式下的阅读模式 */
[data-theme="dark"] .read-mode #aside-content .card-widget {
background: rgba(34, 34, 32, 0.9) !important;
color: #b8bfc6;
}
[data-theme="dark"] .read-mode div#post {
background: rgba(34, 34, 32, 0.9) !important;
color: #b8bfc6;
}

去除侧栏红皮喇叭的抖动效果

早就看右边公告卡片的红色小喇叭不爽了,一直抖个不停 ,找了半天也没发现有右侧卡片的配置项,这回直接去主题源文件里逮你  ̄へ ̄

F12定位到该图标,得到图标名为fa-bullhorn,全局搜索定位到该图标在 [BlogRoot]\node_modules\hexo-theme-butterfly\layout\includes\widget\card_announcement.pug 中,显然去掉其内置图标动画后缀即可,将 i.fas.fa-bullhorn.fa-shake 更换为不带抖动效果的fa图标:

1
2
- i.fas.fa-bullhorn.fa-shake
+ i.fas.fa-bullhorn

版权标位置移动至底部

©2025 - xxxx By 0x9c5 这一标识放到footer-wrap容器的底部,看起来更自然,不会挤在一起。

1
2
3
4
5
6
7
/* 版权标位置移至底部 */
.copyright{
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, -50%);
}

文章底部版权块背景色

1
2
3
4
5
/* 底部版权背景色 */
.post-copyright{
/* background: linear-gradient(45deg, #f6d8f5, #c2f1f0, #f0debf); */
background: #f3f4f4;
}

“优化”文章页面侧栏toc右上角的百分比

省流:scroll_percent: false

顺藤摸瓜

在测试文章页面的时候早就注意到,目录右上角的阅读百分比感觉对不上,F12看了下,即使滑到底部这个阅读进度甚至都到不了100。

于是我开始翻主题文件看看这玩意的js逻辑是怎么写的。

首先在页面上定位这个元素 class="toc-percentage",其在 main.js 中被选择:

1
$tocPercentage = $cardTocLayout.querySelector('.toc-percentage')

然后在 main.js 中,找到tocPercentage所包裹的文字内容(即进度百分比数字)是被一个叫 getScrollPercent() 的函数计算出来的:

1
2
3
if (isToc && GLOBAL_CONFIG.percent.toc) {
$tocPercentage.textContent = btf.getScrollPercent(currentTop, $article)
}

于是定位至该函数在 utils.js 中,是一个自调用函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
getScrollPercent: (() => {
let docHeight, winHeight, headerHeight, contentMath

return (currentTop, ele) => {
if (!docHeight || ele.clientHeight !== docHeight) {
docHeight = ele.clientHeight
winHeight = window.innerHeight
headerHeight = ele.offsetTop
contentMath = Math.max(docHeight - winHeight, document.documentElement.scrollHeight - winHeight)
}

const scrollPercent = (currentTop - headerHeight) / contentMath
return Math.max(0, Math.min(100, Math.round(scrollPercent * 100)))
}
})(),

函数浅析

其中传入一个double型和一个element,输出一个数字 (currentTop: any, ele: any) => number

其中传入的第一个参数currentTop看名字也能略知一二,在调用时作为声明的局部变量被设为 const currentTop = window.scrollY || document.documentElement.scrollTop,一个双精度浮点值,查了下文档,没理解错的话,左半获取当前viewport上边缘的Y坐标,右半是获取当前页面的滚动条Y坐标,其中哪个能被转换为true则返回它自身。

第二个参数ele显然传入一个元素,调用时传入的是 $article,被设为 const $article = document.getElementById('article-container') ,然后F12看到article#article-container.container.post-content 包含了整个文章本体,确实是需要被计算阅读进度的部分。

其逻辑大致呈这样:

{picture(byd我图呢?)}

嘛……感觉这个计算逻辑貌似并没有 没能找出 什么问题,在我浏览其它基于butterfly的博客文章页面这个toc百分比几乎都是正常工作的,于是去官方文档看看有没有人提过相关的issue什么的…… 前人栽树,后人乘凉 ,结果除了翻出2020/08/31远古时期v3.1.0的更新日志中Fix部分有一条“修復toc滾動百分比不準的Bugs”外,没找到什么有用的信息。

欧亨利式结尾

可惜我也不是来考古的,但离开之际,察觉到一股微妙的不对劲,再定睛一看,怎么Jerry自己的文章页tocPercentage显示也对不上啊喂wwww

我释怀地似了

与其说是似了,更多是某种连解决自己页面上侧栏的一个阅读进度显示问题都举步维艰,有如初入新手村被路边初始小怪一脚踢死的无力感。

最后默默地在配置文件中关掉了scroll_percent显示,毕竟怎么说这个阅读进度百分比也算不上什么必须的信息。

卒。

更改footer遮罩

复制了一些调整页面样式的css之后发现有好多行代码都对 #footer 动手动脚的,都冲突了已经,这个部分在我 CV工程 的疏忽之下被n行 !important 来回拳打脚踢,样式惨不忍睹,故将这些页脚相关的代码全注释掉了,重置一个简单的页脚遮罩:

1
2
3
4
5
6
7
8
/* 页脚只保留半透遮罩 */
#footer {
background: rgba(224, 224, 224, 0.4);
}
/* 夜间模式页脚半透遮罩 */
[data-theme="dark"] #footer {
background: rgba(31, 31, 31, 0.5)
}

2025-07-01 22:30:00

信息卡片头像状态

修改 node_modules\hexo-theme-butterfly\layout\includes\widget\card_author.pug

1
2
3
4
5
6
7
8
9
10
11
if theme.aside.card_author.enable
.card-widget.card-info.text-center
- .avatar-img
- img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
+ div.card-info-avatar
+ .avatar-img
+ img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
+ div.author-status-box
+ div.author-status
+ g-emoji.g-emoji(alias="palm_tree" fallback-src="https://lskypro.acozycotage.net/LightPicture/2022/12/fe1dc0402e623096.jpg") 🐟
+ span 认真摸鱼中

注:fallback-src为备用链接,当有设备不支持该emoji时加载链接指向的图像。

custom.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
.card-info-avatar .author-status-box {
position: absolute;
bottom: 0;
left: calc(100% - 28px);
width: 28px;
height: 28px;
border: 1px solid #d0d7de;
border-radius: 2em;
background-color: #f8f8f8bb;
transition: 0.4s;
overflow: hidden;
}

[data-theme="dark"] .card-info-avatar .author-status-box {
background-color: #222222f2;
border: 1px solid #5c6060;
}

.card-info-avatar .author-status-box .author-status {
display: flex;
align-items: center;
justify-content: center;
height: 28px;
padding: 0 5px;
}

.card-info-avatar .author-status-box:hover {
width: 105px;
}

.card-info-avatar .author-status-box:hover .author-status span {
width: 105px;
margin-left: 4px;
}

.card-info-avatar .author-status-box .author-status span {
width: 0;
font-size: 12px;
height: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
transition: 0.4s;
}

.card-widget .card-info-avatar {
display: inline-block;
position: relative;
}

头像框呼吸灯

custom.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
/* 信息卡片头像呼吸灯 */
[data-theme="light"] .avatar-img {
animation: avatar_breathing_light 4s ease-in-out infinite;
}
[data-theme="dark"] .avatar-img {
animation: avatar_breathing_dark 4s ease-in-out infinite;
}
@keyframes avatar_breathing_light {
0% {
box-shadow: 0px 0px 1px 1px #ffdddd;
}
50% {
box-shadow: 0px 0px 5px 5px #ffdddd;
}
100% {
box-shadow: 0px 0px 1px 1px #ffdddd;
}
}
@keyframes avatar_breathing_dark {
0% {
box-shadow: 0px 0px 1px 1px #006e6e;
}
50% {
box-shadow: 0px 0px 5px 5px #006e6e;
}
100% {
box-shadow: 0px 0px 1px 1px #006e6e;
}
}

2025-07-02 12:30:00

搞耍标题

新建 \js\dynamicTitle.js ,在其中写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//动态标题
var OriginTitile = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
//离开当前页面时标签显示内容
document.title = '( ˘・з・) 跑哪去了呀~';
clearTimeout(titleTime);
} else {
//返回当前页面时标签显示内容
document.title = '٩(๑> ₃ <)۶ 欢迎回来~';
//两秒后变回正常标题
titleTime = setTimeout(function () {
document.title = OriginTitile;
}, 2000);
}
});

弄好后使用Minify JS Online对文件进行压缩,可读性下降0.01%,体积压缩 41.27%,竟然节省了高达215 bytes的体积 蚊子腿也是肉

小改导航栏

就是hover时变成小房子按钮,好像并没有什么卵用呢… ( º﹃º )

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
/* 导航栏标题增强 */
.nav-site-title .site-name::before {
opacity: 0;
background-color: #49b1f5 !important;
border-radius: 8px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
-ms-border-radius: 8px;
-o-border-radius: 8px;
transition: 0.3s;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-ms-transition: 0.3s;
-o-transition: 0.3s;
position: absolute;
top: 0 !important;
right: 0 !important;
width: 100%;
height: 100%;
content: "\f015";
box-shadow: 0 0 5px var(--theme-color);
font-family: "Font Awesome 6 Free";
text-align: center;
color: white;
line-height: 34px; /*如果有溢出或者垂直不居中的现象微调一下这个参数*/
font-size: 18px; /*根据个人喜好*/
}
.nav-site-title .site-name:hover::before {
opacity: 1;
scale: 1.03;
}
.nav-site-title .site-name {
position: relative;
font-size: 24px;
}

2025-07-03 07:30:00