跳过正文

Hugo + Blowfish|自装样式记录

·4402 字·9 分钟· loading ·
目录

本文主要是想记录一下自己装修博客的过程,这次搭博客真的蛮快的,一天之内我就搞得七七八八了,这得归功于网上这么多的分享记录,所以我也来贡献一份自己的记录啦。

搭建博客
#

我已经确定博客框架选择Hugo,因为最多人用(虽然我也不太确定,但是身边人确实大部分都用的是Hugo),这样Debug方便,抄别人的装修作业也很方便(x)

挑选主题
#

我个人觉得搭建博客第一步就是先选主题,因为每个主题都会有自己的教程,跟着主题的官方教程走,出错的概率非常小。我挑选主题时最看重三个要素:

  1. 使用人数多不多。 这个优先级最高,因为虽然我是程序员,但我也不太喜欢花太多时间和精力在Debug或者自己造轮子上面。如果选择很多人都在用的主题,自己遇到的问题大概率别人已经遇到并解决了。于是,我是在Best Hugo Themes这个网站上挑选的,因为它有显示GitHub Star数和上次更新时间,哪些主题是很成熟的、更新勤快的主题,十分一目了然。
  2. 完美支持Markdown,并能优雅美丽地展示Markdown。 有些博客虽然很美丽,但只会美丽地展示一部分的Markdown元素,这些博客都会直接被我pass掉。
  3. 有提供足够的自定义空间。 我知道受欢迎的博客肯定也是经过多次设计迭代、被市场证明的美丽博客,但是不可能要求它全部内容都符合自己的审美,所以肯定是要自己改动一部分的。我也不希望直接去修改主题的源代码,这样要是我想更新主题的话不方便。我会去查看心仪主题的配置文档,看它们提供哪些配置选项、有哪些可以自定义等等。

经过多番对比挑选,最后我的决赛名单剩下三位选手:

  1. Stack
  2. Hugo Apéro
  3. BlowFish

第一位选手的强悍实力和美貌程度无需我多言,但我不太爱三栏式布局,所以一直在纠结,以及我希望首页展示一张美丽图片而不是直接展示文章列表,Stack似乎是做不到的。除非我再自己设计一个主页加上去,点击按钮再真正进入Stack博客,略有点麻烦了,挂起先。

第二位选手没有其他选手那么出名,但是它真的十分美丽……真的太美了!!!我第一眼就爱上了!!!有点奇怪的是这个博客主题似乎只流行于一些小圈子,当我谷歌搜索这个主题时,发现几乎都是一些研究学者、教授或者科学家在用(擦汗)最终因为这个博客提供的功配置项比较少,支持的Markdown也有限,所以被我pass掉了。但是由于它真的太美了,所以本站参考了它的配色、插图和首页布局,在这里谢谢设计者Desirée De Leon 🦒

第三位选手也是位很强大的选手,虽然我也不太喜欢它的首页,但它提供自定义首页的选项,十分好!也完美支持Markdown!虽然UI不太符合我的审美,看起来像是技术宅男最爱的那种主题,配了很多萌妹插图的那种,呃脑海里已经闪过无数个画面、、、但是主题也提供了这方面的定制选项。所以我只需要修改一下配色、加个首页,这个工作量我能接受,因此最后就选择了BlowFish。

版本和开发工具
#

写此博客时,我的配置如下:

Hugo版本:v0.145.0

BlowFish版本:2.84.0

命令行工具:Warp

开发工具:Webstorm

操作系统:MacOS

如果直接复制我文中提到的代码后出错了,记得查看版本是否一致哦^ ^

装修博客
#

搭建首页
#

我把首页文件放在layouts/index.html,BlowFish文档中说自定义首页文件要放在layouts/partials/home/custom.html,我实验了一下,效果是一样的。以下是我的首页代码:

