点击查看更新记录

更新记录

2020-12-09:内测版v0.01

  1. 起草教程,编写TO DO
  2. 收集相应参考方案

2020-12-10:内测版v0.02

  1. 完成字体引入教程
  2. 完成版块显隐及透明度修改教程

2020-12-11:内测版v0.03

  1. 新增阿里图标库引入方案。

2020-12-12:内测版v0.04

  1. 新增侧栏按钮缩进思路。
  2. 修改关于阿里图标库引入的一些描述。
  3. 新增TODO,将阿里图标库symbol引入方案写成外挂标签形式。
  4. 为了便于阅读,将所有内容都做了折叠隐藏,点开才能观看。

2020-12-12:内测版v0.05

  1. 本帖移除阿里矢量图标库方案
  2. 将阿里矢量图标库引入方案转至单独帖

2021-04-20:新增图片模糊渐变清晰动画

  1. css3动画写法。新增图片模糊渐变清晰动画。
  2. 群友的要求真的是各种各样奇奇怪怪的。
  3. butterfly_v3.7.5+自带该功能。无需添加。

2021-05-11:新增鼠标指针样式修改

  1. 新增鼠标指针样式修改。

2021-06-04:新增站点标签title动态修改

  1. 新增站点标签title动态修改。
点击查看参考教程
参考方向教程原贴
谷歌字体API用法谷歌字体API文档
参考了font-display的用法font-display的用法
参考了stylus语法Stylus官方文档
参考了一图流实现方法小冰博客-教程:Butterfly主题的一图流和视频流背景修改方法
参考了动态背景的实现方案小冰博客-butterfly随机背景最简单的写法
参考了各类样式效果及css源码内容小康博客-Hexo博客之butterfly主题优雅魔改系列(持续更新)
参考了夜间模式的整合思路evrstr-在Hexo的Butterfly主题使用Twikoo评论配置黑暗模式

魔改样式引入

点开查看魔改样式引入

引入魔改样式的方法很简单,自建一个css文件,然后引入即可。
butterfly主题为例。可以在[Blogroot]\themes\butterfly\source\css\目录下新建custom.css文件,然后在[Blogroot]\_config.butterfly.ymlinject配置项中引入自定义样式文件。

inject:
head:
- <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">

其中media="defer" onload="this.media='all'"是异步加载配置项,确保自定义样式会在页面加载完成后才继续渲染。如果没有需求或效果不好可以不加这个

当然也可以采用CSS整合方案,关于这部分内容可以参考站内教程:Hexo博客静态资源加速

接下来的魔改内容,如果没有特别声明,都默认是写入custom.css中。

字体样式修改

