Butterfly魔改合集
修改记录
2022-06-27
- 升级butterfly至4.3.1,并重新进行内部结构调整
2022-06-28
- 新增Gitcalendar
2022-07-31
- 将Twikoo换成Waline评论插件
2022-08-02
- 引入菜单栏、社交栏多色图标
2022-08-04
- 首页文章卡片修改
- 使用
gulp压缩博客静态资源 - 删除SAO-UI-PLAN–Card-Player
- 删除SAO-UI-PLAN-Card-Widget
- 停用随机背景或banner效果
- 启用渐变星空Sky粒子背景特效
2022-08-06
- 优化本帖布局
- 重新启用Twikoo评论并关闭Waline
- 美化Twikoo评论卡片
- 停用首页卡片Wosjs动画
2022-08-06
- 信笺样式留言板
本站部分文章转载自Akilarの糖果屋,如有侵权,请联系作者,本站仅当学习使用!
写在前面-CSS整合
为了追求视觉体验,不要给index.css等涉及首页样式的CSS文件添加异步加载。然而事实上,相比于给css添加异步加载,不如将我们的魔改样式整合到index.css文件内,减少对服务器的请求次数,这样更能节省加载时间。本合集有关css的创建都是采用该方案
点开查看CSS整合方案
- 新建
[Blogroot]\themes\butterfly\source\css\_custom文件夹,然后把自定义魔改样式的css文件拖动进去。文件目录层级可以表示为以下情况:plaintext1
2
3
4
5
6
7source
|__ css
|__ _custom
|__ custom1.css
|__ custom2.css
|__ custom3.css
|__ index.styl - 在
[[Blogroot]\themes\butterfly\source\css\index.styl最底处中新增一行代码:@import '_custom/*.css',表示引入_custom文件夹下的所有css文件。diff1
2
3
4
5
6
7
8
9
10
11
12
13if hexo-config('css_prefix')
@import 'nib'
@import '_third-party/normalize.min.css'
// project
@import 'var'
@import '_global/*'
@import '_highlight/highlight'
@import '_page/*'
@import '_layout/*'
@import '_tags/*'
@import '_mode/*'
+ @import '_custom/*.css' - 如果是使用的外链css,也可以在这里引入。同样是修改
[Blogroot]\themes\butterfly\source\css\index.styl代码,使用@import逐行引入(此处为了确保自定义样式不会被覆盖,放在最底下):diff1
2
3
4
5
6
7
8
9
10
11
12
13if hexo-config('css_prefix')
@import 'nib'
@import '_third-party/normalize.min.css'
// project
@import 'var'
@import '_global/*'
@import '_highlight/highlight'
@import '_page/*'
@import '_layout/*'
@import '_tags/*'
@import '_mode/*'
+ @import 'https://cdn.jsdelivr.net/gh/username/repo/css/example.css' - 这样一来,每个魔改方案的
css依然可以在独立的css文件中找到并修改(如果是手动添加整合的话,只能用注释分割,显然很不利于后续查找修改),而在每次提交时,运行hexo g的过程中就会将所有css文件都整合到index.css,可以在主题配置文件的CDN配置项里给index.css加上jsdelivr进一步提升加载速度(注意刷新jsdelivr的缓存)。
字体样式修改
字体样式的修改需要先引入相应的字体文件,此处推荐使用:
- 打开谷歌字体库

- 输入预览字样,选择喜欢的字体。找到满意的字体后点击进入字体详情页,可以在右侧找到
Select this style等字样的按钮,之后能在侧边栏看到引入内容,分别是字体的API引入链接和font-family写法

- 首先需要引入样式,在
[Blogroot]\themes\butterfly\source\css\_custom新建font.css,写入字体样式APIcss1
@import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@300&display=swap');
- 为了便于预览,我们可以试试直接在页面按F12,然后在控制台中进行调试。
- 在控制台添加的样式是暂时的,我们在预览觉得满意后,就可以把
font-family写进来custom.css了css1
2
3
4@import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@300&display=swap');
h1#site-title {
font-family: 'Roboto+Condensed:wght@300', cursive;
} - 如果需要把某种字体设置为默认字体,可以在
[Blogroot]\_config.butterfly.yml补充以下内容yml1
2
3
4
5
6
7# Global font settings
# Don't modify the following settings unless you know how they work (非必要不要修改)
font:
global-font-size: 16px
code-font-size: 16px
font-family: ZhuZiAYuan
code-font-family: - font-display属性介绍
- 首先需要下载心仪的字体。此处推荐一个免费的字体库网站,支持在线转换预览和免费字体包下载。
- 这里我选择的一款叫做甜甜圈海报字体,根据页面按钮找到字体下载。将下载好的字体放至
[Blogroot]\themes\butterfly\source\fonts\下
不一定是ttf后缀,其他后缀也是完全正常的,例如eot、otf、fon、font、ttc、woff、woff2等
- 首先需要引入样式,在
[Blogroot]\themes\butterfly\source\css\_custom新建font.css,写入字体样式APIcss1
2
3
4
5
6/* 甜甜圈海报字体 */
@font-face {
font-family: 'CandyFont'; /* 字体名自定义即可 */
src: url('/fonts/CandyHome.ttf'); /* 字体文件路径 */
font-display: swap;
} - 为了便于预览,我们可以试试直接在页面按F12,然后在控制台中进行调试。
- 在控制台添加的样式是暂时的,我们在预览觉得满意后,就可以把
font-family写进来custom.css了css1
2
3
4
5
6
7
8
9/* 甜甜圈海报字体 */
@font-face {
font-family: 'CandyFont'; /* 字体名自定义即可 */
src: url('/fonts/CandyHome.ttf'); /* 字体文件路径 */
font-display: swap;
}
#aside-content {
font-family: CandyFont;
} - 如果需要把某种字体设置为默认字体,可以在
[Blogroot]\_config.butterfly.yml补充以下内容yml1
2
3
4
5
6
7# Global font settings
# Don't modify the following settings unless you know how they work (非必要不要修改)
font:
global-font-size: 16px
code-font-size: 16px
font-family: ZhuZiAYuan
code-font-family: - font-display属性介绍
夜间模式或阅读模式修改
点击查看夜间模式或阅读模式修改教程
如果熟悉stylus,可以直接修改[Blogroot]\themes\butterfly\source\css\_mode\darkmode.styl来新增夜间模式样式,但此贴依旧是通过css的方式引入。
有一点需要注意,使用gulp压缩css后,不能以[data-theme=dark]开头,不然会出现本地首个样式能生效但部署远端却无法生效的Bug。
- 新建
[Blogroot]\themes\butterfly\source\css\_custom\dark-read.csscss1
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/* 阅读模式: */
.read-mode #aside-content .card-widget{
background: rgba(158, 204, 171, 0.5);
}
.read-mode div#post{
background: rgba(158, 204, 171, 0.5);
}
.read-mode div#page{
background: rgba(158, 204, 171, 0.5);
}
.read-mode div#category{
background: rgba(158, 204, 171, 0.5);
}
.read-mode div#tag{
background: rgba(158, 204, 171, 0.5);
}
.read-mode div#archive{
background: rgba(158, 204, 171, 0.5);
}
/* 夜间模式 */
[data-theme=dark] div#post{
background: rgba(35,35,35,0.5);
}
[data-theme=dark] div#page{
background: rgba(35,35,35,0.5);
}
[data-theme=dark] div#category{
background: rgba(35,35,35,0.5);
}
[data-theme=dark] div#tag{
background: rgba(35,35,35,0.5);
}
[data-theme=dark] div#archive{
background: rgba(35,35,35,0.5);
}
[data-theme=dark] #recent-posts>.recent-post-item {
background: rgba(35,35,35,0.5);
}
[data-theme=dark] #aside-content .card-widget{
background: rgba(35,35,35,0.5);
}
/* 夜间模式下的阅读模式: */
[data-theme=dark] .read-mode #aside-content .card-widget{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
[data-theme=dark] .read-mode div#post{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
[data-theme=dark] .read-mode div#page{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
[data-theme=dark] .read-mode div#category{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
[data-theme=dark] .read-mode div#tag{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
[data-theme=dark] .read-mode div#archive{
background: rgba(35,35,35,0.5);
color: #ffffff;
}
透明度修改
点击查看透明度修改教程
- 新建
[Blogroot]\themes\butterfly\source\css\_custom\opacity.css,并添加以下内容css1
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/* 首页文章卡片 */
#recent-posts > .recent-post-item{
background:rgba(255, 255, 255, 0.9);
}
/* 首页侧栏卡片 */
.card-widget{
background:rgba(255, 255, 255, 0.9);
}
/* 文章页面正文背景 */
div#post{
background: rgba(255, 255, 255, 0.9);
}
/* 分页页面 */
div#page{
background: rgba(255, 255, 255, 0.9);
}
/* 归档页面 */
div#archive{
background: rgba(255, 255, 255, 0.9);
}
/* 标签页面 */
div#tag{
background: rgba(255, 255, 255, 0.9);
}
/* 分类页面 */
div#category{
background: rgba(255, 255, 255, 0.9);
}
/* opacity定义的是全局的透明度,会影响添加该属性的页面元素及其下属元素 */
#footer{
opacity: 0.5;
} - 如果想定义头图或页脚全透明以实现一图流,继续添加如下内容
一图流方案生效的前提是必须先设置默认的全局背景,在主题配置文件[Blogroot]\_config.butterfly.yml中找到background配置项,改为自己心仪的背景图片链接。
1 | /* 页脚透明 */ |
评论卡片优化
点击查看评论卡片优化教程
当前方案为内测尝鲜版,基本逻辑可以实现,但是js代码可读性较差,且不保证没有冗余步骤。
新建
[Blogroot]\themes\butterfly\source\css\_custom\fixed_comment.css,添加以下内容css1
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
58div#post-comment.fixedcomment {
position: fixed;
top: 0;
width: 60%;
right: 0;
padding: 25px 30px 20px 20px;
height: 100vh;
overflow: scroll;
z-index: 90;
background: rgba(222, 222, 222, 0.95);
box-shadow:3px 2px 14px #464340;
animation: fixedright 0.5s linear;
}
div#post-comment.fixedcomment::-webkit-scrollbar {
width: 0;
}
div#quit-board{
display: none;
}
div#quit-board.fixedcomment {
position: fixed;
display:block;
left: 0;
top: 0;
width: 40%;
height: 100vh;
z-index: 89;
background: rgba(25,25,25,0.3);
filter: blur(4px) ;
animation: fixedleft 0.5s linear;
}
/*手机端样式适配*/
@media screen and (max-width: 768px) {
div#post-comment.fixedcomment {
width: 90%;
right: 0;
}
div#quit-board.fixedcomment {
width: 10%;
}
}
/*动画效果*/
@keyframes fixedright {
from {right:-50%;}
to {right:0;}
}
@keyframes fixedleft {
from {left:-50%;}
to {left:0;}
}
/* 夜间模式匹配 */
[data-theme="dark"] div#post-comment.fixedcomment {
background: rgba(35, 35, 35, 0.95);
box-shadow:3px 2px 12px #90a1a4;
}
[data-theme="dark"] div#quit-board.fixedcomment {
background: rgba(147, 146, 128, 0.3);
}新建
[Blogroot]\themes\butterfly\source\js\custom\fixed_comment.js,添加以下内容js1
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//移除FixedComment类,保持原生样式,确保不与最新评论跳转冲突
function RemoveFixedComment() {
var activedItems = document.querySelectorAll('.fixedcomment');
if (activedItems) {
for (i = 0; i < activedItems.length; i++) {
activedItems[i].classList.remove('fixedcomment');
}
}
}
//给post-comment添加fixedcomment类
function AddFixedComment(){
var commentBoard = document.getElementById('post-comment');
var quitBoard = document.getElementById('quit-board');
commentBoard.classList.add('fixedcomment');
quitBoard.classList.add('fixedcomment');
}
//创建一个蒙版,作为退出键使用
function CreateQuitBoard(){
var quitBoard = `<div id="quit-board" onclick="RemoveFixedComment()"></div>`
var commentBoard = document.getElementById('post-comment');
commentBoard.insertAdjacentHTML("beforebegin",quitBoard)
}
function FixedCommentBtn(){
//第一步,判断当前是否存在FixedComment类,存在则移除,不存在则添加
// 获取评论区对象
var commentBoard = document.getElementById('post-comment');
// 若评论区存在
if (commentBoard) {
// 判断是否存在fixedcomment类
if (commentBoard.className.indexOf('fixedcomment') > -1){
// 存在则移除
RemoveFixedComment();
}
else{
// 不存在则添加
CreateQuitBoard();
AddFixedComment();
}
}
// 若不存在评论区则跳转至留言板(留言板路径记得改为自己的)
else{
// 判断是否开启了pjax,尽量不破坏全局吸底音乐刷新
if (pjax){
pjax.loadUrl("/comments/#post-comment");
}
else{
window.location.href = "/comments/#post-comment";
}
}
}
//切换页面先初始化一遍,确保开始时是原生状态。所以要加pjax重载。
RemoveFixedComment();修改
[Blogroot]\_config.butterfly.yml的inject配置项,引入js代码diff1
2
3
4
5inject:
head:
bottom:
+ - <script data-pjax defer src="/js/custom/fixed_comment.js"></script>理论上给任意元素添加
onclick="FixedCommentBtn();"属性就可以实现评论区侧栏开闭。此处我是修改了原生Butterfly主题的直达评论按钮。修改[Blogroot]\themes\butterfly\layout\includes\rightside.pugdiff1
2
3if commentsJsLoad
- a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment"))
+ button#to_comment(type="button" title=_p("rightside.scroll_to_comment") onclick="FixedCommentBtn();")
添加随机背景或banner
点击查看添加随机背景或banner教程
butterfly主题使用id为web_bg的div来存放背景图片,使用id为page-header的div来存放banner图片。只需要通过重设这个div的背景图片属性就可以替换背景图片。
此方案必须要先在主题配置文件_config.butterfly.yml中配置了默认背景才能生效。最终效果为切换页面或刷新页面时,随机替换当前背景。
- 新建
[Blogroot]\themes\butterfly\source\js\custom\randombg.js,添加以下内容js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//随机背景图片数组,图片可以换成图床链接,注意最后一条后面不要有逗号
var backimg =[
"url(/img/bg1.JPG)",
"url(/img/bg2.jpg)",
"url(/img/bg3.jpg)",
"url(/img/bg4.jpg)"
];
//获取背景图片总数,生成随机数
var bgindex =Math.floor(Math.random() * backimg.length);
//重设背景图片
document.getElementById("web_bg").style.backgroundImage = backimg[bgindex];
//随机banner数组,图片可以换成图床链接,注意最后一条后面不要有逗号
var bannerimg =[
"url(/img/bg1.JPG)",
"url(/img/bg2.jpg)",
"url(/img/bg3.jpg)",
"url(/img/bg4.jpg)"
];
//获取banner图片总数,生成随机数
var bannerindex =Math.floor(Math.random() * bannerimg.length);
//重设banner图片
document.getElementById("page-header").style.backgroundImage = bannerimg[bannerindex]; - 在
[Blogroot]\_config.butterfly.yml引入randombg.jsdiff1
2
3
4inject:
head:
bottom:
+ - <script async data-pjax src="/js/custom/randombg.js"></script>
站点动态title
站点动态title是通过js监测是否聚焦于当前页面,从而替换标签显示内容。
点击查看添加站点动态title教程
- 新建
[Blogroot]\themes\butterfly\source\js\custom\diytitle.js,添加以下内容js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//动态标题
var OriginTitile = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
//离开当前页面时标签显示内容
document.title = 'w(゚Д゚)w 不要走!再看看嘛!';
clearTimeout(titleTime);
}
else {
//返回当前页面时标签显示内容
document.title = '♪(^∇^*)欢迎回来!' + OriginTitile;
//两秒后变回正常标题
titleTime = setTimeout(function () {
document.title = OriginTitile;
}, 2000);
}
}); - 在
[Blogroot]\_config.butterfly.yml引入diytitle.jsdiff1
2
3
4
5
6inject:
head:
# - <link rel="stylesheet" href="/xxx.css">
bottom:
# - <script src="xxxx"></script>
+ - <script async src="/js/costom/diytitle.js"></script>
引入Iconfont
点击查看Iconfont引入教程
- 修改
[Blogroot]\_config.butterfly.yml的inject配置项 - 新建
[Blogroot]\themes\butterfly\source\css\_custom\iconfont.css样式 - 新建
[Blogroot]\themes\butterfly\scripts\tag\iconfont.js
菜单栏、社交栏多色图标引入
点击查看菜单栏、社交栏多色图标引入教程
- 完成
Inconfont的Symbol方式导入 - 修改
[Blogroot]\themes\butterfly\layout\includes\header\menu_item.pug - 修改
[Blogroot]\themes\butterfly\layout\includes\header\social.pug
Sidebar Card Clock
点击查看Sidebar Card Clock引入教程
- 安装插件,在博客根目录
[Blogroot]下打开终端,运行以下指令:bash1
npm install hexo-butterfly-swiper --save
- 在
[Blogroot]\_config.butterfly.yml中添加swiper配置项yml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# electric_clock
# see https://akilar.top/posts/4e39cf4a/
electric_clock:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
exclude:
# - /posts/
# - /about/
layout: # 挂载容器类型
type: class
name: sticky_layout
index: 0
loading: https://npm.elemecdn.com/hexo-butterfly-clock/lib/loading.gif #加载动画自定义
clock_css: https://npm.elemecdn.com/hexo-butterfly-clock/lib/clock.min.css
clock_js: https://npm.elemecdn.com/hexo-butterfly-clock/lib/clock.min.js
ip_api: https://pv.sohu.com/cityjson?ie=utf-8 - 参数释义
| 参数 | 备选值/类型 | 释义 |
|---|---|---|
| priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10 |
| enable | true/false | 【必选】控制开关 |
| enable_page | path/all | 【可选】填写想要应用的页面的相对路径(即路由地址),如根目录就填’/’,分类页面就填’/categories/’。若要应用于所有页面,就填’all’,默认为all |
| exclude | path | 【可选】填写想要屏蔽的页面,可以多个。写法见示例。原理是将屏蔽项的内容逐个放到当前路径去匹配,若当前路径包含任一屏蔽项,则不会挂载。 |
| layout.type | id/class | 【可选】挂载容器类型,填写id或class,不填则默认为id |
| layout.name | text | 【必选】挂载容器名称 |
| layout.index | 0和正整数 | 【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位 |
| loading | URL | 【可选】电子钟加载动画的图片 |
| clock_css | URL | 【可选】电子钟样式CDN资源 |
| clock_js | URL | 【可选】电子钟执行脚本CDN资源 |
| ip_api | URL | 【可选】获取时钟IP的API |
Swiper Bar
点击查看Swiper Bar教程
- 安装插件,在博客根目录
[Blogroot]下打开终端,运行以下指令:bash1
npm install hexo-butterfly-swiper --save
- 在
[Blogroot]\_config.butterfly.yml中添加swiper配置项yml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# hexo-butterfly-swiper
# see https://akilar.top/posts/8e1264d1/
swiper:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
timemode: date #date/updated
layout: # 挂载容器类型
type: id
name: recent-posts
index: 0
default_descr: 再怎么看我也不知道怎么描述它的啦!
swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css #swiper css依赖
swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js #swiper js依赖
custom_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css # 适配主题样式补丁
custom_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js # swiper初始化方法 - 参数释义
| 参数 | 备选值/类型 | 释义 |
|---|---|---|
| priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10 |
| enable | true/false | 【必选】控制开关 |
| enable_page | path/all | 【可选】填写想要应用的页面的相对路径(即路由地址),如根目录就填’/’,分类页面就填’/categories/’。若要应用于所有页面,就填’all’,默认为all |
| timemode | date/updated | 【可选】时间显示,date为显示创建日期,updated为显示更新日期,默认为date |
| layout.type | id/class | 【可选】挂载容器类型,填写id或class,不填则默认为id |
| layout.name | text | 【必选】挂载容器名称 |
| layout.index | 0和正整数 | 【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位 |
| default_descr | text | 默认文章描述 |
| swiper_css | URL | 【可选】自定义的swiper依赖项css链接 |
| swiper_js | URL | 【可选】自定义的swiper依赖项加js链接 |
| custom_css | URL | 【可选】适配主题样式补丁 |
| custom_js | URL | 【可选】swiper初始化方法 |
Tag Plugins Plus
点击查看教程
- 安装插件,在博客根目录
[Blogroot]下打开终端,运行以下指令:bash1
2
3npm install hexo-butterfly-tag-plugins-plus --save
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save - 在
[Blogroot]\_config.butterfly.yml中添加tag_plugins配置项
相关推荐版块侧栏卡片化
点击查看相关推荐版块侧栏卡片化教程
- 修改
[Blogroot]\themes\butterfly\scripts\helpers\related_post.jsdiff1
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
33if (relatedPosts.length > 0) {
- result += '<div class="relatedPosts">'
- result += `<div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>${headlineLang}</span></div>`
- result += '<div class="relatedPosts-list">'
+ result += '<div class="card-widget card-recommend-post">'
+ result += `<div class="item-headline"><i class="fas fa-dharmachakra"></i><span>${headlineLang}</span></div>`
+ result += '<div class="aside-list">'
for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
const cover =
relatedPosts[i].cover === false
? relatedPosts[i].randomcover
: relatedPosts[i].cover
- result += `<div><a href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">`
- result += `<img class="cover" src="${this.url_for(cover)}" alt="cover">`
+ result += `<div class="aside-list-item">`
+ result += `<a class="thumbnail" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}"><img src="${this.url_for(cover)}" alt="${relatedPosts[i].title}"></a>`
+ result += `<div class="content">`
+ result += `<a class="title" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">${relatedPosts[i].title}</a>`
if (dateType === 'created') {
- result += `<div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> ${this.date(relatedPosts[i].created, hexoConfig.date_format)}</div>`
+ result += `<time datetime="${this.date(relatedPosts[i].created, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].created, hexoConfig.date_format)}">${this.date(relatedPosts[i].created, hexoConfig.date_format)}</time>`
} else {
- result += `<div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</div>`
+ result += `<time datetime="${this.date(relatedPosts[i].updated, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}">${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</time>`
}
- result += `<div class="title">${relatedPosts[i].title}</div>`
- result += '</div></a></div>'
+ result += `</div></div>`
}
result += '</div></div>'
return result
}js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23if (relatedPosts.length > 0) {
result += '<div class="card-widget card-recommend-post">'
result += `<div class="item-headline"><i class="fas fa-dharmachakra"></i><span>${headlineLang}</span></div>`
result += '<div class="aside-list">'
for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
const cover =
relatedPosts[i].cover === false
? relatedPosts[i].randomcover
: relatedPosts[i].cover
result += `<div class="aside-list-item">`
result += `<a class="thumbnail" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}"><img src="${this.url_for(cover)}" alt="${relatedPosts[i].title}"></a>`
result += `<div class="content">`
result += `<a class="title" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">${relatedPosts[i].title}</a>`
if (dateType === 'created') {
result += `<time datetime="${this.date(relatedPosts[i].created, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].created, hexoConfig.date_format)}">${this.date(relatedPosts[i].created, hexoConfig.date_format)}</time>`
} else {
result += `<time datetime="${this.date(relatedPosts[i].updated, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}">${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</time>`
}
result += `</div></div>`
}
result += '</div></div>'
return result
} - 因为原本的版块是在文章下方,而现在我们需要把它改到侧栏,所以需要修改
[Blogroot]\themes\butterfly\layout\post.pug,大约26行的位置先移除在文章底部的推荐版块。diff1
2
3
4
5
6if theme.post_pagination
include includes/pagination.pug
- if theme.related_post && theme.related_post.enable
- != related_posts(page,site.posts)
if page.comments !== false && theme.comments && theme.comments.use - 因为感觉文章也最新文章和推荐文章同时存在,最新文章就显得有点多余了,所以我把最新文章的侧栏卡片注释了,修改
[Blogroot]\themes\butterfly\layout\includes\widget\index.pugdiff1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#aside-content.aside-content
//- post
if is_post()
if showToc && theme.toc.style_simple
.sticky_layout
include ./card_post_toc.pug
else
!=partial('includes/custom/SAO_card_player', {}, {cache:theme.fragment_cache})
!=partial('includes/widget/card_announcement', {}, {cache:theme.fragment_cache})
!=partial('includes/widget/card_top_self', {}, {cache:theme.fragment_cache})
.sticky_layout
if showToc
include ./card_post_toc.pug
+ if theme.related_post && theme.related_post.enable
+ != related_posts(page,site.posts)
- - !=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
+ //- !=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
!=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
Gitcalendar
点击查看Gitcalendar引入教程
安装插件,在博客根目录
[Blogroot]下打开终端,运行以下指令:bash1
npm install hexo-filter-gitcalendar --save
在
[Blogroot]\_config.butterfly.yml中添加gitcalendar配置项yml1
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# hexo-filter-gitcalendar
# see https://akilar.top/posts/1f9c68c9/
gitcalendar:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: / # 应用页面
# butterfly挂载容器
layout: # 挂载容器类型
type: id
name: recent-posts
index: 0
# volantis挂载容器
# layout:
# type: class
# name: l_main
# index: 0
# matery挂载容器
# layout:
# type: id
# name: indexCard
# index: 0
# mengd挂载容器
# layout:
# type: class
# name: content
# index: 0
user: Akilarlxh #git用户名
apiurl: 'https://gitcalendar.akilar.top'
minheight:
pc: 280px #桌面端最小高度
mibile: 0px #移动端最小高度
color: "['#e4dfd7', '#f9f4dc', '#f7e8aa', '#f7e8aa', '#f8df72', '#fcd217', '#fcc515', '#f28e16', '#fb8b05', '#d85916', '#f43e06']" #橘黄色调
# color: "['#ebedf0', '#fdcdec', '#fc9bd9', '#fa6ac5', '#f838b2', '#f5089f', '#c4067e', '#92055e', '#540336', '#48022f', '#30021f']" #浅紫色调
# color: "['#ebedf0', '#f0fff4', '#dcffe4', '#bef5cb', '#85e89d', '#34d058', '#28a745', '#22863a', '#176f2c', '#165c26', '#144620']" #翠绿色调
# color: "['#ebedf0', '#f1f8ff', '#dbedff', '#c8e1ff', '#79b8ff', '#2188ff', '#0366d6', '#005cc5', '#044289', '#032f62', '#05264c']" #天青色调
container: .recent-post-item(style='width:100%;height:auto;padding:10px;') #父元素容器,需要使用pug语法
gitcalendar_css: https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.css
gitcalendar_js: https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.js参数释义
| 参数 | 备选值/类型 | 释义 |
|---|---|---|
| priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10,选填 |
| enable | true/false | 【必选】控制开关 |
| enable_page | path/all | 【可选】填写想要应用的页面的相对路径(即路由地址),如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填’all’,默认为’/‘ |
| layout.type | id/class | 【可选】挂载容器类型,填写id或class,不填则默认为id |
| layout.name | text | 【必选】挂载容器名称 |
| layout.index | 0和正整数 | 【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位 |
| user | text | 【必选】git用户名 |
| apiurl | url | 【可选】默认使用提供文档提供的api,但还是建议自建api,参考教程:自建API部署 |
| minheight.pc | 280px | 【可选】桌面端最小高度,默认为280px |
| minheight.mobile | 0px | 【可选】移动端最小高度,默认为0px |
| color | list | 【可选】一个包含11个色值的数组,文档给出了四款预设值 |
| container | pug | 【可选】预留的父元素容器,用以适配多主题,需要用pug语法填写,目前已适配butterfly,volantis,matery,mengd主题,这四个主题,插件会自自动识别_config.yml内填写的theme配置项。其余主题需要自己填写父元素容器。 |
| gitcalendar_css | URL | 【可选】自定义CSS样式链接 |
| gitcalendar_js | URL | 【可选】自定义js链接 |
引入Waline评论
点击查看Waline引入教程
- 在LeanCloud中创建数据库
- 在Vercel部署服务端
- 修改
[Blogroot]\themes\butterfly\layout\includes\third-praty\comments\waline.pug
1 | - const { serverURL, option, pageview } = theme.waline |
引入Twikoo评论
twikoo评论块气泡风格美化
点击查看twikoo评论块气泡风格美化教程
- 新建
[Blogroot]\themes\butterfly\source\css\_custom\twikoo_beautify.css,添加以下内容css1
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213/* 自定义twikoo评论输入框高度 */
.tk-input[data-v-619b4c52] .el-textarea__inner {
height: 130px ;
}
/* 输入评论时自动隐藏输入框背景图片 */
.tk-input[data-v-619b4c52] .el-textarea__inner:focus {
background-image: none ;
}
/* 调整楼中楼样式 ,整体左移,贴合气泡化效果 */
.tk-replies {
left: -70px;
width: calc(100% + 70px);
}
/* 头像宽度调整 rem单位与全局字体大小挂钩,需配合自己情况调整大小以保证头像显示完整*/
.tk-replies .tk-avatar {
width: 2.5rem ;
height: 2.5rem ;
}
.tk-replies .tk-avatar img {
width: 2.5rem ;
height: 2.5rem ;
}
/* 回复框左移,避免窄屏时出框 */
.tk-comments-container .tk-submit {
position: relative;
left: -70px;
}
/* 评论块气泡化修改 */
.tk-content {
background: linear-gradient( 135deg, #ABDCFF 10%, #0396FF 100%); /*默认模式访客气泡配色*/
padding: 10px;
color: #fff; /*默认模式访客气泡字体配色*/
border-radius: 10px;
font-size: 16px ;
width: fit-content;
max-width: 100%;
position: relative ;
overflow: visible ;
max-height: none ;
}
/* 修复图片出框 */
.tk-content img {
max-width: 100% ;
}
/* 修复过长文本出框 */
.tk-content pre {
white-space: pre-wrap;
word-wrap: break-word;
}
.tk-content a {
color: #eeecaa; /*默认模式超链接配色*/
}
.tk-content::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 20px;
left: -13px;
border-top: 2px solid transparent;
border-bottom: 20px solid transparent;
border-right: 15px solid #00a6ff; /*默认模式访客气泡小三角配色*/
border-left: 0px solid transparent;
}
.tk-master .tk-content {
background: linear-gradient( 135deg, #FAD7A1 10%, #E96D71 100%);/*默认模式博主气泡配色*/
color: #fff; /*默认模式博主气泡字体配色*/
width: fit-content;
max-width: 100%;
}
.tk-master .tk-content a {
color: #eeecaa;
}
.tk-master .tk-content::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 20px;
left: -13px;
border-top: 2px solid transparent;
border-bottom: 20px solid transparent;
border-right: 15px solid #ff8080; /*默认模式博主气泡小三角配色*/
border-left: 0px solid transparent;
}
.tk-row[data-v-d82ce9a0] {
max-width: 100%;
width: fit-content;
}
.tk-avatar {
border-radius: 50%;
margin-top: 10px;
}
/* 夜间模式配色,具体比照上方默认模式class */
[data-theme="dark"] .tk-content {
background: linear-gradient( 135deg, #6B73FF 10%, #000DFF 100%);
color: #fff;
}
[data-theme="dark"] .tk-content a {
color: #dfa036;
}
[data-theme="dark"] .tk-content::before {
border-right: 15px solid #000;
}
[data-theme="dark"] .tk-master .tk-content {
background: linear-gradient( 135deg, #FAB2FF 10%, #1904E5 100%);;
color: #fff;
}
[data-theme="dark"] .tk-master .tk-content a {
color: #dfa036;
}
[data-theme="dark"] .tk-master .tk-content::before {
border-top: 2px solid transparent;
border-bottom: 20px solid transparent;
border-right: 15px solid #000;
border-left: 0px solid transparent;
}
/* 自适应内容 */
@media screen and (min-width: 1024px) {
/* 设置宽度上限,避免挤压博主头像 */
.tk-content {
max-width: 75%;
width: fit-content;
}
.tk-master .tk-content {
width: 75%;
}
.tk-master .tk-content::before {
left: 100%;
border-left: 15px solid #ff8080;
border-right: 0px solid transparent;
}
.tk-master .tk-avatar {
position: relative;
left: calc(75% + 70px);
}
.tk-master .tk-row[data-v-d82ce9a0] {
position: relative;
top: 0px;
left: calc(75% - 230px);
}
[data-theme="dark"] .tk-master .tk-content::before {
border-left: 15px solid #000;
border-right: 0px solid transparent;
}
}
/* 设备名称常态隐藏,悬停评论时显示 */
.tk-extras {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
.tk-content:hover + .tk-extras {
-webkit-animation: tk-extras-fadeIn 0.5s linear;
-moz-animation: tk-extras-fadeIn 0.5s linear;
-o-animation: tk-extras-fadeIn 0.5s linear;
-ms-animation: tk-extras-fadeIn 0.5s linear;
animation: tk-extras-fadeIn 0.5s linear;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@-moz-keyframes tk-extras-fadeIn {
from {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
to {
opacity: 1;
-ms-filter: none;
filter: none;
}
}
@-webkit-keyframes tk-extras-fadeIn {
from {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
to {
opacity: 1;
-ms-filter: none;
filter: none;
}
}
@-o-keyframes tk-extras-fadeIn {
from {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
to {
opacity: 1;
-ms-filter: none;
filter: none;
}
}
@keyframes tk-extras-fadeIn {
from {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
to {
opacity: 1;
-ms-filter: none;
filter: none;
}
}
首页卡片修改
点击查看首页卡片修改教程
样式配色因为采用了大量伪类,所以如果底色采用了半透明配色,可能因为卡片叠加加深导致接合边界非常明显的暴露出来。所以在配色上,不建议加半透明的。因为部分伪类的偏移量是靠计算得出的,为了尽量满足自适应效果,部分位置保留了5%左右的容差。所以在一些极端屏宽比下,还是会出现一些样式不完美问题。
- 修改
[Blogroot]\themes\butterfly\layout\includes\mixins\post-ui.pug,将整个文件的内容替换为以下代码。plaintext1
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
115mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
.recent-post-content(class=leftOrRight)
a.article-content(href=url_for(link) title=subtitle)
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.article-content-text!= article.description
when 2
if article.description
.article-content-text!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.article-content-text!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.article-content-text!= expert
.recent-post-info
a.article-title(href=url_for(link) title=subtitle)
.article-title-link= title
.recent-post-meta
.article-meta-wrap
if (is_home() && (article.top || article.sticky > 0))
span.article-meta
i.fas.fa-thumbtack.sticky
span.sticky= _p('sticky')
span.article-meta-separator |
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
i.fas.fa-inbox
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
i.fas.fa-tag
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a(href=full_url_for(link) + '#disqus_thread')
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment' itemprop="discussionUrl")
span.valine-comment-count(data-xid=url_for(link) itemprop="commentCount")
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(id=url_for(link))
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
.recent-post-cover
img.article-cover(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=subtitle)
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index - 修改
[Blogroot]\themes\butterfly\source\css\_page\homepage.styl,将整个文件的内容替换为以下代码。stylus1
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351//default color:
:root
--recent-post-bgcolor: rgba(255, 255, 255, 0.9)
--article-content-bgcolor: #49b1f5
--recent-post-triangle: #fff
--recent-post-cover-shadow: #ffffff
[data-theme="dark"]
--recent-post-bgcolor: rgba(35,35,35,0.5)
--article-content-bgcolor: #99999a
--recent-post-triangle: #37e2dd
--recent-post-cover-shadow: #232323
.recent-posts
padding 0 15px 0 15px
.recent-post-item
margin-bottom 15px
width 100%
background var(--recent-post-bgcolor)
overflow hidden
border-radius 15px
.recent-post-info
.article-title-link
display -webkit-box
-webkit-box-orient vertical
-webkit-line-clamp 2
overflow hidden
.article-content
background var(--article-content-bgcolor)
position relative
display flex
align-items: center;
justify-content: center;
.article-content-text
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
display -webkit-box
-webkit-box-orient vertical
-webkit-line-clamp 4
text-overflow: ellipsis
overflow hidden
color #fff
text-shadow: 1px 2px 3px #000;
.recent-post-cover
position relative
background transparent
img
&.article-cover
height 100%
width 100%
object-fit cover
.recent-post-info
align-items center
flex-direction column
position relative
background var(--recent-post-bgcolor)
display flex
color #000000
.article-title
height 50%
font-size 24px
display: flex
align-items: center
justify-content: flex-end
flex-direction: column
.article-title-link
color: var(--text-highlight-color)
transition: all .2s ease-in-out
&:hover
color: $text-hover
.recent-post-meta
height 50%
display: flex
align-items: center
justify-content: flex-start
flex-direction: column
.article-meta-wrap
font-size 12px
color #969797
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
a
color: var(--text-highlight-color)
transition: all .2s ease-in-out
color #969797
&:hover
color: $text-hover
&.ads-wrap
display: block
height: auto
@media screen and (min-width:600px)
.recent-post-item
&:hover
.recent-post-content
&.both,
&.right
transform translateX(21%)
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
left: 50px;
.article-content-text
margin 20px 20px 20px 60px
&.left
transform translateX(-21%)
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
right: 50px;
.article-content-text
margin 20px 60px 20px 20px
.recent-post-content
background var(--recent-post-bgcolor)
position relative
height 200px
width 130%
z-index 0
display flex
overflow hidden
border 0px solid
&::before
content: "";
width: 0;
height: 0;
background: transparent;
position: absolute;
z-index: 3;
top: calc(50% - 10px);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&.both,
&.right
flex-direction: row;
left calc(-23.07% - 41px)
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
left: calc(23.07% + 40px);
border-left: 6px solid var(--recent-post-triangle);
.recent-post-info
&::before
background linear-gradient(to right, var(--recent-post-cover-shadow), transparent)
left calc(100% - 1px)
.article-content
&::before
right -59px
border-left 60px solid var(--article-content-bgcolor)
.article-content-text
margin 20px 20px 20px 0px
.article-title
padding 0px 30px 0px 70px
.recent-post-meta
padding 0px 20px 0px 70px
&.left
flex-direction: row-reverse;
right 9px
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
right: calc(23.07% + 40px);
border-right: 6px solid var(--recent-post-triangle);
.recent-post-info
&::before
background linear-gradient(to left, var(--recent-post-cover-shadow), transparent)
right calc(100% - 1px)
.article-content
&::before
left -59px
border-right 60px solid var(--article-content-bgcolor)
.article-content-text
margin 20px 0px 20px 20px
.article-title
padding 0px 70px 0px 30px
.recent-post-meta
padding 0px 70px 0px 20px
.article-content
width 30%
height 200px
left 0
align-items center
&::before
content ""
width 0
height 0
background transparent
position absolute
z-index 2
top 0
border-top 100px solid transparent
border-bottom 100px solid transparent
.recent-post-info
width 60%
height 200px
&::before
content ""
width 200px
height 200px
position absolute
z-index 1
top 0
.recent-post-meta
& > .article-meta-wrap
margin: 6px 0
color: $theme-meta-color
font-size: 90%
& > .post-meta-date
cursor: default
.sticky
color: $sticky-color
i
margin: 0 4px 0 0
.article-meta-label
if hexo-config('post_meta.page.label')
padding-right: 4px
else
display: none
.article-meta-separator
margin: 0 6px
.article-meta-link
margin: 0 4px
if hexo-config('post_meta.page.date_format') == 'relative'
time
display: none
a
color: $theme-meta-color
&:hover
color: $text-hover
text-decoration: underline
.recent-post-cover
width 40%
height 200px
@media screen and (max-width:600px)
.recent-post-item
height 400px
.recent-post-content
display flex
flex-direction: column
height 400px
.article-content
pointer-events none
order: 1;
height: 200px;
position: absolute;
width: calc(100% - 40px);
z-index: 3;
background: rgba(22,22,22,0.5);
border-top-left-radius: 15px;
border-top-right-radius: 15px;
display: none
opacity: 0
.article-content-text
height 120px
color: white;
width: 80%
.recent-post-cover
order: 2
height 200px
transition: all .5s
.recent-post-info
order: 3
height 200px
&::before
content: '';
width: 0;
height: 0;
position: absolute;
z-index: 3;
bottom: calc(100% - 4px);
left: 0;
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
&::after
content: '';
width: 0;
height: 0;
position: absolute;
z-index: 3;
bottom: calc(100% + 150px);
right: 0;
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
.article-title
padding: 0px 35px 0px 35px
.recent-post-meta
padding: 0px 30px 0px 30px
&:hover
.article-content
display: flex ;
animation: shutter-effect-content 0.5s 2 forwards linear
.recent-post-info
&::before
animation: shutter-effect-left 0.5s 1 ease-in-out
&::after
animation: shutter-effect-right 0.5s 1 ease-in-out
.recent-post-cover
filter blur(2px)
@keyframes shutter-effect-right {
0%{
bottom: calc(100% + 150px);
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
}
50%{
bottom: 100%;
border-top: 200px solid var(--recent-post-bgcolor);
border-left: 600px solid transparent;
}
100%{
bottom: calc(100% + 150px);
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
}
}
@keyframes shutter-effect-left {
0%{
bottom: calc(100% - 4px);
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
}
50%{
bottom: calc(100% - 4px);
border-bottom: 200px solid var(--recent-post-bgcolor);
border-right: 600px solid transparent;
}
100%{
bottom: calc(100% - 4px);
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
}
}
@keyframes shutter-effect-content {
from {
opacity: 0
}
to {
opacity: 1
}
}
使用gulp压缩博客静态资源
点击查看gulp压缩博客静态资源教程
- 安装
Gulp插件:在博客根目录[Blogroot]打开终端,输入:bash1
2npm install --global gulp-cli #全局安装gulp指令集
npm install gulp --save #安装gulp插件 - 安装各个下属插件以实现对各类静态资源的压缩
- 压缩HTML:bash
1
2
3npm install gulp-htmlclean --save-dev
npm install gulp-html-minifier-terser --save-dev
# 用gulp-html-minifier-terser可以压缩HTML中的ES6语法 - 压缩CSS:bash
1
npm install gulp-clean-css --save-dev
- 压缩JSbash
1
npm install gulp-terser --save-dev
- 压缩字体包bash
1
npm install gulp-fontmin --save-dev
为
Gulp创建gulpfile.js任务脚本。在博客根目录[Blogroot]下新建gulpfile.js,打开[Blogroot]\gulpfile.js,输入以下内容:bash1
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//用到的各个插件
var gulp = require('gulp');
var cleanCSS = require('gulp-clean-css');
var htmlmin = require('gulp-html-minifier-terser');
var htmlclean = require('gulp-htmlclean');
var fontmin = require('gulp-fontmin');
// gulp-tester
var terser = require('gulp-terser');
// 压缩js
gulp.task('compress', () =>
gulp.src(['./public/**/*.js', '!./public/**/*.min.js'])
.pipe(terser())
.pipe(gulp.dest('./public'))
)
//压缩css
gulp.task('minify-css', () => {
return gulp.src(['./public/**/*.css'])
.pipe(cleanCSS({
compatibility: 'ie11'
}))
.pipe(gulp.dest('./public'));
});
//压缩html
gulp.task('minify-html', () => {
return gulp.src('./public/**/*.html')
.pipe(htmlclean())
.pipe(htmlmin({
removeComments: true, //清除html注释
collapseWhitespace: true, //压缩html
collapseBooleanAttributes: true,
//省略布尔属性的值,例如:<input checked="true"/> ==> <input />
removeEmptyAttributes: true,
//删除所有空格作属性值,例如:<input id="" /> ==> <input />
removeScriptTypeAttributes: true,
//删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,
//删除<style>和<link>的 type="text/css"
minifyJS: true, //压缩页面 JS
minifyCSS: true, //压缩页面 CSS
minifyURLs: true //压缩页面URL
}))
.pipe(gulp.dest('./public'))
});
//压缩字体
function minifyFont(text, cb) {
gulp
.src('./public/fonts/*.ttf') //原字体所在目录
.pipe(fontmin({
text: text
}))
.pipe(gulp.dest('./public/fontsdest/')) //压缩后的输出目录
.on('end', cb);
}
gulp.task('mini-font', (cb) => {
var buffers = [];
gulp
.src(['./public/**/*.html']) //HTML文件所在目录请根据自身情况修改
.on('data', function(file) {
buffers.push(file.contents);
})
.on('end', function() {
var text = Buffer.concat(buffers).toString('utf-8');
minifyFont(text, cb);
});
});
// 运行gulp命令时依次执行以下任务
gulp.task('default', gulp.parallel(
'compress', 'minify-css', 'minify-html','mini-font'
))在每次运行完
hexogenerate生成静态页面后,运行gulp对其进行压缩。关于
font-min的补充说明,在本文中,是通过读取所有编译好的html文件(./public/**/*.html)中的字符,然后匹配原有字体包内./public/fonts/*.ttf字体样式,输出压缩后的字体包到./public/fontsdest/目录。所以最终引用字体的相对路径应该是/fontsdest/*.ttf。而本地测试时,如果没有运行gulp,自然也就不会输出压缩字体包到public目录,也就看不到字体样式。
渐变星空Sky粒子背景特效
点击查看渐变星空Sky粒子背景特效教程
信笺样式留言板
点击查看信笺样式留言板教程
- 在
[Blogroot]运行指令
1 | npm install hexo-butterfly-envelope --save |
- 在站点配置文件或者主题配置文件添加配置项(对,两者任一均可。但不要都写)
1 | # envelope_comment |
