展开代码/收起
{{ define "main" }}  
<main class="w-full mt-20 px-6">  
    <section class="flex flex-col lg:flex-row items-center justify-between gap-16 max-w-6xl mx-auto">  
  
        <!-- 图片区块 -->  
        <div class="lg:w-1/2 order-first lg:order-none shrink-0">  
            {{ with .Params.images }}  
            {{ range first 1 . }}  
            <img width="650" src="{{ . }}" alt="Background"  
                 class="mx-auto rounded-xl shadow-md object-contain" />  
            {{ end }}  
            {{ end }}  
        </div>  
  
        <!-- 文字区块 -->  
        <div class="lg:w-1/2 text-right flex flex-col justify-center">  
            {{ with .Params.title }}  
            <h1 class="text-4xl lg:text-5xl font-semibold mb-4 leading-tight max-w-md mx-auto lg:mx-0">{{ . }}</h1>  
            {{ end }}  
  
            {{ with .Params.subtitle }}  
            <h2 class="text-sm uppercase tracking-widest font-bold text-gray-500 mb-6 max-w-md mx-auto lg:mx-0">{{ . }}</h2>  
            {{ end }}  
  
            {{ with .Params.description }}  
            <p class="text-lg text-gray-700 mb-8 mt-6 leading-relaxed max-w-md mx-auto lg:mx-0 whitespace-nowrap">{{ . | markdownify }}</p>  
            {{ end }}  
        </div>  
  
    </section>  
</main>  
{{ end }}

修改配色和插图
#

上文提到过这个博客的配色参考了Hugo Apéro这个主题,具体方式就是去它的GitHub仓库查看它的CSS或者SCSS文件里设计的色号是什么;也可以用取色工具(我用的是Pixeur)直接去取,但是会有误差。然后根据自己所用主题的文档去修改配色,这一步就不多说啦。在这里列一下我用的几个主要配色:

插图也是参考了Hugo Apéro,用的是法国插画家George Barbier的作品。Artvee上的画作很全,还都很清晰,我一般就在上面直接搜作者名然后截图/下载。

修改字体
#

我使用的字体列表如下:

每次下载字体时最好下载GBK版,意思是简繁体都适用,以及最好把字体格式转换为WOFF2,性能最佳。大家可能都已经发现了,这些宋体的英文字符一般都挺丑的,但是有时候中文博客里也会掺杂一些英语词句,我不希望展示出丑丑的宋体英文,于是我加了这个设置:

1
2
3
4
5
6
7
@font-face {  
  font-family: 'title-font';  
  src: url('/fonts/HanaMinA.woff2') format('woff2');  
  font-weight: normal;  
  font-style: normal;  
  unicode-range: U+4E00-9FFF;  /* 只包含 CJK 中文范围 */
}

这样就能限制这个中文字体只应用在中文字符上,而不会影响英文字符。

除此之外还有另一种方法可以实现同样的效果,在设置字体时,把英文字体放在中文字体前面,浏览器会从左到右查找字体,一旦找到能显示的字体就使用。这样浏览器会优先使用英文字体,但是英文字体中没有对中文的适配,会自动采用中文字体。

1
2
3
4
/* 中文标题样式(作用于 h1-h6) */
h1:lang(zh), h2:lang(zh), h3:lang(zh), h4:lang(zh), h5:lang(zh), h6:lang(zh) {  
  font-family: title-font-en, title-font, "PingFang SC", "Noto Serif SC", "Microsoft YaHei";  
}

在我修改完字体以后,页面中所有文字部分莫名变窄了,如下图所示:

文字变窄了
文字变窄了

正常显示的页面
正常显示的页面

询问了GPT以后,它猜测是因为主题内定义的max-w-prosemax-w-* 限制了容器宽度,我检查了一下,果然发现主题默认写了max-w-prose,它会把正文区域的最大宽度限制在 65ch(大约 65 个字符宽),于是我加了个代码取消掉了这个限制:

.max-w-prose {  
  max-width: none !important;  
}