字体样式的修改需要先引入相应的字体文件,此处推荐使用:

  1. 打开谷歌字体库,

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

  3. 首先需要引入样式,在custom.css中写入字体样式API

    @import url('https://fonts.googleapis.com/css2?family=Zhi+Mang+Xing&display=swap');
  4. 为了便于预览,我们可以试试直接在页面按F12,然后在控制台中进行调试。

  5. 当然,在控制台添加的样式是暂时的,我们在预览觉得满意后,就可以把font-family写进来custom.css

    @import url('https://fonts.googleapis.com/css2?family=Zhi+Mang+Xing&display=swap');

    h1#site-title {
    font-family: 'Zhi Mang Xing', cursive;
    }

    这个font-family的写法表示主字体用'Zhi Mang Xing',若字体包内没有相应字体,则使用备用字体cursive,备用字体可以写多个。形如:

    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif

    当页面加载时,若主字体包内没有相应的字体支持,会依次向下寻找。

  6. 字体样式API实际上可以拆解成如下类型:

    • 谷歌字体API:https://fonts.googleapis.com/css2
    • 字体样式:family=Zhi+Mang+Xing
    • font-display属性:display=swap

      font-display属性是一个新的CSS属性,可以让自定义字体的显示更加顺滑,取值有:

      1. auto:默认值。使用自定义字体的文本会先被隐藏,直到字体加载结束才会显示。
      2. swap:后备文本立即显示直到自定义字体加载完成后再使用自定义字体渲染文本。
      3. fallback:需要使用自定义字体渲染的文本会在较短的时间(100ms according to Google )不可见,如果自定义字体还没有加载结束,那么就先加载无样式的文本。一旦自定义字体加载结束,那么文本就会被正确赋予样式。
      4. optional:效果和fallback几乎一样,都是先在极短的时间内文本不可见,然后再加载无样式的文本。不过optional选项可以让浏览器自由决定是否使用自定义字体,而这个决定很大程度上取决于浏览器的连接速度。如果速度很慢,那你的自定义字体可能就不会被使用。

      此处得益于谷歌字体API自动引入了该属性,我们无需再添加。

    • 更多API参数可以参考谷歌字体API文档
  1. 首先需要下载心仪的字体。此处推荐一个免费的字体库网站,支持在线转换预览和免费字体包下载。

    这里我选择的一款叫做甜甜圈海报字体。根据页面按钮找到字体下载。得到相应的字体文件。为了方便起见,我将其重命名为Candy.ttf

    不一定是ttf后缀,其他后缀也是完全正常的,例如eot、otf、fon、font、ttc、woff、woff2等.

  2. 将下载好的字体包放到本地文件夹下,这里推荐新建一个fonts文件夹。例如我是放在[Blogroot]\themes\butterfly\source\fonts\目录下。

  3. 在自定义样式custom.css中引入字体包:

    @font-face{
    font-family:'Candyhome' ; /* 字体名自定义即可 */
    src:url('/fonts/Candy.ttf'); /* 字体文件路径 */
    font-display : swap;
    }
  4. 为了便于预览,我们可以试试直接在页面按F12,然后在控制台中进行调试。

  5. 当然,在控制台添加的样式是暂时的,我们在预览觉得满意后,就可以把font-family写进来custom.css

    @font-face{
    font-family:'Candyhome' ; /* 字体名自定义即可 */
    src:url('/fonts/Candy.ttf'); /* 字体文件路径 */
    font-display : swap;
    }

    h1#site-title {
    font-family: 'Candyhome', sans-serif;
    }

关于font-display属性,这是一个新的CSS属性,可以让自定义字体的显示更加顺滑,取值有:

  1. auto:默认值。使用自定义字体的文本会先被隐藏,直到字体加载结束才会显示。
  2. swap:后备文本立即显示直到自定义字体加载完成后再使用自定义字体渲染文本。
  3. fallback:需要使用自定义字体渲染的文本会在较短的时间(100ms according to Google )不可见,如果自定义字体还没有加载结束,那么就先加载无样式的文本。一旦自定义字体加载结束,那么文本就会被正确赋予样式。
  4. optional:效果和fallback几乎一样,都是先在极短的时间内文本不可见,然后再加载无样式的文本。不过optional选项可以让浏览器自由决定是否使用自定义字体,而这个决定很大程度上取决于浏览器的连接速度。如果速度很慢,那你的自定义字体可能就不会被使用。

关于font-family的写法,此处表示主字体用'Candyhome',若字体包内没有相应字体,则使用备用字体sans-serif,备用字体可以写多个。形如:

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif

当页面加载时,若主字体包内没有相应的字体支持,会依次向下寻找。

版块显隐修改

点击查看板块显隐教程

有时候会遇到一些不希望显示的内容,但用不知道要怎么关掉它。那么干脆简单粗暴点,直接把它隐藏了。
同样是使用F12打开控制台,使用左上角的网页元素选择器,定位到希望隐藏的元素上,获取他的id或者class,然后在custom.css中使用隐藏属性,此处假设我要隐藏idhidden_element的div元素:

#hidden_element{
display: none!important;
visibility: hidden;
opacity: 0;
/* 三条属性择一即可 */
}

