前言
鸽了几万年的楠终于开始重构自己的屎山博客了,此贴来记录楠是用了什么东西堆成新的 屎山
部署
- 由
GitHub储存 - 由
Vercel托管部署 - 更换
vercel.cdn.yt-blog.top节点加快国内访问速度 - 版本:
hexo: 6.3.0butterfly: 4.7.0
整理配置文件
- 将主题配置文件复制出来,方便更改
- 将配置文件注释汉化
图床
本来想搞个 cdn 来加速 GitHub 仓库当图床的,结果 https 要证书,就开始了艰辛的坐牢一日。
证书
- 安装
wsl,在微软商店下载了个Ubuntu 2204版本。 - 启动的时候出错了,一直报错
0x8004032d。上网查找之后使用下面的命令安装并初始化(前提是已经开启Hype-v适用于Linux的Windows子系统虚拟机平台)。cmd wsl --install
- 就是正常配置用户名密码啥的,成功进入 wsl。并使用 sudo 命令设置 root 密码。
sh sudo passwd root
- 安装
acme.sh的时候又出问题了,没有代理连接不上Github。解决方法来自博客园的一篇文章 传送门。 省流: 就是在Windows中的C:\Users\<your_username>目录下创建一个.wslconfig 文件,并写入以下代码。config [experimental] autoMemoryReclaim=gradual networkingMode=mirrored dnsTunneling=true firewall=true autoProxy=true
再使用终端重启 wsl。shell wsl --shutdown
注意,每次开关梯子都要重新启动 wsl - 成功安装
acme.sh后便开始手动生成证书- 第一次要先使用
sh ~/.acme.sh/acme.sh --register-account -m <你的邮箱>
来注册账户 - 注册成功后使用
sh ~/.acme.sh/acme.sh --issue -d <域名> --dns dns-01
生成证书 - 按照要求在域名服务商添加
TXT解析,等候片刻再次运行命令就生成证书了
- 第一次要先使用
- 生成的证书在/root 目录,这里又出现个问题,无法访问,显示没有权限。
解决方法:
sh cd / sudo nano /etc/wsl.conf
在wsl.cong里面添加conf [user] default=root
让默认账户是 root 就解决了
配置 cdn
自己搞半天没成功,最后问了一下 煮雪话河山 大佬,并跟着大佬一步一步走才成功
- 绑定的加速网站:要加速的网站
- 源站:加速网站绑定的源站,如
vercel绑定域名的时候的cname.vercel-dns.com或者是cf page绑定域名时候的xxx.pages.dev - https 证书:证书
外挂标签
使用的是店长的 Tag Plugins Plus 用的是源码部署,站外卡片的样式因为看到 June 的样式很喜欢,所以就也去洪哥的帖子 cv 了一个下来,略微改改。
文章版权卡片美化
使用的是 Fomalhaut 和 店长 的样式,并自己修改了一点 css。
修改过的 css:
beautify()
headStyle(fontsize)
padding-left: unit(fontsize + 12, 'px')
&:before
margin-left: unit((-(fontsize + 6)), 'px')
font-size: unit(fontsize, 'px')
&:hover
padding-left: unit(fontsize + 18, 'px')
h1,
h2,
h3,
h4,
h5,
h6
transition: all .2s ease-out
&:before
position: absolute
top: calc(50% - 7px)
color: $title-prefix-icon-color
content: $title-prefix-icon
line-height: 1
transition: all .2s ease-out
@extend .fontawesomeIcon
&:hover
&:before
color: $light-blue
h1
headStyle(20)
h2
headStyle(18)
h3
headStyle(16)
h4
headStyle(14)
h5
headStyle(12)
h6
headStyle(12)
ol,
ul
p
margin: 0 0 8px
li
&::marker
color: $light-blue
font-weight: 600
font-size: 1.05em
&:hover
&::marker
color: var(--pseudo-hover)
ul > li
list-style-type: circle
#article-container
word-wrap: break-word
overflow-wrap: break-word
a
color: $theme-link-color
&:hover
text-decoration: underline
img
display: block
margin: 0 auto 20px
max-width: 100%
transition: filter 375ms ease-in .2s
p
margin: 0 0 16px
iframe
margin: 0 0 20px
if hexo-config('anchor')
a.headerlink
&:after
@extend .fontawesomeIcon
float: right
color: var(--headline-presudo)
content: '\f0c1'
font-size: .95em
opacity: 0
transition: all .3s
&:hover
&:after
color: var(--pseudo-hover)
h1,
h2,
h3,
h4,
h5,
h6
&:hover
a.headerlink
&:after
opacity: 1
ol,
ul
ol,
ul
padding-left: 20px
li
margin: 4px 0
p
margin: 0 0 8px
if hexo-config('beautify.enable')
if hexo-config('beautify.field') == 'site'
beautify()
else if hexo-config('beautify.field') == 'post'
&.post-content
beautify()
> :last-child
margin-bottom: 0 !important
#post
.tag_share
.post-meta
&__tag-list
display: inline-block
&__tags
display: inline-block
margin: 8px 8px 8px 0
padding: 0 12px
width: fit-content
border: 1px solid $light-blue
border-radius: 12px
color: $light-blue
font-size: .85em
transition: all .2s ease-in-out
&:hover
background: $light-blue
color: var(--white)
.post_share
display: inline-block
float: right
margin: 8px 0
width: fit-content
.social-share
font-size: .85em
.social-share-icon
margin: 0 4px
width: w = 1.85em
height: w
font-size: 1.2em
line-height: w
.post-copyright
position: relative
margin: 40px 0 10px
padding: 10px 16px
border: 1px solid var(--light-grey)
transition: box-shadow .3s ease-in-out
overflow: hidden
border-radius: 12px!important
background: none;
&:before
background var(--heo-post-blockquote-bg)
position absolute
right -26px
top -120px
content '\f25e'
font-size 200px
font-family 'Font Awesome 5 Brands'
opacity .2
&:hover
box-shadow: 0px 0px 8px 1px #e5e5e5
.post-copyright
&-meta
color: $light-blue
font-weight: bold
&-info
padding-left: 6px
a
text-decoration: none
word-break: break-word
&:hover
text-decoration: none
.post-copyright-cc-info
color: $theme-color;
.post-outdate-notice
position: relative
margin: 0 0 20px
padding: .5em 1.2em
border-radius: 3px
background-color: $noticeOutdate-bg
color: $noticeOutdate-color
if hexo-config('noticeOutdate.style') == 'flat'
padding: .5em 1em .5em 2.6em
border-left: 5px solid $noticeOutdate-border
&:before
@extend .fontawesomeIcon
position: absolute
top: 50%
left: .9em
color: $noticeOutdate-border
content: '\f071'
transform: translateY(-50%)
.ads-wrap
margin: 40px 0
.post-copyright-m-info
.post-copyright-a,
.post-copyright-c,
.post-copyright-u
display inline-block
width fit-content
padding 2px 5px
[data-theme="dark"]
#post
.post-copyright
background #07080a
text-shadow #bfbeb8 0 0 2px
border 1px solid rgb(19 18 18 / 35%)
animation flashlight 1s linear infinite alternate
.post-copyright-info
color #e0e0e4
#post
.post-copyright__title
font-size 22px
.post-copyright__notice
font-size 15px
返回顶部显示网页阅读进度
虽然 Buttrtfly 4.6 版本 就加入了内置了这个功能,可以在配置文件开启,但是内置的的滑动没有 Leonus 的丝滑,所以还是选择自己动手。
用了 Leonus 的教程,但是发现 Leonus 大佬的 js 在我这里有点小问题,所以也自己修改了一下。
这是我修改过的 js(把 childNodes 改成了 children)
window.onscroll = percent; // 执行函数
// 页面百分比
function percent() {
let a = document.documentElement.scrollTop || window.pageYOffset; // 卷去高度
let b
= Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.body.clientHeight,
document.documentElement.clientHeight
) - document.documentElement.clientHeight; // 整个网页高度
let result = Math.round((a / b) * 100); // 计算百分比
let up = document.querySelector("#go-up"); // 获取按钮
percentSpan = document.querySelector("#percent"); // 获取显示的按钮
if (result <= 95) {
up.children[0].style.display = "none";
up.children[1].style.display = "block";
percentSpan.children[0].innerHTML = result;
}
else {
up.children[1].style.display = "none";
up.children[0].style.display = "block";
}
}
打开控制台和复制提醒
按键防抖:
// 按键防抖
let TT = null; // 防抖全局计时器
/**
* 防抖函数
* @param {逻辑} fn
* @param {防抖时间} time
*/
function debounce(fn, time) {
if (TT !== null)
clearTimeout(TT);
TT = setTimeout(fn, time);
}
// 按键防抖 end --
// 检测事件并弹窗
document.onkeydown = function (e) {
// 复制
if (e.ctrlKey && e.key === "c") {
debounce(function () {
Snackbar.show({
text: "复制成功啦🌞若要转载最好保留原文链接!",
pos: "top-right",
actionText: "版权声明",
actionTextColor: "#FF8599",
onActionClick() {
location.assign("/privacy");
},
});
}, 300);
}
// 打开控制台
if (
e.keyCode == 123
|| (e.ctrlKey
&& e.shiftKey
&& (e.keyCode === 74 || e.keyCode === 73 || e.keyCode === 67))
|| (e.ctrlKey && e.keyCode === 85)
) {
debounce(function () {
Snackbar.show({
text: "开发者模式已打开🍟记住要遵循GPL协议吖!",
pos: "top-right",
showAction: false,
});
}, 300);
}
};
// 检测事件并弹窗 end --
/* Snackbar弹窗 */
.snackbar-container {
border-radius: 15px;
}
/* Snackbar弹窗 end */
Heo 加载动画
博客宽屏适配
文章双栏
在店长的教程上做了一点自己的修改
替换 [themes]\butterfly\layout\includes\mixins\post-ui.pug 为下面代码(用的是店长的,删减了一些东西)
mixin 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)
.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=title)
.recent-post-info
a.article-title(href=url_for(link) title=title)
.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'
+countBlockInIndex
a(href=full_url_for(link) + '#disqus_thread')
i.fa-solid.fa-spinner.fa-spin
when 'Disqusjs'
+countBlockInIndex
a(href=full_url_for(link) + '#disqusjs')
span.disqus-comment-count(data-disqus-url=full_url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(id=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin
a.article-content(href=url_for(link) title=title)
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index
用的是 模式二 并且将三栏修改成双栏,加上自己的一些修改
// 默认的首页卡片容器布局
.recent-posts
padding 0 15px 0 15px
height fit-content
.recent-post-item
margin-bottom 15px
background var(--recent-post-bgcolor)
overflow hidden
border-radius 15px
.recent-post-content
display flex
background var(--recent-post-bgcolor)
position relative
.recent-post-cover
display flex
background transparent
.recent-post-info
display flex
background transparent
flex-direction column
justify-content center
align-items center
.article-title
height 50%
display: flex
text-align: center
align-items: center
justify-content: flex-end
flex-direction: column
.article-title-link
color: var(--text-highlight-color)
font-size: 20px
-webkit-line-clamp: 2
line-height: 30px
margin-top: 0
font-weight: 700
margin-bottom: 0
width: 100%
-webkit-transition: .3s
-moz-transition: .3s
-o-transition: .3s
-ms-transition: .3s
transition: .3s
display: -webkit-box
overflow: hidden
-webkit-box-orient: vertical
&:hover
color: $text-hover
.recent-post-meta
height 50%
display: flex
text-align: center
flex-direction: row
align-items: center
.article-meta-wrap
color #969797
display: -webkit-box;
-webkit-box-orient: vertical
overflow: hidden
a
color: var(--text-highlight-color)
transition: all .2s ease-in-out
color #969797
&:hover
color: $text-hover
.article-content
display flex
text-align: center
flex-direction row
align-items center
justify-content center
.article-content-text
display -webkit-box
-webkit-box-orient vertical
text-overflow: ellipsis
overflow hidden
color #fff
text-shadow 1px 2px 3px #000
&.ads-wrap
display: block !important
height: auto !important
nav#pagination
width: 100%
// 卡片单元布局样式
.recent-posts
padding 0 15px 0 15px
display flex
flex-direction row
flex-wrap wrap
justify-content: space-between
.recent-post-item
border-radius 15px
overflow hidden
.recent-post-content
flex-direction column
flex-wrap nowrap
align-items center
max-height 400px
height: auto
width 100%
.recent-post-cover
width 100%
height 200px
// clip-path polygon(0 130px,0 0,100% 0,100% 130px,50% 100%)
img
height 200px
width 100%
object-fit cover
.recent-post-info
height 150px
width 100%
padding 0px 25px 5px 25px
.article-title
margin: 0px 40px
font-size 18px
.article-title-link
-webkit-line-clamp: 2;
.recent-post-meta
.article-meta-wrap
font-size 95%
-webkit-line-clamp: 3;
.article-content
position absolute
height 200px
width 100%
.article-content-text
-webkit-line-clamp 3
font-size 16px
margin 0px 25px 30px 25px
&::before
content "❝"
font-size 20px
&::after
content "❞"
font-size 20px
// 双栏布局卡片自适应适配
@media screen and (min-width:572px)
.recent-posts
.recent-post-item
width 49%
border 2px solid var(--recent-post-borderColor)
box-shadow: var(--card-box-shadow)
transition: .5s
&:hover
box-shadow: var(--card-hover-box-shadow)
border 2px solid var(--recent-post-hover-borderColor)
// 单栏布局卡片自适应适配
@media screen and (max-width:572px)
.recent-posts
.recent-post-item
width 100%
transition: .5s
.article-meta-separator,
.article-meta-wrap i,
.article-meta-link {
margin: 0 6px;
}
信息卡片头像状态
Nav 导航栏修改
原本的样式有问题,无法居中,扒了一下鱼佬的导航栏,重新改了一版
部分来自于
- 分离搜索栏与菜单栏
- 子菜单横向布局
- 网站标题部分的增强版 (自己修改了一些)
- 显示标题 (自己修改了上下滑动动画和去除 jq 依赖)
上下滑动动画
修改 [themes]\butterfly\layout\includes\header\nav.pug: (注意缩进)
nav#nav
+ #navBox
span#blog-info
a(href=url_for('/') title=config.title)
if theme.nav.logo
img.site-icon(src=url_for(theme.nav.logo))
if theme.nav.display_title
span.site-name=config.title
#menus
!=partial('includes/header/menu_item', {}, {cache: true})
+ #menuTitleBox
+ center(id="name-container")
+ a(id="page-name" href="javascript:scrollToTop()") PAGE_NAME
#nav-right
if (theme.algolia_search.enable || theme.local_search.enable)
#search-button
a.site-page.social-icon.search
i.fas.fa-search.fa-fw
#toggle-menu
a.site-page
i.fas.fa-bars.fa-fw
添加 nav.js
document.addEventListener("pjax:complete", tonav);
document.addEventListener("DOMContentLoaded", tonav);
function tonav() {
function up() {
document.querySelector("#name-container").style.transform
= "translate(-50%, 60px)";
document.querySelector("#nav .menus_items").style.transform
= "translateY(0)";
document.querySelector("#menuTitleBox").style.zIndex = "-1";
}
function scrollToTop() {
btf.scrollToDest(0, 500);
}
function updatePageName() {
const pageNameElement = document.getElementById("page-name");
if (pageNameElement) {
pageNameElement.innerText = document.title.split(" | 鹊楠の小窝")[0];
}
else {
// 使用 MutationObserver 监听 DOM 变化,确保元素加载后更新标题
const observer = new MutationObserver((mutations, observer) => {
const pageNameElement = document.getElementById("page-name");
if (pageNameElement) {
pageNameElement.innerText = document.title.split(" | 鹊楠の小窝")[0];
observer.disconnect(); // 元素找到后停止观察
}
});
// 开始观察整个文档
observer.observe(document.body, { childList: true, subtree: true });
}
}
up();
let position = window.scrollY;
window.addEventListener("scroll", function () {
let scroll = window.scrollY;
if (scroll > position) {
document.querySelector("#name-container").style.transform
= "translate(-50%, 0)";
document.querySelector("#nav .menus_items").style.transform
= "translateY(-60px)";
document.querySelector("#menuTitleBox").style.zIndex = "1";
}
else {
up();
}
position = scroll;
});
document
.querySelector("#name-container")
.addEventListener("click", function () {
scrollToTop();
});
updatePageName(); // 调用更新页面标题的函数
}
完整 css (我也挑不出来了,混在一起)
/* Nav导航栏 */
#nav #navBox {
width: 100%;
height: 60px;
position: relative;
display: flex;
align-items: center;
}
#nav .site-page:not(.child):after {
display: none;
}
.nav-fixed #nav {
backdrop-filter: blur(5px) saturate(150%);
}
.menus_item_child li:not(#sidebar-menus li) {
float: left;
border-radius: 6px !important;
-webkit-border-radius: 6px !important;
-moz-border-radius: 6px !important;
-ms-border-radius: 6px !important;
-o-border-radius: 6px !important;
}
.menus_item_child:not(#sidebar-menus ul) {
/*
left:calc(-150%)!important;这是估算值,为了保持元素居中的,如果不合适可以自己调
改为:*/
left: 50%;
translate: -50%;
}
#nav #blog-info {
overflow: visible;
flex: none;
z-index: 100;
}
#nav #blog-info a {
position: relative;
font-size: 1.2em;
}
#nav #blog-info a::before {
opacity: 0;
background-color: var(--theme-color) !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;
transform: translate(-50%, -50%);
top: 55%;
left: 50%;
width: 120%;
height: 120%;
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;
font-weight: 900;
}
#nav #blog-info a:hover::before {
opacity: 1;
scale: 1.03;
}
#nav.hide-menu .menus_items {
display: inline-block;
transition: 0.3s;
}
#nav .menus_items .menus_item,
#nav .site-page.social-icon.search {
padding: 0 10px;
margin: 0 5px;
border-radius: 10px;
transition: 0.5s;
}
#nav .menus_items .menus_item:hover,
#nav .site-page.social-icon.search:hover {
background: var(--theme-color);
box-shadow: 0 0 5px var(--theme-color);
}
#nav .menus_items .menus_item:hover a {
color: #fff;
}
#page-header.nav-fixed #nav .menus_items .menus_item:hover a,
#page-header.nav-fixed #nav .site-page.social-icon.search:hover {
color: #fff;
}
#menuTitleBox {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
#menuTitleBox #name-container {
height: 100%;
line-height: 60px;
position: absolute;
left: 50%;
transform: translateX(-50%);
transition: 0.3s;
}
#menuTitleBox #name-container::before {
opacity: 0;
background-color: var(--theme-color) !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;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
width: 100%;
height: 60%;
content: "回到顶部";
box-shadow: 0 0 5px var(--theme-color);
text-align: center;
color: white;
line-height: 36px;
font-size: 18px;
font-weight: 900;
}
#menuTitleBox #name-container:hover::before {
opacity: 1;
scale: 1.03;
cursor: pointer;
}
#nav.hide-menu #toggle-menu {
display: none !important;
}
#nav #nav-right {
z-index: 100;
position: absolute;
right: 0;
}
#nav a.site-page {
padding-bottom: 6px;
display: inline-block;
}
#nav a.site-page span {
padding-left: 4px;
}
#nav a.site-page::before {
display: none;
}
#nav #menus {
position: absolute;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
}
#nav #menus .menus_items {
transition: 0.3s;
}
#nav .menus_items .menus_item .menus_item_child {
padding: 5px;
border-radius: 15px;
}
#nav .menus_items .menus_item .menus_item_child li {
transition: 0.3s;
border-radius: 10px !important;
margin: 0 2px;
}
#nav .menus_items .menus_item .menus_item_child li:hover {
background: var(--theme-color);
}
#nav .menus_items .menus_item .menus_item_child li:hover a {
color: #fff !important;
}
@media screen and (max-width: 768px) {
/* 菜单修复 */
#nav.hide-menu #toggle-menu {
display: inline-block !important;
}
#nav #menus,
#nav #menuTitleBox {
display: none;
}
#nav #blog-info a {
font-size: 1em;
}
}
/* Nav导航栏 */
旧版本
修改 [themes]\butterfly\layout\includes\header\nav.pug
#menus
!=partial('includes/header/menu_item', {}, {cache: true})
+ #menuTitleBox
+ center(id="name-container")
+ a(id="page-name" href="javascript:scrollToTop()") PAGE_NAME
...
在 js 文件夹新建并引用这段代码
document.addEventListener("pjax:complete", tonav);
document.addEventListener("DOMContentLoaded", tonav);
function up() {
document.querySelector("#name-container").style.top = "60px";
document.querySelector("#nav.hide-menu .menus_items").style.transform
= "translateY(0)";
document.querySelector("#menuTitleBox").style.zIndex = "-1";
}
function scrollToTop() {
btf.scrollToDest(0, 500);
}
function tonav() {
up();
let position = window.scrollY;
window.addEventListener("scroll", function () {
let scroll = window.scrollY;
if (scroll > position) {
document.querySelector("#name-container").style.top = "0";
document.querySelector("#nav.hide-menu .menus_items").style.transform
= "translateY(-60px)";
document.querySelector("#menuTitleBox").style.zIndex = "1";
}
else {
up();
}
position = scroll;
});
document
.querySelector("#name-container")
.addEventListener("click", function () {
scrollToTop();
});
document.getElementById("page-name").innerText
= document.title.split(" | 鹊楠の小窝")[0];
}
最后是 css 部分 (仅实现这个功能)
#nav #blog-info {
overflow: visible;
flex: none;
z-index: 99;
}
#menuTitleBox {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
#menuTitleBox #name-container {
height: 100%;
line-height: 60px;
position: absolute;
left: 50%;
transform: translateX(-50%);
transition: 0.5s;
}
#nav.hide-menu #toggle-menu {
display: none !important;
}
#nav #nav-right {
z-index: 99;
}
@media screen and (max-width: 572px) {
/* 菜单修复 */
#nav.hide-menu #toggle-menu {
display: inline-block !important;
}
#menus {
display: none;
}
#nav #blog-info a {
font-size: 1em;
}
}
完整 css
/* Nav导航栏 */
#nav {
justify-content: space-between;
user-select: none;
}
#nav .site-page:not(.child):after {
display: none;
}
.nav-fixed #nav {
backdrop-filter: blur(5px) saturate(150%);
}
.menus_item_child li:not(#sidebar-menus li) {
float: left;
border-radius: 6px !important;
-webkit-border-radius: 6px !important;
-moz-border-radius: 6px !important;
-ms-border-radius: 6px !important;
-o-border-radius: 6px !important;
}
.menus_item_child:not(#sidebar-menus ul) {
/*
left:calc(-150%)!important;这是估算值,为了保持元素居中的,如果不合适可以自己调
改为:*/
left: 50%;
translate: -50%;
}
#nav #blog-info {
overflow: visible;
flex: none;
z-index: 99;
}
#nav #blog-info a {
position: relative;
font-size: 1.2em;
}
#nav #blog-info a::before {
opacity: 0;
background-color: var(--theme-color) !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;
transform: translate(-50%, -50%);
top: 55%;
left: 50%;
width: 120%;
height: 120%;
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;
font-weight: 900;
}
#nav #blog-info a:hover::before {
opacity: 1;
scale: 1.03;
}
#nav.hide-menu .menus_items {
display: inline-block;
transition: 0.3s;
}
#nav .menus_items .menus_item,
#nav .site-page.social-icon.search {
padding: 0 10px;
margin: 0 5px;
border-radius: 10px;
transition: 0.5s;
}
#nav .menus_items .menus_item:hover,
#nav .site-page.social-icon.search:hover {
background: var(--theme-color);
box-shadow: 0 0 5px var(--theme-color);
}
#nav .menus_items .menus_item:hover a {
color: #fff;
}
#page-header.nav-fixed #nav .menus_items .menus_item:hover a,
#page-header.nav-fixed #nav .site-page.social-icon.search:hover {
color: #fff;
}
#menuTitleBox {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
#menuTitleBox #name-container {
height: 100%;
line-height: 60px;
position: absolute;
left: 50%;
transform: translateX(-50%);
transition: 0.3s;
}
#menuTitleBox #name-container::before {
opacity: 0;
background-color: var(--theme-color) !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;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
width: 100%;
height: 60%;
content: "回到顶部";
box-shadow: 0 0 5px var(--theme-color);
text-align: center;
color: white;
line-height: 36px;
font-size: 18px;
font-weight: 900;
}
#menuTitleBox #name-container:hover::before {
opacity: 1;
scale: 1.03;
}
#nav.hide-menu #toggle-menu {
display: none !important;
}
#nav #nav-right {
z-index: 99;
}
#nav a.site-page {
padding-bottom: 6px;
display: inline-block;
}
#nav a.site-page span {
padding-left: 4px;
}
#nav a.site-page::before {
display: none;
}
#nav .menus_items .menus_item .menus_item_child {
padding: 5px;
border-radius: 15px;
}
#nav .menus_items .menus_item .menus_item_child li {
transition: 0.3s;
border-radius: 10px !important;
margin: 0 2px;
}
#nav .menus_items .menus_item .menus_item_child li:hover a {
color: #fff !important;
}
@media screen and (max-width: 768px) {
/* 菜单修复 */
#nav.hide-menu #toggle-menu {
display: inline-block !important;
}
#menus {
display: none;
}
#nav #blog-info a {
font-size: 1em;
}
}
/* Nav导航栏 */
首页分类磁贴
使用的是小冰大佬的插件
其中深色模式适配我是用了 css 变量
# 小冰分类磁贴 color_setting: text_color: var(--fl-text) text_hover_color: var(--fl-hover-text) background_color: var(--fl-bg) background_hover_color: var(--theme-color)
:root {
/* 首页分类磁贴 */
--fl-bg: #e5e5e5;
--fl-text: #000;
--fl-hover-text: #fff;
}
[data-theme="dark"] {
/* 首页分类磁贴 */
--fl-bg: #222;
--fl-text: #fff;
}
首页置顶轮播
参考
再加上自己微调
/* 首页轮播图 */
#swiper_container .blog-slider__content {
height: 250px;
}
#swiper_container a.blog-slider__title {
font-weight: bold;
}
#swiper_container .blog-slider__text {
font-size: 1em;
}
#swiper_container .swiper-button-next:after,
#swiper_container .swiper-button-prev:after {
color: var(--theme-color);
}
/* 首页轮播图 */
归档、分类、标签页美化
参考
自己修改的 css:
归档
/* 归档、标签、分类页 */
#archive,
#tag,
#category {
padding: 25px 10px;
}
.article-sort-title {
margin-top: 30px;
margin-bottom: 20px;
}
.article-sort-item::before,
.article-sort-title::before,
.article-sort-title::after {
content: none;
}
.article-sort .year {
width: 100% !important;
border-bottom: dashed 5px var(--theme-color);
font-size: 26px;
margin-top: 20px;
}
.article-sort {
border: none;
display: flex;
flex-wrap: wrap;
margin: 20px 20px;
padding: 0;
}
.article-sort-item:not(.year) {
padding: 8px 10px;
width: calc(50% - 0.8rem);
margin: 0.4rem;
border: 2px solid var(--theme-color);
border-radius: 15px;
background: var(--card-bg);
transition: 0.5s;
height: 120px;
}
.article-sort-item-a {
position: absolute;
width: 100%;
height: 100%;
}
.article-sort-item-img {
transition: 0.5s;
height: 90px;
width: 140px;
}
.article-sort-item > a > img {
border-radius: 15px;
}
.article-sort-item-title {
font-size: 22px;
padding-left: 10px;
margin: 10px 0;
line-height: 25px;
text-overflow: ellipsis;
}
.article-sort-item-title:hover {
transform: none;
}
.article-sort-meta {
height: max-content;
position: relative;
}
.article-sort-meta > .article-meta-wrap {
float: left;
}
.article-sort-meta > .article-sort-item-time {
float: right;
}
.article-sort-item-categories,
.article-sort-item-tags {
margin: 0 3px;
padding: 5px 8px;
border-radius: 25px;
border: var(--archives-categories-border);
font-size: 12px;
transition: 0.5s;
}
.article-sort-item-info > div:not(.article-sort-meta) {
display: flex;
align-items: center;
justify-content: space-between;
}
.article-sort-item > i {
position: absolute;
right: 10px;
color: var(--archives-hover-font);
}
.article-sort-description,
.article-sort-item > i {
width: 0;
opacity: 0;
overflow: hidden;
transition: 0.5s;
}
.article-sort-description {
width: 0;
height: 59px;
line-height: 59px;
vertical-align: middle;
margin: 5px 10px 0 15px;
text-overflow: ellipsis;
}
.article-sort-item:hover:not(.year) {
background-color: var(--theme-color);
box-shadow: 0 0 10px var(--theme-color);
}
.article-sort-item:hover:not(.year) {
background-color: var(--theme-color);
box-shadow: 0 0 10px var(--theme-color);
}
.article-sort-item:hover:not(.year) .article-sort-description,
.article-sort-item:hover:not(.year) > i {
width: auto;
opacity: 1;
}
.article-sort-item:hover:not(.year) .article-sort-description {
width: auto;
}
.article-sort-item:hover:not(.year) .article-sort-item-img {
transition: 0.5s;
width: 0;
}
.article-sort-item:hover:not(.year) .article-sort-item-title {
color: var(--archives-hover-font) !important;
}
.article-sort-item:hover:not(.year) .article-meta-wrap a,
.article-sort-item:hover:not(.year) .article-sort-description,
.article-sort-item:hover:not(.year) .article-sort-item-time {
color: var(--archives-hover-timeColor) !important;
}
.article-sort-item:hover:not(.year) .article-sort-item-categories {
border: var(--archives-categories-border);
}
.article-sort-item:hover:not(.year) .article-sort-item-tags {
border: var(--archives-categories-border);
}
#pagination .page-number {
border-radius: 6px;
}
@media screen and (max-width: 768px) {
.article-sort-item:not(.year) {
width: 100%;
}
.article-sort-meta > .article-meta-wrap {
display: none;
}
.article-sort-item-title {
font-size: 16px;
}
.article-sort-item-img {
width: 90px;
}
}
/* 归档、标签、分类页 end */
踩了个坑,归档页显示标签(tags)要在配置文件开启,浪费了我好多时间 😭😭
分类
只参考了一下 meuicat 大佬的页面,css 是自己手搓的 {% psw 绝对不是因为懒得改变量 (确信) %}
/* 分类 */
.category-lists ul li:before {
content: "\f550";
font-weight: 900;
cursor: pointer;
font-family: "Font Awesome 6 Free";
position: static;
border: none;
font-size: 20px;
width: auto;
height: auto;
}
.category-lists .category-list .category-list-count:before,
.category-lists .category-list .category-list-count:after {
display: none;
}
.category-lists ul {
padding: 0;
margin: 20px 0;
display: flex;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.category-lists ul li {
padding: 0.5em;
border: 1px solid #cacaca;
border-radius: 15px;
margin: 10px;
padding: 10px;
box-shadow: 0 0 8px 6px #2c2d300c;
display: flex;
justify-content: center;
align-items: center;
transition: 0.5s;
}
.category-lists ul li:hover {
box-shadow: 0 0 8px 5px var(--theme-color);
background: var(--theme-color);
border-color: var(--theme-color);
transform: scale(1.1);
}
.category-lists ul li:hover a {
color: #fff;
}
.category-lists ul li a:hover {
color: #fff !important;
}
.category-lists .category-list a {
font-size: 1.2em;
margin: 0 10px;
}
.category-lists .category-list .category-list-count {
color: #858585;
background: #e5e5e5;
padding: 2px 15px;
margin: 0;
border-radius: 10px;
}
标签
如果标签页的标签没有数字的话看这里
修改 [themes]\butterfly\scripts\helpers\page.js
const length = sizes.length - 1
source.sort(orderby, order).forEach(tag => {
const ratio = length ? sizes.indexOf(tag.length) / length : 0
const size = minfontsize + ((maxfontsize - minfontsize) * ratio)
let style = `font-size: ${parseFloat(size.toFixed(2))}${unit};`
const color = 'rgb(' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ')' // 0,0,0 -> 200,200,200
style += ` color: ${color}`
- result += `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}</a>`
+ result += `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}<span>${tag.length}</span></a>`
})
return result
/* 标签 */
.tag-cloud-list.is-center {
display: flex;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.tag-cloud-list a {
color: var(--font-color) !important;
padding: 0.5em;
border: 1px solid #cacaca;
border-radius: 15px;
margin: 10px;
padding: 10px;
box-shadow: 0 0 8px 6px #2c2d300c;
display: flex;
justify-content: center;
align-items: center;
transition: 0.3s;
}
.tag-cloud-list a:hover {
color: #fff !important;
box-shadow: 0 0 8px 5px var(--theme-color);
background: var(--theme-color);
border-color: var(--theme-color);
transform: scale(1.1);
}
.tag-cloud-list a span {
margin-left: 10px;
color: #858585;
background: #e5e5e5;
padding: 2px 15px;
border-radius: 10px;
}
.tag-cloud-list a:before {
content: "\f02b";
color: var(--tag-icon-color);
font-weight: 900;
cursor: pointer;
font-family: "Font Awesome 6 Free";
position: static;
border: none;
font-size: 20px;
width: auto;
height: auto;
margin-right: 10px;
}
右下角菜单修改
添加直达底部
修改 [themes]\butterfly\layout\includes\rightside.pug , 在最下面添加代码 (注意缩进)
button#go-down(type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500);") i.fas.fa-arrow-down
样式美化
/* 右下角菜单 */
#rightside #rightside-config-show > button,
#rightside #rightside-config-hide > button {
border-radius: 50%;
}
/* 右下角菜单 end */
持久化 url
安装 hexo-abbrlink2 插件
npm install hexo-abbrlink2 --save
修改 _config.yml 的 permalink 为
permalink: posts/:abbrlink/ # 永久链接格式
在 _config.yml 添加配置
# hexo-abbrlink2 # 持久化url abbrlink: start: 0 # 启起始文章id,默认为0 ,可以自定义,比如100
Foot 页脚
参考
我的 footer.pug 和 footer.styl
#footer-wrap
.wordcount
- let allword = totalcount(site)
span= '楠居然写了 ' + allword + ' 字'
br
if isNaN(allword)
- allword= Number(allword.replace('k', ''))
if allword< 50
span= "还在努力更新中.. 咕咕咕"
else if allword< 70
span= "好像写完一本 埃克苏佩里 的 《小王子》 了啊"
else if allword< 90
span= "好像写完一本 鲁迅 的 《呐喊》 了啊"
else if allword< 100
span= "好像写完一本 林海音 的 《城南旧事》 了啊"
else if allword< 110
span= "好像写完一本 马克·吐温 的 《王子与乞丐》了! 了啊"
else if allword< 120
span= "好像写完一本 鲁迅 的 《彷徨》 了啊"
else if allword< 130
span= "好像写完一本 余华 的 《活着》 了啊"
else if allword< 140
span= "好像写完一本 曹禺 的 《雷雨》 了啊"
else if allword< 150
span= "好像写完一本 史铁生 的 《宿命的写作》 了啊"
else if allword< 160
span= "好像写完一本 伯内特 的 《秘密花园》 了啊"
else if allword< 170
span= "好像写完一本 曹禺 的 《日出》 了啊"
else if allword< 180
span= "好像写完一本 马克·吐温 的 《汤姆·索亚历险记》 了啊"
else if allword< 190
span= "好像写完一本 沈从文 的 《边城》 了啊"
else if allword< 200
span= "好像写完一本 亚米契斯 的 《爱的教育》 了啊"
else if allword< 210
span= "好像写完一本 巴金 的 《寒夜》 了啊"
else if allword< 220
span= "好像写完一本 东野圭吾 的 《解忧杂货店》 了啊"
else if allword< 230
span= "好像写完一本 莫泊桑 的 《一生》 了啊"
else if allword< 250
span= "好像写完一本 简·奥斯汀 的 《傲慢与偏见》 了啊"
else if allword< 280
span= "好像写完一本 钱钟书 的 《围城》 了啊"
else if allword< 300
span= "好像写完一本 张炜 的 《古船》 了啊"
else if allword< 310
span= "好像写完一本 茅盾 的 《子夜》 了啊"
else if allword< 320
span= "好像写完一本 阿来 的 《尘埃落定》 了啊"
else if allword< 340
span= "好像写完一本 艾米莉·勃朗特 的 《呼啸山庄》 了啊"
else if allword< 350
span= "好像写完一本 雨果 的 《巴黎圣母院》 了啊"
else if allword< 360
span= "好像写完一本 东野圭吾 的 《白夜行》 了啊"
else
span= "好像写完一本我国著名的 四大名著 了!!!"
else
span= "还在努力更新中.. 咕咕咕"
.footer-content
div(style="font-size: 0.7rem")
span#timeDate= '载入天数...'
span= ' '
span#times= '载入时分秒...'
script(src="/static/js/duration.js")
if theme.footer.owner.enable
- var now = new Date()
- var nowYear = now.getFullYear()
if theme.footer.owner.since && theme.footer.owner.since != nowYear
.copyright!= `©${theme.footer.owner.since} - ${nowYear} By ${config.author}`
else
.copyright!= `©${nowYear} By ${config.author}`
if theme.footer.copyright
.framework-info
span= _p('footer.framework') + ' '
a(href='https://hexo.io')= 'Hexo'
span.footer-separator |
span= _p('footer.theme') + ' '
a(href='https://github.com/jerryc127/hexo-theme-butterfly')= 'Butterfly'
if theme.footer.custom_text
.footer_custom_text!=`${theme.footer.custom_text}`
#footer
position: relative
.wordcount
text-align: center
font-family: 'Noto Serif SC', -apple-system,BlinkMacSystemFont,Roboto,Segoe UI,Helvetica,Arial,serif
font-size: large
padding: 2rem 0 0 0
&::before
display: none
#footer-wrap
position: relative
padding: 40px 20px
color: var(--font-color)
text-align: center
a
color: var(--light-grey)
margin: 0 5px
&:hover
text-decoration: underline
img
max-height: 20px
&>div
margin: 10px 0
.footer-separator
margin: 0 4px
.icp-icon
padding: 0 4px
max-height: 1.4em
width: auto
vertical-align: text-bottom
首页封面样式
/* 首页修改 */
body {
background: var(--qn-body-bg);
/* 确保伪元素相对于容器定位 */
}
@media screen and (min-width: 768px) {
.page {
position: relative;
}
.page::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
/* 确保伪元素在内容的下方 */
background: var(--qn-body-bg);
background-attachment: local;
background-position: center;
background-repeat: initial;
background-image: var(--qn-bg-img);
will-change: opacity, transform, filter;
opacity: calc(1 - var(--process) * 1) !important;
filter: blur(calc(var(--process) * 10px));
transform: scale(calc(1 + var(--process) * 0.1));
/* 可选,增加平滑过渡效果 */
}
[data-theme="dark"] .page.home::before {
height: 100vh;
}
[data-theme="dark"] .page::before {
width: 100%;
height: 400px;
background: var(--qn-body-bg);
background-attachment: local;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
/* 保持背景图片的原始尺寸 */
background-image: var(--qn-bg-img);
}
}
@media screen and (max-width: 768px) {
.page::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
/* 确保伪元素在内容的下方 */
background: var(--qn-body-bg);
background-attachment: local;
background-position: center;
background-repeat: initial;
background-image: var(--qn-bg-img);
}
[data-theme="dark"] .page::before {
width: 100%;
height: 100vh;
background: var(--qn-body-bg);
background-attachment: local;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: fixed;
background-image: var(--qn-bg-img);
}
}
.article-meta-separator,
.article-meta-wrap i,
.article-meta-link {
margin: 0 6px;
}
.home #page-header:not(.not-top-img):before,
.page #page-header::before {
display: none;
}
#page-header {
background: none;
}
/* 导航栏 */
/* 封面标题 */
/* 封面副标题 */
/* 手机端Icon */
#nav a,
#page-header #site-title,
#page-header #site-subtitle,
#page-header #site_social_icons .social-icon {
color: var(--header-font-color);
}
/* 首页修改 end */
// 首页封面样式
window.addEventListener("scroll", function () {
// 获取当前页面滚动的高度
const scrollTop = window.scrollY || document.documentElement.scrollTop;
// 获取90%视口高度,即页面90vh对应的像素值
const thresholdHeight = window.innerHeight * 0.8;
// 计算scrollTop占thresholdHeight的比例,并限制在0-1之间
let scrollPercentage = scrollTop / thresholdHeight;
if (scrollPercentage > 1) {
scrollPercentage = 1;
}
else if (scrollPercentage < 0) {
scrollPercentage = 0;
}
// 输出或使用这个scrollPercentage值
console.log(scrollPercentage);
// 将这个值应用于其他操作,例如CSS变量
document.documentElement.style.setProperty("--process", scrollPercentage);
});
// 首页封面样式 end --
文章页样式
/* 文章页 */
/* 顶部封面 */
.post-bg {
position: relative;
}
#page-header:not(.not-top-img):before {
position: absolute;
width: 100%;
height: 100%;
background-color: var(--mark-bg);
content: "";
backdrop-filter: blur(8px) brightness(0.5);
}
.post #page-header {
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
}
/* 导航栏 */
.post #page-header #nav a {
color: var(--post-header-font-color);
}
.post #page-header.nav-fixed #nav a {
color: var(--post-fixed-nav-font-color);
}
/* 目录 */
#aside-content #card-toc .toc-content .toc-link.active {
border-radius: 5px;
}
/* 文章页 end */
波浪线
参考
搜索时滚动条消失恢复
我发现在打开搜索弹窗的时候会禁止滚动页面,并且滚动条会消失,造成页面宽度变化,很丑,所以就找办法给他干掉了
修改 [themes]\butterfly\source\js\search\local-search.js 大约第 7 行
window.addEventListener('load', () => {
let loadFlag = false
let dataObj = []
const $searchMask = document.getElementById('search-mask')
const openSearch = () => {
- const bodyStyle = document.body.style
- bodyStyle.width = '100%'
- bodyStyle.overflow = 'hidden'
btf.animateIn($searchMask, 'to_show 0.5s')
btf.animateIn(document.querySelector('#local-search .search-dialog'), 'titleScale 0.5s')
setTimeout(() => { document.querySelector('#local-search-input input').focus() }, 100)
if (!loadFlag) {
search()
loadFlag = true
}
...
修改网站 cdn
优化一下加载速度
cdn 大部分来自 Heo 佬
Butterfly CDN链接更改指南,替换jsdelivr提升访问速度
我的 option
option:
countup_js: /static/js/countup.js
# main_css:
# main:
# utils:
translate: https://cdn.jsdmirror.com/npm/js-heo@1.0.6/translate/tw_cn.js
# local_search:
algolia_js: https://cdn.jsdmirror.com/npm/js-heo@1.0.11/algolia/algolia.js
algolia_search_v4: https://cdn.staticfile.org/algoliasearch/4.14.3/algoliasearch-lite.umd.min.js
instantsearch_v4: https://cdn.staticfile.org/instantsearch.js/4.49.2/instantsearch.production.min.js
# docsearch_js:
# docsearch_css:
pjax: https://lib.baomitu.com/pjax/0.2.8/pjax.min.js
gitalk: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/gitalk/1.7.2/gitalk.min.js
gitalk_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/gitalk/1.7.2/gitalk.min.css
# blueimp_md5:
valine: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/valine/1.4.16/Valine.min.js
disqusjs: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/disqusjs/1.3.0/disqus.js
disqusjs_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/disqusjs/1.3.0/disqusjs.css
twikoo: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twikoo/1.4.18/twikoo.all.min.js
# waline_js:
# waline_css:
sharejs: https://lib.baomitu.com/social-share.js/1.0.16/js/social-share.min.js
sharejs_css: https://lib.baomitu.com/social-share.js/1.0.16/css/share.min.css
# mathjax:
# katex:
# katex_copytex:
# mermaid:
# canvas_ribbon:
# canvas_fluttering_ribbon:
# canvas_nest:
lazyload: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vanilla-lazyload/17.3.1/lazyload.iife.min.js
instantpage: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/instant.page/5.1.0/instantpage.min.js
typed: https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/typed.js/2.0.12/typed.min.js
# pangu:
fancybox_css_v4: https://cdn.staticfile.org/fancyapps-ui/4.0.31/fancybox.min.css
fancybox_v4: https://cdn.staticfile.org/fancyapps-ui/4.0.31/fancybox.umd.min.js
medium_zoom: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/medium-zoom/1.0.6/medium-zoom.min.js
snackbar_css: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/node-snackbar/0.1.16/snackbar.min.css
snackbar: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/node-snackbar/0.1.16/snackbar.min.js
# activate_power_mode:
# fireworks:
# click_heart:
# ClickShowText:
fontawesomeV6: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/6.0.0/css/all.min.css
# flickr_justified_gallery_js:
# flickr_justified_gallery_css:
aplayer_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css
aplayer_js: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js
meting_js: https://cdn.jsdmirror.com/npm/js-heo@1.0.12/metingjs/Meting.min.js
prismjs_js: https://cdn.jsdmirror.com/npm/prismjs@1.1.0/prism.js
prismjs_lineNumber_js: https://cdn.jsdmirror.com/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js
prismjs_autoloader: https://cdn.jsdmirror.com/npm/prismjs/plugins/autoloader/prism-autoloader.min.js
# artalk_js:
# artalk_css:
busuanzi: //npm.elemecdn.com/penndu@1.0.0/bsz.js
那年今日
基于 butterfly 主题的历史上的今天 2.0 重置版
点击文章卡片进入文章页
参考
子级a标签href避免触发父级onclick的方法,子元素阻止冒泡
看不懂的点这里
修改 [themes]\butterfly\layout\includes\mixins\post-ui.pug :
mixin postUI(posts)
each article , index in page.posts.data
+ - let link = article.link || article.path
+ .recent-post-item(onclick=`pjax.loadUrl('${url_for(link)}')`)
- .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' : ''
-
往下翻找到 .article-meta__categories 和 .article-meta__tags , 在 a 标签后的括号内添加 onclick="window.event.cancelBubble=true;" (注意,要加个空格)
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) onclick="window.event.cancelBubble=true;").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) onclick="window.event.cancelBubble=true;").article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
外挂标签之折叠栏
店长的外挂标签里的折叠栏不是很喜欢,因为用的是 details 元素实现的,没有过渡动画,所以就自己重写了一下源码和样式
示例代码 (其实和店长的没啥区别,就是少了个颜色的选项)
{% folding, 展示 %}
{% folding open, 默认打开 %}
内容
{% endfolding %}
{% folding, 默认关闭 %}
内容
{% endfolding %}
{% endfolding %}
在 [themes]\butterfly\scripts\tag 目录下新建 folding.js 文件
"use strict";
function postFolding(args, content) {
args = args.join(" ").split(",");
let style = "";
let title = "";
if (args.length > 1) {
style = args[0].trim();
title = args[1].trim();
}
else if (args.length > 0) {
title = args[0].trim();
}
if (style != undefined) {
return `<div class="details" ${style}>
<div class="collapsible"> ${title} </div>
<div class="content">
${hexo.render
.renderSync({ text: content, engine: "markdown" })
.split("\n")
.join("")}
</div>
</div>`;
}
else {
return `<div class="details">
<div class="collapsible"> ${title} </div>
<div class="content">
${hexo.render
.renderSync({ text: content, engine: "markdown" })
.split("\n")
.join("")}
</div>
</div>`;
}
}
hexo.extend.tag.register("folding", postFolding, { ends: true });
在 [themes]\butterfly\source\css\_tags 目录下新建 folding.styl 文件
Tips:如果需要修改颜色,改颜色变量就好了
.details
margin: 1em 0
border: 1px solid transparent
border-radius: 10px
transition: all 0.3s
.content
padding: 0 20px
height: 0
overflow: hidden
transition: all 0.3s
.collapsible
background-color: var(--linkDiv-bgColor)
color: white
cursor: pointer
padding: 8px
text-align: left
outline: none
font-size: 15px
border-radius: 10px
transition: all 0.3s
color: var(--linkDiv-titleColor)
display: flex
align-items: center
position: relative
user-select: none
&:hover
cursor: pointer
background-color: var(--theme-color)
color: var(--linkDiv-hoverColor)
&:after
opacity: 1
color: var(--linkDiv-hoverColor)
&:before
color: var(--linkDiv-hoverColor)
&:before
content: "\f0da"
font-weight: 900
font-family: "Font Awesome 6 Free"
font-size: 1.3em
color: var(--theme-color)
margin-right: 10px
transition: all 0.3s
&:after
content: '\002B'
color: var(--linkDiv-titleColor)
opacity: 0
font-weight: bold
float: right
position: absolute
right: 15px
transition: 0.3s
.details[open]>.collapsible:after
content: "\2212"
.details[open]>.collapsible
border-radius: 9px 9px 0 0
background-color: var(--theme-color)
color: var(--linkDiv-hoverColor)
margin-bottom: 20px
.details[open]>.collapsible:after
opacity: 1
color: var(--linkDiv-hoverColor)
.details[open]>.collapsible:before
transform: rotate(90deg)
color: var(--linkDiv-hoverColor)
.details[open]>.content
border-radius: 0 0 10px 10px
.details[open]
border: 1px solid var(--theme-color)
在自己的 js 文件夹下新建 foldMain.js 文件 (名字随意的啦) 并引用
document.querySelectorAll(".collapsible").forEach((button) => {
let heightTimeOut;
button.addEventListener("click", function () {
const details = this.parentElement;
const content = details.querySelector(".content");
const contentTranTime
= Number.parseFloat(window.getComputedStyle(content).transitionDuration) * 1000;
// 切换 open 属性
if (details.hasAttribute("open")) {
if (heightTimeOut) {
clearTimeout(heightTimeOut);
}
content.style.height = content.scrollHeight + "px";
setTimeout(() => {
details.removeAttribute("open");
content.style.height = 0 + "px"; // 收起时,重置 max-height
}, 1);
}
else {
details.setAttribute("open", "");
content.style.height = content.scrollHeight + "px"; // 展开时,设置 max-height 为内容高度
heightTimeOut = setTimeout(() => {
content.style.height = "auto";
}, contentTranTime);
}
});
});
// 页面加载时,为已展开的内容设置 max-height
document.querySelectorAll(".details[open]").forEach((details) => {
const content = details.querySelector(".content");
content.style.height = "auto";
});
引入 foldMain.js 并适配 Pjax
- <script data-pjax src="/static/js/foldMain.js?1"></script> # 外挂标签-折叠栏
说说
因为我没有服务器 😭,所以使用的是本地静态的说说,正好浮杨大佬新开发了一个说说,我就试试水
浮杨佬说说的项目地址
正常插件安装版
没有自定义需求的直接 npm 安装就好了
npm install hexo-butterfly-statictalk
鹊楠魔改免安装版
这个是我自己改给自己用的,舍弃掉了自动生成时间,可能不是那么好看和好用,可以自己改改
2024/9/2 更新
修复 bug
function arrangeItems() {
let container = document.querySelector("#talk-container");
let items = document.querySelectorAll(".talk-wrapper");
if (container && items) {
let containerWidth = container.clientWidth;
let columns = 3; // 默认列数
if (containerWidth <= 768) {
columns = 1; // 窗口宽度 <= 768px 时为单列布局
}
else if (containerWidth <= 1000) {
columns = 2; // 窗口宽度 <= 1000px 时为双列布局
}
let columnHeights = new Array(columns).fill(0); // 初始化每列高度为0
let columnWidth = containerWidth / columns; // 计算每列宽度
let margin = 20; // 间隔
// 从后往前遍历 items
for (let i = items.length - 1; i >= 0; i--) {
let item = items[i];
let itemHeight = item.offsetHeight;
let minHeight = Math.min(...columnHeights); // 获取最短列的高度
let minIndex = columnHeights.indexOf(minHeight); // 获取最短列的索引
let translateX = minIndex * columnWidth;
let translateY = minHeight;
let isLastColumn = minIndex === columns - 1;
item.style.transform = `translate(${translateX}px, ${translateY}px)`;
item.style.width = isLastColumn
? `${columnWidth}px`
: `${columnWidth - margin}px`;
columnHeights[minIndex] += itemHeight + margin;
}
container.style.height = `${Math.max(...columnHeights)}px`;
}
else {
}
}
function todo() {
if (location.pathname.startsWith("/talk")) {
arrangeItems();
window.addEventListener("scroll", arrangeItems);
window.addEventListener("resize", arrangeItems);
}
}
document.addEventListener("pjax:complete", todo);
document.addEventListener("DOMContentLoaded", todo);
新建 talk 页面
hexo new page talk
打开 source\talk\index.md 添加
--- title: 说说 date: 2024-08-10 23:25:34 type: talk ---
修改 [themes]\butterfly\layout\page.pug
extends includes/layout.pug
block content
#page
if top_img === false
h1.page-title= page.title
case page.type
when 'tags'
include includes/page/tags.pug
when 'link'
include includes/page/flink.pug
when 'categories'
include includes/page/categories.pug
+ when 'talk'
+ include includes/page/talk.pug
default
include includes/page/default-page.pug
if page.comments !== false && theme.comments && theme.comments.use
- var commentsJsLoad = true
!=partial('includes/third-party/comments/index', {}, {cache: true})
在 [themes]\butterfly\layout\includes\page 文件夹下新建 talk.pug 文件,写入
if site.data.talk
#talk-container
each i in site.data.talk
- let content = markdown(i.content)
- let time = i.time
- content = content.replace(/<img src="(.*?)"[^>]*>/g, '<a href="$1" data-fancybox="gallery" data-caption="" data-thumb="$1">$&</a>')
div.talk-wrapper
div.talk-content!= content
div.talk-footer
div.talk-time= time
在 [themes]\butterfly\source\css\_page 文件夹下新建 talk.styl 文件,写入
#talk-container
width 100%
position relative
.talk-wrapper
width 30%
position absolute
/* 默认宽度,适用于三列布局 */
box-sizing border-box
padding 1em
border-radius 10px
transform translate(0, 0)
/* 初始位置 */
transition all 0.3s
box-shadow var(--card-box-shadow)
border 1px solid var(--talk-time-bg)
.talk-content
img
display: block
margin: 0 auto 20px
max-width: 100%
-webkit-transition: filter 375ms ease-in 0.2s
-moz-transition: filter 375ms ease-in 0.2s
-o-transition: filter 375ms ease-in 0.2s
-ms-transition: filter 375ms ease-in 0.2s
transition: filter 375ms ease-in 0.2s
.talk-wrapper:hover
box-shadow var(--card-hover-box-shadow)
border-color var(--theme-color)
.talk-content h1,
.talk-content h2,
.talk-content h3,
.talk-content h4,
.talk-content h5,
.talk-content h6
color var(--font-color)
.talk-footer
border-top 2px dotted var(--talk-time-bg)
padding 5px
display flex
justify-content flex-end
.talk-time
padding 3px 7px
background var(--talk-time-bg)
font-size .7rem
border-radius 25px
margin-top 5px
.talk-time::before
content "\f017"
font-weight 900
font-family "Font Awesome 6 Free"
margin-right 5px
@media (max-width: 768px)
.talk-wrapper
width 100% !important
/* 单列布局 */
在自己的 js 文件夹下新建 talk.js 写入
function arrangeItems() {
let container = document.querySelector("#talk-container");
let items = document.querySelectorAll(".talk-wrapper");
if (container && items) {
let columns = 3; // 默认列数
let containerWidth = container.clientWidth;
if (containerWidth <= 768) {
columns = 1; // 窗口宽度 <= 768px 时为单列布局
}
else if (containerWidth <= 1000) {
columns = 2; // 窗口宽度 <= 1000px 时为双列布局
}
let columnHeights = new Array(columns).fill(0); // 初始化每列高度为0
let columnWidth = containerWidth / columns; // 计算每列宽度
let margin = 20; // 间隔
items.forEach((item, index) => {
// 获取当前元素的高度
let itemHeight = item.offsetHeight;
let minHeight = Math.min(...columnHeights); // 获取最短列的高度
let minIndex = columnHeights.indexOf(minHeight); // 获取最短列的索引
// 计算transform位置
let translateX = minIndex * columnWidth;
let translateY = minHeight;
// 判断是否为最后一列
let isLastColumn = minIndex === columns - 1;
// 设置transform位置
item.style.transform = `translate(${translateX}px, ${translateY}px)`;
item.style.width = isLastColumn
? `${columnWidth}px`
: `${columnWidth - margin}px`; // 最后一列不减去间隔
// 更新列高度
columnHeights[minIndex] += itemHeight + margin; // 加上底部间距
});
// 更新容器的高度以适应所有列
container.style.height = `${Math.max(...columnHeights)}px`;
}
else {
}
}
if (location.pathname.startsWith("/talk")) {
window.onload = arrangeItems();
// 滚动后重新布局
window.addEventListener("scroll", arrangeItems);
// 当窗口大小改变时重新布局
window.addEventListener("resize", arrangeItems);
}
并在配置文件引入该 js
bottom: - <script data-pjax src="/static/js/talk.js?1"></script> # 说说
最后在 source\_data 文件夹下新建 talk.yml
参考写法
- content: |
1
test
# test1