修改网站图标
#

BlowFish默认使用一只河豚(?)作为网站图标,还挺萌的,但是我还是想换成比较有个人特色的图标,在此推荐favicon.io这个网站,上传图片就能一键获得所需图标文件,然后按照操作把代码复制到自己的项目里的head.html里就可以了。

插入NeoDB卡片
#

我到处抄作业,先从这个博客里抄了代码,但是报错了,我就扔进GPT里一番倒腾,但是这个UI有点丑,我又想直接复制薯饼的代码但是也因为Hugo版本不一致报错了,我只好抄了些idea回来(?)比如优化评分不足时的展示就被我抄过来了嘻嘻(*^^*)

我还加了对夜间模式的CSS修改,现在NeoDB卡片的代码如下:

展开代码/收起
{{ $dbUrl := .Get 0 }}  
{{ $dbApiUrl := "https://neodb.social/api/" }}  
{{ $dbType := "" }}  
  
{{ if (findRE `^.*neodb\.social\/.*` $dbUrl) }}  
{{ $dbType = replaceRE `.*neodb.social\/(.*\/.*)` "$1" $dbUrl }}  
{{ else }}  
{{ $dbType = $dbUrl }}  
{{ $dbApiUrl = "https://neodb.social/api/catalog/fetch?url=" }}  
{{ end }}  
  
{{ $remote := resources.GetRemote (print $dbApiUrl $dbType) }}  
{{ $dbFetch := $remote | transform.Unmarshal }}  
  
{{ if $dbFetch }}  
{{ $itemRating := 0 }}{{ with $dbFetch.rating }}{{ $itemRating = . }}{{ end }}  
<div class="db-card">  
    <div class="db-card-subject">  
        <div class="db-card-post">  
            <img loading="lazy" decoding="async" referrerpolicy="no-referrer" src="{{ $dbFetch.cover_image_url }}">  
        </div>  
        <div class="db-card-content">  
            <div class="db-card-title"><a href="{{ $dbUrl }}" class="cute" target="_blank" rel="noreferrer">{{ $dbFetch.title }}</a></div>  
            <div class="rating">  
                {{ if $dbFetch.rating }}  
                <span class="allstardark">  
                                    <span class="allstarlight" style="width:{{mul 10 $itemRating }}%"></span>  
                                </span>  
                <span class="rating_nums">{{ $itemRating }}</span>  
                {{ else }}  
                <span class="rating_nums" style="color:#737373;">评分人数不足</span>  
                {{ end }}  
            </div>  
            <div class="db-card-abstract">{{ $dbFetch.brief }}</div>  
        </div>  
        <div class="db-card-cate">{{ $dbFetch.category }}</div>  
    </div>  
</div>  
{{ else }}  
<p style="text-align: center;"><small>远程获取内容失败,请检查 API 有效性。</small></p>  
{{ end }}

CSS的代码如下:

展开代码/收起
/* db-card -------- start*/  
.db-card {  
  margin: 2rem 3rem;  
  background: #FAFAFA;  
  border-radius: 8px;  
  box-shadow: 0px px 2px rgba(0, 0, 0, 0.04), 0px 0px 2px rgba(0, 0, 0, 0.06), 0px 0px 1px rgba(0, 0, 0, 0.04);  
}  
  
.db-card-subject {  
  display: flex;  
  align-items: flex-start;  
  line-height: 1.6;  
  padding: 12px;  
  position: relative  
}  
  
.db-card-content {  
  flex: 1 1 auto  
}  
  
.db-card-post {  
  width: 96px;  
  margin-right: 15px;  
  display: flex;  
  flex: 0 0 auto  
}  
  
.db-card-title {  
  margin-bottom: 5px;  
  font-size: 18px  
}  
  
.db-card-title a {  
  text-decoration: none!important  
}  
  
.db-card-abstract,  
.db-card-comment {  
  font-size: 14px;  
  overflow: auto;  
  max-height: 7rem  
}  
  