以上三条属性的区别在于:

  1. display:none

    display:none可以隐藏所有的信息,包括div下的文本和图片,同时被隐藏的内容不占用空间。

  2. visibility: hidden

    visibility属性规定元素是否可见。这个属性指定是否显示一个元素生成的元素框。这意味着元素仍占据其本来的空间,不过可以完全不可见。除了hidden以外还有两个取值:

    • visible 默认值,元素可见。
    • hidden 元素不可见。
    • collapse 当在表格元素中使用时,此值可删除一行或一列,但是它不会影响表格的布局。被行或列占据的空间会留给其他内容使用。如果此值被用在其他的元素上,会呈现为hidden
  3. opacity: 0

    opacity属性决定元素的透明度。
    这意味着将opacity设为0只能从视觉上隐藏元素。而元素本身依然占据它自己的位置并对网页的布局起作用。

透明度修改(含一图流方案)

点击查看透明度修改教程

对于页面的透明度配置有多种方案,此处讨论三种。

  1. background:rgba(255,255,255,0.5)

    background属性的配置应该算是我们最期望的效果了,它只会使被添加了的该属性的页面元素背景变得透明,而不会对这一页面元素下的其他元素(包括div、span、p、a等任何标签)有任何影响。一般用来对文章内容或页面卡片添加透明度。这样可以保证字体不会变透明

    /* 首页文章卡片 */
    #recent-posts > .recent-post-item{
    background:rgba(255, 255, 255, 0.9);
    }
    /* 首页侧栏卡片 */
    .card-widget{
    background:rgba(255, 255, 255, 0.9)!important;
    }
    /* 文章页面正文背景 */
    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);
    }
  2. opacity:0.5

    opacity定义的是全局的透明度,会影响添加该属性的页面元素及其下属元素。

    #footer{
    opacity: 0.5;
    }
  3. background:transparent

    这一属性会让定义了该属性的页面元素背景变完全透明,但不会影响下属元素,效果等同于background:rgba(255,255,255,0)
    实例:定义头图或页脚全透明以实现一图流

    /* 页脚透明 */
    #footer{
    background: transparent!important;
    }
    /* 头图透明 */
    #page-header{
    background: transparent!important;
    }
    /*top-img黑色透明玻璃效果移除,不建议加,除非你执着于完全一图流或者背景图对比色明显 */
    #page-header.post-bg:before {
    background-color: transparent!important;
    }
    /*夜间模式伪类遮罩层透明*/
    [data-theme="dark"]
    #footer::before{
    background: transparent!important;
    }
    [data-theme="dark"]
    #page-header::before{
    background: transparent!important;
    }

侧栏按钮缩进

含Aplayer全局吸底音乐标签伸缩实例

点击查看侧栏按钮缩进教程

在魔改过程中应该会遇到想要让一个按钮变成侧栏伸缩的形式,不需要它时就所在侧栏里,需要时才弹出。这点可以通过fixed定位属性和hover选择器做到。

  1. fixed定位会使得该元素的位置相对于浏览器窗口而固定,即使窗口滚动,它也不会移动。例如我希望idfixedElement的按钮牢牢固定在右下角,可以定义它的定位属性:

    #fixedElement{
    position: fixed;
    width: 60px
    /* 假定宽度是60px */
    bottom: 60px;
    /* 定义元素下边框与浏览器下边框的距离 */
    left: -30px;
    /* 定义元素左边框与浏览器左边框的距离 */
    /* 此时效果上此按钮应当缩进侧栏一半 */
    }
  2. hover选择器定义鼠标悬停到该元素上时的样式,例如,我希望鼠标悬停在上述这个idfixedElement的按钮时,这个按钮能够完全显示。

    #fixedElement:hover{
    left: 0px;
    }
  3. 应用实例
    我们可以尝试隐藏Aplayer的全局吸底音乐标签,在[Blogroot]\themes\butterfly\source\css\custom.css中添加如下内容:

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
    left: -66px !important;
    /* 默认情况下缩进左侧66px,只留一点箭头部分 */
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
    left: 0 !important;
    /* 鼠标悬停是左侧缩进归零,完全显示按钮 */
    }

夜间模式或阅读模式修改

