Hexo NexT主题的字体更换

本文主要讲述Hexo NexT主题的字体更换,包括一些比较精细的设置。

本文运行环境:

1
2
3
hexo: 4.2.1
hexo-cli: 3.1.0
NexT: 8.0.0-rc.4

注意,对于使用 Hexo 5.0 版本及以上、NexT v8.1.0 版本及以上的读者,默认的自定义配置文件已经从 source/_data/next.yml 变更为 _config.next.yml,请注意迁移与替换。对于日后 NexT 可能会出现的重大更新造成的配置变动,可能会在此处更新,或另外写文章说明。

在主题配置里更换字体

打开source/_data/next.yml,在里面搜索# Font Settings,把自定义font打开。可以看到这里可以更改全局字体、网站标题字体、h1-h6字体、正文字体与代码块字体。你可以去Google字体页面去选择喜欢的字体进行修改,也可以替换字号(这里的字号可以理解为比例,默认是1)。

字体的host默认为https://fonts.googleapis.com,可能在某些地区访问会不太顺利。我们可以更改它为https://fonts.loli.net以获取更快速的访问[1]

更精细的配置

主题配置里的选项可能过于少了,如果你感到不满意,想做一些更精细的配置,那就需要你学习一下CSS了。下面列举一些我更改的例子。

更改行内代码块样式

首先在source/_data/next.yml里搜索custom_file_path,打开style: source/_data/styles.styl功能,并新建这个文件。

source/_data/styles.styl里加入如下内容即可:

source/_data/styles.styl
1
2
3
4
5
6
// inline code
p code {
color: #c71585;
background: #fffafa;
margin: 2px;
}

更改跨行代码块样式

跨行代码块分为几个部分:文件标题(如有)、代码行数与代码内容。这三者分别由.highlight figcaption.highlight .gutter pre.highlight .code pre控制。比如我把文件标题与代码行数改了一下:

source/_data/styles.styl
1
2
3
4
5
6
7
8
9
10
11
// code block file name
.highlight figcaption {
color: #fffafa;
background: #808080;
font-family: $code-font-family;
}

// code block line number
.highlight .gutter pre {
background: #dcdcdc;
}

这里的$code-font-family是在themes/next/source/css/_variables/base.styl里定义的变量,用于控制代码的字体。代码文件标题的字体默认是与正文字体一致,与代码块整体不太协调,我就改了一下。

中英文使用不同的默认字体

这个解决办法比较复杂。source/_data/next.yml的字体设置功能暂时不支持放置多个选项,仔细观察会发现这里面有一些不科学。如果想让中英文默认字体单独设置,就无法做到,原因是中文字体会包括英文字体,并造成覆盖。

一个非常粗糙的做法是,在global处设置英文字体,然后在titleheadingsposts处设置中文字体。但这样无法让后三者中英文默认字体不同,不是好的方案。那么怎么办呢?这就需要去看看NexT主题的源码了。

主题内部,字体的设置都存放在themes/next/source/css/_variables/base.styl里,一共有这么几个变量:

  • $font-family-chinese 负责调控中文字体(但任何字体设置的优先级更高)。
  • $font-family-base 负责调控全局字体,主要是不被下面几类包括的文字。
  • $font-family-logo 负责调控网站标题的字体。
  • $font-family-headings 负责调控h1-h6的字体,包括标题与文中小标题。
  • $font-family-posts 负责调控正文字体。
  • $font-family-monospace 负责调控代码块的字体。

要做到更改,我们可以打开_config.yml里面的variable: source/_data/variables.styl,并新建此文件,以达到覆盖变量的目的。

在做这一步之前,我们先在_config.yml里面字体的global处设置一款纯英文字体,保证它的优先级比中文字体高。我在这里选择了Noto Sans

下一步,比如我们想给中文设置一款默认的衬线字体Noto Serif SC,我们可以加入这一行:

source/_data/variables.styl
1
$font-family-chinese = "Noto Serif SC", "PingFang SC", "Microsoft YaHei";

这样是不是大功告成了呢?本地看一下,发现并未改动。为什么呢?试了一下发现原来只重新定义$font-family-chinese不够,必须把剩下的字体再重新定义一下才可以。我们可以把剩下的字体变量都复制过来:

source/_data/variables.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$font-family-chinese = "Noto Serif SC", "PingFang SC", "Microsoft YaHei";

$font-family-base = $font-family-chinese, sans-serif;
$font-family-base = get_font_family('global'), $font-family-chinese, sans-serif if get_font_family('global');

$font-family-logo = $font-family-base;
$font-family-logo = get_font_family('title'), $font-family-base if get_font_family('title');

$font-family-headings = $font-family-base;
$font-family-headings = get_font_family('headings'), $font-family-base if get_font_family('headings');

$font-family-posts = $font-family-base;
$font-family-posts = get_font_family('posts'), $font-family-base if get_font_family('posts');

$font-family-monospace = consolas, Menlo, monospace, $font-family-chinese;
$font-family-monospace = get_font_family('codes'), consolas, Menlo, monospace, $font-family-chinese if get_font_family('codes');

这样就没问题了,成功实现中英文默认字体不同。但如果你需要一些更精细的设置,那就需要多研究研究这几个变量了。


  1. 参考网页:https://sb.sb/blog/css-cdn/ ↩︎