.db-card-cate {  
  position: absolute;  
  top: 0;  
  right: 0;  
  background: #f99b0170;  
  padding: 1px 8px;  
  font-size: small;  
  font-style: italic;  
  border-radius: 0 8px 0 8px;  
  text-transform: capitalize  
}  
  
.db-card-post img {  
  width: 96px!important;  
  height: 128px!important;  
  border-radius: 4px;  
  -o-object-fit: cover;  
  object-fit: cover  
}  
  
.rating {  
  margin: 0 0 5px;  
  font-size: 13px;  
  line-height: 1;  
  display: flex;  
  align-items: center  
}  
  
.rating .allstardark {  
  position: relative;  
  color: #f99b01;  
  height: 16px;  
  width: 80px;  
  background-size: auto 100%;  
  margin-right: 8px;  
  background-repeat: repeat;  
  background-image: url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjxwYXRoIGQ9Ik05MDguMSAzNTMuMWwtMjUzLjktMzYuOUw1NDAuNyA4Ni4xYy0zLjEtNi4zLTguMi0xMS40LTE0LjUtMTQuNS0xNS44LTcuOC0zNS0xLjMtNDIuOSAxNC41TDM2OS44IDMxNi4ybC0yNTMuOSAzNi45Yy03IDEtMTMuNCA0LjMtMTguMyA5LjMtMTIuMyAxMi43LTEyLjEgMzIuOS42IDQ1LjNsMTgzLjcgMTc5LjEtNDMuNCAyNTIuOWMtMS4yIDYuOS0uMSAxNC4xIDMuMiAyMC4zIDguMiAxNS42IDI3LjYgMjEuNyA0My4yIDEzLjRMNTEyIDc1NGwyMjcuMSAxMTkuNGM2LjIgMy4zIDEzLjQgNC40IDIwLjMgMy4yIDE3LjQtMyAyOS4xLTE5LjUgMjYuMS0zNi45bC00My40LTI1Mi45IDE4My43LTE3OS4xYzUtNC45IDguMy0xMS4zIDkuMy0xOC4zIDIuNy0xNy41LTkuNS0zMy43LTI3LTM2LjN6TTY2NC44IDU2MS42bDM2LjEgMjEwLjNMNTEyIDY3Mi43IDMyMy4xIDc3MmwzNi4xLTIxMC4zLTE1Mi44LTE0OUw0MTcuNiAzODIgNTEyIDE5MC43IDYwNi40IDM4MmwyMTEuMiAzMC43LTE1Mi44IDE0OC45eiIgZmlsbD0iI2Y5OWIwMSIvPjwvc3ZnPg==)  
}  
  
.rating .allstarlight {  
  position: absolute;  
  left: 0;  
  color: #f99b01;  
  height: 16px;  
  overflow: hidden;  
  background-size: auto 100%;  
  background-repeat: repeat;  
  background-image: url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjxwYXRoIGQ9Ik05MDguMSAzNTMuMWwtMjUzLjktMzYuOUw1NDAuNyA4Ni4xYy0zLjEtNi4zLTguMi0xMS40LTE0LjUtMTQuNS0xNS44LTcuOC0zNS0xLjMtNDIuOSAxNC41TDM2OS44IDMxNi4ybC0yNTMuOSAzNi45Yy03IDEtMTMuNCA0LjMtMTguMyA5LjMtMTIuMyAxMi43LTEyLjEgMzIuOS42IDQ1LjNsMTgzLjcgMTc5LjEtNDMuNCAyNTIuOWMtMS4yIDYuOS0uMSAxNC4xIDMuMiAyMC4zIDguMiAxNS42IDI3LjYgMjEuNyA0My4yIDEzLjRMNTEyIDc1NGwyMjcuMSAxMTkuNGM2LjIgMy4zIDEzLjQgNC40IDIwLjMgMy4yIDE3LjQtMyAyOS4xLTE5LjUgMjYuMS0zNi45bC00My40LTI1Mi45IDE4My43LTE3OS4xYzUtNC45IDguMy0xMS4zIDkuMy0xOC4zIDIuNy0xNy41LTkuNS0zMy43LTI3LTM2LjN6IiBmaWxsPSIjZjk5YjAxIi8+PC9zdmc+)  
}  
  