点击查看夜间模式或阅读模式修改教程
  1. 此处仅针对Butterfly主题。如果熟悉stylus,可以直接修改[Blogroot]\themes\butterfly\source\css\_mode\darkmode.styl来新增夜间模式样式。例如twikoo的夜间模式样式适配(详情请参考@evrstr制作的Butterfly主题下Twikoo评论夜间模式样式)

  2. 当然此帖依然讨论的是使用CSS。Butterfly主题使用[data-theme='dark']来界定夜间模式和日间模式。使用.read-mode的类来界定阅读模式。
    可以简单的认为,当切换为夜间模式或者阅读模式时,会给页面整体套上一个壳,而我们要做的就是对这个壳底下的元素重新定义样式。此处以对文字页和侧栏的设置为例:
    修改[Blogroot]\themes\butterfly\source\css\custom.css

    • 夜间模式:
      [data-theme="dark"]
      #aside-content .card-widget{
      background: rgba(0, 0, 0, 0.5)!important;
      }
      [data-theme="dark"]
      div#post{
      background: rgba(0, 0, 0, 0.5)!important;
      }
    • 阅读模式:
      .read-mode #aside-content .card-widget{
      background: rgba(158, 204, 171, 0.5)!important;
      }
      .read-mode div#post{
      background: rgba(158, 204, 171, 0.5)!important;
      }
    • 夜间模式下的阅读模式:
      [data-theme="dark"]
      .read-mode #aside-content .card-widget{
      background: rgba(0, 0, 0, 0.5)!important;
      color: #ffffff;
      }
      [data-theme="dark"]
      .read-mode div#post{
      background: rgba(0, 0, 0, 0.5)!important;
      color: #ffffff;
      }

随机背景或banner效果

点击查看随机背景或banner效果教程
  1. (此方案参考自冰老师的随机背景方案)随机背景或banner可以通过js进行修改。butterfly主题使用id为web_bg的div来存放背景图片,使用id为page-header的div来存放banner图片。只需要通过重设这个div的背景图片属性就可以替换背景图片。

    此方案必须要先在主题配置文件_config.butterfly.yml中配置了默认背景才能生效。最终效果为切换页面或刷新页面时,随机替换当前背景。

  2. [Blogroot]\themes\butterfly\source\js\目录下新建randombg.js

    //随机背景图片数组,图片可以换成图床链接,注意最后一条后面不要有逗号
    var backimg =[
    "url(/img/bg1.JPG)",
    "url(/img/bg2.jpg)",
    "url(/img/bg3.jpg)",
    "url(/img/bg4.jpg)"
    ];
    //获取背景图片总数,生成随机数
    var bgindex =Math.ceil(Math.random() * (backimg.length-1));
    //重设背景图片
    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.ceil(Math.random() * (bannerimg.length-1));
    //重设banner图片
    document.getElementById("page-header").style.backgroundImage = bannerimg[bannerindex];
  3. [Blogroot]\_config.butterfly.yml引入randombg.js

    inject:
    head:
    bottom:
    - <script async data-pjax src="/js/randombg.js"></script>

    其中async属性提供异步加载减少Html阻塞。

图片模糊渐变清晰

点击查看图片模糊渐变清晰方案
  1. css3中有个filter滤镜属性,可以提供高斯模糊滤镜。而animation动画属性支持给网页添加动画效果。把他们结合一下就可以了。
  2. 此处以给网页头图和网页背景添加图片渐变模糊为例,在custom.css中添加
    /*10s为加载动画的时间,1为加载动画的次数,ease-in-out为动画效果*/
    #page-header,
    #web_bg {
    -webkit-animation: imgblur 10s 1 ease-in-out;
    animation: imgblur 10s 1 ease-in-out;
    }
    @keyframes imgblur {
    0% {
    filter: blur(5px);
    }
    100% {
    filter: blur(0px);
    }
    }
    /*适配使用-webkit内核的浏览器 */
    @-webkit-keyframes imgblur {
    0% {
    -webkit-filter: blur(5px);
    }
    100% {
    -webkit-filter: blur(0px);
    }
    }
  3. 考虑到还有部分读者的需求是指定页面,可以在对应文章或者page的markdown文件里写css代码:
    {% raw %}
    <style>
    /*10s为加载动画的时间,1为加载动画的次数,ease-in-out为动画效果*/
    #page-header,
    #web_bg {
    -webkit-animation: imgblur 10s 1 ease-in-out;
    animation: imgblur 10s 1 ease-in-out;
    }
    @keyframes imgblur {
    0% {
    filter: blur(5px);
    }
    100% {
    filter: blur(0px);
    }
    }
    /*适配使用-webkit内核的浏览器 */
    @-webkit-keyframes imgblur {
    0% {
    -webkit-filter: blur(5px);
    }
    100% {
    -webkit-filter: blur(0px);
    }
    }
    </style>
    {% endraw %}