time: 2024-09-01
- content: |
2
# test1
time: 2024-09-01
关于我
直接从鱼那里搬过来的关于页面,做了一点点自己的修改
- 删除捐赠
楠的破烂博客还敢开捐赠?! - 修改 51LA 的统计数据为 Hexo 自带数据
统计数据部分
#statistic
div
span 文章数量
span= site.posts.length
div
span 运行时间
span#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
div
span 访客数量
span#busuanzi_value_site_uv
div
span 总访问量
span#busuanzi_value_site_pv
div
span 最近更新
span#last-push-date(data-lastPushDate=date_xml(Date.now()))
修改国内不蒜子统计平台
来自杜老师的教程
压缩静态资源
来自 空梦大佬
Todo
自己用 md 写的太丑辣,懒得动脑,直接拿 亦小封 佬的用
不过佬的瀑布流代码在我这里有点小问题,我就用我自己的屎山代码代替了))
外挂标签之外链卡片
参考洪哥的样式
做出了自己的修改
修改 [themes]\butterfly\scripts\tag\link.js :
function link(args) {
args = args.join(" ").split(",");
let title = args[0];
let sitename = args[1];
let link = args[2];
let isLocalLink = link.startsWith("/");
let tipsText = isLocalLink
? "✅此为本站站点,可以放心食用~"
: "❗这是个站外网站呢,不保证站点的可用性和安全性哟~";
let imgUrl = isLocalLink
? "https://tuchuang.voooe.cn/images/2024/01/29/logo_icon.png"
: "https://api.iowen.cn/favicon/"
+ link.replace(/^https?:\/\//i, "")
+ ".png";
let targetAttr = isLocalLink ? "" : 'target="_blank"';
return `<a class="tag-Link" ${targetAttr} href="${link}">
<div class="tag-link-tips">${tipsText}</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 });
修改 [themes]\butterfly\source\css\_tags\link.styl :
#article-container
.tag.link
text-align center
a
&.link-card
margin 0.25rem auto
background #f6f6f6
display inline-flex
align-items center
cursor pointer
text-align center
min-width 200px
max-width 361px
color #444
border-radius 12px
text-decoration none
&:hover
box-shadow 0 4px 8px 0 rgba(0, 0, 0, 0.1)
div
&.left
width 48px
height 48px
margin 12px
overflow hidden
flex-shrink 0
position relative
i
font-size 32px
line-height 48px
margin-left 4px
img
display block
position absolute
border-radius 2px
top 50%
left 50%
transform translate(-50%, -50%)
&.right
overflow hidden
margin-right 12px
p
margin 0
&.text
font-weight bold
&.url
flex-shrink 0
color rgba(68, 68, 68, 0.65)
font-size 13px
@media screen and (max-width: 425px)
#article-container
a
&.link-card
max-width 100%
@media screen and (max-width: 375px)
#article-container
a
&.link-card
width 100%
#article-container a.link-card div.left,
#article-container a.link-card div.right
pointer-events none
[data-theme="dark"]
#article-container
a
&.link-card
filter brightness(0.7)
img
filter brightness(1)
评论样式
参考了 Ariasaka 和 店长 的一些样式
css
/* 评论 */
#twikoo .tk-admin {
position: fixed !important;
right: -50%;
z-index: 999;
}
#twikoo .tk-admin.__show {
left: 100% !important;
transform: translateX(-100%);
}
.tk-input.el-textarea textarea {
min-height: 120px !important;
}
.tk-content {
border-radius: 2px 10px 10px 10px;
background: #e5e5e5;
padding: 5px 20px;
color: #000;
}
.tk-content-expand {
max-width: 90%;
}
.tk-comment .tk-submit .tk-avatar,
.tk-replies .tk-avatar {
width: 2.5rem !important;
height: 2.5rem !important;
}
.tk-comment.tk-master .tk-avatar.tk-clickable.tk-has-avatar {
margin: 0 0 0 1rem !important;
}
.tk-comment .tk-submit .tk-avatar .tk-avatar-img,
.tk-replies .tk-avatar .tk-avatar-img {
height: 2.5rem !important;
}
.tk-comment.tk-master .tk-content {
border-radius: 10px 2px 10px 10px;
}
.tk-comment.tk-master,
.tk-comment.tk-master .tk-row,
.tk-comment.tk-master .tk-extras {
flex-direction: row-reverse;
width: 100%;
}
.tk-comment.tk-master .tk-main {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.twikoo .el-button--primary.is-disabled,
.twikoo .el-button--primary.is-disabled:active,
.twikoo .el-button--primary.is-disabled:focus,
.twikoo .el-button--primary.is-disabled:hover {
background: #fb85999e !important;
}
.el-button--primary {
background-color: var(--theme-color) !important;
border-color: var(--theme-color) !important;
}
.el-button--primary:focus,
.el-button--primary:hover {
background: #fb8599d9 !important;
border-color: #fb8599d9 !important;
}
.twikoo .el-input__inner:focus,
.twikoo .el-textarea__inner:focus,
.el-button--primary:focus,
.el-button--primary:hover {
border-color: #fb8599d9 !important;
}
.tk-icon.__comments,
.tk-action-icon.tk-action-icon-solid,
.tk-action-icon,
.tk-action-count {
color: var(--theme-color) !important;
}
.tk-tag-green.tk-tag-green {
background-color: var(--theme-color);
border: none;
border-radius: 5px;
color: #fff;
margin: 0 10px;
}
#article-container strong:not(strong:has(code)) {
background: linear-gradient(
rgba(255, 51, 184, 0.15),
rgba(255, 51, 184, 0.15)
) no-repeat bottom / 100% 30%;
}
a.tk-ruser {
color: #000;
margin: 0 5px;
font-weight: 900;
font-size: 15px;
}
.tk-collapse-wrap,
.tk-expand-wrap {
box-shadow: 0 0 5px;
margin-top: 10px;
border-radius: 10px;
overflow: hidden;
transition: 0.3s;
}
.tk-collapse-wrap:hover,
.tk-expand-wrap:hover {
border-color: var(--theme-color);
}
.tk-expand {
font-size: 12px;
}
.tk-expand-wrap .tk-expand:hover {
background-color: var(--theme-color);
color: #fff;
}
/* 设置文字内容 :nth-child(1)的作用是选择第几个 */
.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
1
):before {
content: "输入您的昵称🍟";
}
.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
2
):before {
content: "收到回复将会发送到您的邮箱,使用QQ邮箱自动获取头像📧";
}
.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
3
):before {
content: "可以通过昵称访问您的网站🔗";
}
/* 当用户点击输入框时显示 */
.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::before,
.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::after {
display: block;
}
/* 主内容区 */
.el-input.el-input--small.el-input-group.el-input-group--prepend::before {
/* 先隐藏起来 */
display: none;
/* 绝对定位 */
position: absolute;
/* 向上移动60像素 */
top: -60px;
/* 文字强制不换行,防止left:50%导致的文字换行 */
white-space: nowrap;
/* 圆角 */
border-radius: 10px;
/* 距离左边50% */
left: 50%;
/* 然后再向左边挪动自身的一半,即可实现居中 */
transform: translate(-50%);
/* 填充 */
padding: 14px 18px;
background: #444;
color: #fff;
}
/* 小角标 */
.el-input.el-input--small.el-input-group.el-input-group--prepend::after {
display: none;
content: "";
position: absolute;
/* 内容大小(宽高)为0且边框大小不为0的情况下,每一条边(4个边)都是一个三角形,组成一个正方形。
我们先将所有边框透明,再给其中的一条边添加颜色就可以实现小三角图标 */
border: 12px solid transparent;
border-top-color: #444;
left: 50%;
transform: translate(-50%, -48px);
}
/* 评论 end */

评论区
评论加载中...