@media(max-width: 550px) {  
  .db-card {  
    margin: .8rem 1rem  
  }  
  .db-card-comment {  
    display: none  
  }  
}  
  
/* 整体滚动条窄一些 */
::-webkit-scrollbar {  
  width: 6px;  
}  
  
/* 轨道完全透明 */
::-webkit-scrollbar-track {  
  background: transparent;  
}  
  
/* 滑块样式 */
::-webkit-scrollbar-thumb {  
  background-color: rgba(150, 150, 150, 0.3);  
  border-radius: 10px;  
}  
  
/* 鼠标 hover 时才更明显 */
::-webkit-scrollbar-thumb:hover {  
  background-color: rgba(150, 150, 150, 0.6);  
}  
  
/* Dark mode for db-card */
.dark {  
  --card-background: #2C2857;  
  --card-text-color-main: #cccccc;  
  --card-shadow: 0 6px 10px rgba(0, 0, 0, 0.6);  
}  
  
.dark .db-card {  
  background: var(--card-background);  
  box-shadow: var(--card-shadow);  
}  
  
.dark .db-card-title,  
.dark .db-card-abstract,  
.dark .db-card-cate,  
.dark .rating_nums {  
  color: var(--card-text-color-main);  
}  
  
.dark .db-card-cate {  
  background: rgba(249, 155, 1, 0.2); /* 柔和橘色 */}  
  
/* 夜间模式下的滚动条更暗一点 */
.dark ::-webkit-scrollbar-thumb {  
  background-color: rgba(255, 255, 255, 0.2);  
}  
.dark ::-webkit-scrollbar-thumb:hover {  
  background-color: rgba(255, 255, 255, 0.35);  
}  
/* db-card -------- end */

最后效果如下:

{\{< neodb "https://neodb.social/movie/75xnIJtis3D92xz0xtKlHZ" >}\}

8.1
广东佛山人叶问(梁朝伟 饰),年少时家境优渥,师从咏春拳第三代传人陈华顺学习拳法,师傅“一条腰带一口气”的告诫,支持他走过兵荒马乱、朝代更迭的混乱年代。妻子张永成(宋慧乔 饰)泼辣干练,二人夫唱妇随,琴瑟合璧。 1936年,佛山武术界乱云激荡。八卦拳宗师宫羽田(王庆祥 饰)年事已高,承诺隐退。其所担任的中华武士会会长职位,自然引起武林高手的关注与觊觎。包括宫羽田的独生女宫二(章子怡 饰)在内,白猿马三(张晋 饰)、关东之鬼丁连山(赵本山 饰)、咏春叶问等高手无不将目光聚焦在正气凛然的宫羽田身上。拳有南北,国有南北乎?最有德行之人才堪会长重任,然这浮世虚名却引得无数迷乱之人狂醉奔忙,浪掷残生。生逢乱世,儿女情长埋藏心底,被冷若寒冰的车轮碾作碎泥……
movie

修改链接样式
#

我不太满意BlowFish的链接样式,具体为链接只有颜色和正文不一样,其他无分别。在我修改完配色后我发现链接的颜色与正文十分接近,很难分辨。我就参考了其他博客所用的类似荧光笔样式,再使唤GPT给我生成了修改链接样式的CSS代码,如下:

展开代码/收起
.prose a {  
  text-decoration: none;  
  color: inherit;  
  background-image: linear-gradient(to top, rgba(249, 155, 1, 0.3) 30%, transparent 30%);  
  transition: background-size 0.3s ease;  
  background-size: 100% 0.4em;  
  background-repeat: no-repeat;  
  background-position: 0 88%;  
}  
  