鼠标指针样式替换

点击查看鼠标指针样式替换

鼠标指针的样式替换原理其实就是重设对应版块的cursor属性,在这之前我们需要准备好相应的.cur文件,即静态鼠标指针图标。(目前还不支持.ani后缀的动态鼠标指针图标)。可以从一些美化网站找到鼠标指针图标。例如店长就是在一个Windows美化网站上找的。

如果下载下来的是.ani格式,然后又实在喜欢这个指针图标,那么可以考虑动态转静态,使用Axialis cursorworkshop这款软件,导入.ani文件后抽取喜欢的那一帧,导出为静态图标。

你甚至还可以直接在阿里图标库里找到心仪的图标以后,在convertio上将png转为cur文件。不过根据店长试用效果来看,因为png文件转的cur文件较大,很多时候图标都加载不出来。最好事先降低一下图标的分辨率到合适的程度。

然后就是正文了,依然是在custom.css中进行修改。用F12控制台左上方的箭头按钮获取对应块元素的id或者css。然后修改对应的cursor属性。cur图标的路径引用方式和背景图片的引用方式是一样的,都支持图床外链和本地相对链接。以下是一些常用位置的更改示例。读者还可以自己定义更多块元素的具体图标。

/* 全局默认鼠标指针 */
body,
html{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/arrow.cur'),auto !important;
}
/* 悬停图片时的鼠标指针 */
img{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/btn.cur'),auto !important;
}
/* 选择链接标签时的鼠标指针 */
a:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/link.cur'),auto;
}
/* 选中输入框时的鼠标指针 */
input:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/input.cur'),auto;
}
/* 悬停按钮时的鼠标指针 */
button:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/btn.cur'),auto;
}
/* 悬停列表标签时的鼠标指针 */
i:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/link.cur'),auto;
}
/* 悬停页脚链接标签(例如页脚徽标)时的鼠标指针 */
#footer-wrap a:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/hf.cur'),auto;
}
/* 悬停页码时的鼠标指针 */
#pagination .page-number:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/i.cur'),auto;
}
/* 悬停菜单栏时的鼠标指针 */
#nav .site-page:hover{
cursor: url('https://cdn.jsdelivr.net/npm/akilar-candyassets/cur/hf.cur'),auto;
}

站点动态title

点击查看站点动态title教程

站点动态title是通过js监测是否聚焦于当前页面,从而替换标签显示内容。

  1. [Blogroot]\themes\butterfly\source\js\目录下新建diytitle.js
    //动态标题
    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);
    }
    });
  2. [Blogroot]\_config.butterfly.ymlinject配置项添加引入,此处因为这是个独立的js,而且体量极小,所以可以添加async异步加载标签:
      inject:
    head:
    # - <link rel="stylesheet" href="/xxx.css">
    bottom:
    # - <script src="xxxx"></script>
    + - <script async src="/js/diytitle.js"></script>

TO DO

魔改样式引入方案

字体样式修改

版块显隐修改

透明度修改

侧栏按钮缩进方案

夜间模式或阅读模式修改

随机背景或banner效果

图片模糊渐变清晰效果

鼠标指针图标替换

站点标签title动态变化