.prose a:hover {  
  background-size: 100% 70%;  
  background-image: linear-gradient(to top, rgba(249, 155, 1, 0.3) 88%, transparent 88%);  
}
注意,代码里的.prose可以去掉,我这么写是因为BlowFish里用它来区分正文和标题,所以我的代码的意思是只有文章正文里的链接会应用这个样式。

添加评论区
#

本博客的评论区用的是Waline,没什么特别的原因,只是看朋友在用所以自己也用(。)我参考的搭建评论区教程是这篇博客,除了单纯地修改颜色以外,我还在原样式的基础上添加了以下代码,让它变得更美观!

.wl-editor {  
  width: calc(100% - 3em);  /* 之前的编辑区不知道为什么宽度超出了,所以设置了这个*/
}  
input:focus {  /* 去掉点击昵称等输入框时出现的蓝色边框*/
  outline: none;  
  border: 0;  
  box-shadow: none;  
}  
textarea:focus {  /* 去掉点击评论正文输入框时出现的蓝色边框*/
  outline: none;  
  border: 0;  
  box-shadow: none;  
}

添加友链
#

网上有很多怎么添加友链的代码,所以我只记录一下我用的CSS样式:

展开代码/收起
  /* ---------- 友链卡片样式开始 ---------- */  a {  
    text-decoration: none;  
    color: inherit;  
    background-size: 0 !important;  
  }  
  
  a:hover {  
    text-decoration: none;  
    color: inherit;  
    background-size: 0 !important;  
  }  
  
  .friend-link {  
    display: block;  
    width: 100%;  
    margin: 1rem auto;  
    text-decoration: none;  
    border-radius: 12px;  
    overflow: hidden;  
    background-color: #fff;  
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);  
    transition: transform 0.2s ease;  
  }  
  
  .friend-link-div {  
    display: flex;  
    align-items: center;  
    padding: 0 16px;  
  }  
  
  .friend-avatar {  
    width: 56px;  
    height: 56px;  
    border-radius: 50%;  
    object-fit: cover;  
    flex-shrink: 0;  
    margin-right: 10px;  
  }  
  
  .friend-link-info {  
    display: flex;  
    flex-direction: column;  
    justify-content: center;  
  }  
  
  .friend-name {  
    font-size: 16px;  
    font-weight: bolder;  
    font-style: normal;  
    color: #444;  
    margin-bottom: 0;  
    margin-top: 0;  
    margin-left: 12px;  
  }  
  
  .friend-bio {  
    font-size: 14px;  
    color: #666;  
    line-height: 1.4;  
    overflow: hidden;  
    text-overflow: ellipsis;  
    margin-top: 0;  
    margin-bottom: 0;  
    margin-left: 12px;  
  }  
  
  /* 夜间模式适配 */  .dark .friend-link {  
    background-color: #5D5470;  
    box-shadow: 0 4px 20px rgba(255, 255, 255, 0.05);  
  }  
  
  .dark .friend-name {  
    color: #ddd;  
  }  
  
  .dark .friend-bio {  
    color: #F5F5F5;  
  }  
  
  .dark .friend-avatar {  
    border-color: #444;  
  }  
  
  /* 响应式优化 */  @media screen and (max-width: 600px) {  
    .friend-link-div {  
      flex-direction: row;  
      padding: 12px 16px;  
    }  
  
    .friend-avatar {  
      width: 56px;  
      height: 56px;  
      margin-right: 12px;  
    }  
  
    .friend-name {  
      font-size: 16px;  
    }  
  
    .friend-bio {  
      font-size: 14px;  
    }  
  }  
  /* ---------- 友链卡片样式结束 ---------- */

总结
#

这么写下来,发现自己确实没怎么改动原主题呢,但是样式却跟原主题几乎两模两样,这就是UI的魅力吧!