hugo博客装修小记之三

hugo博客装修小记之三

Hugo博客Book主题装修小记第三辑。没想到新的一期来得这么快,这次主要针对阅读体验进行了一些样式变更。主要包括注脚样式、Twikoo样式和功能、目录样式和功能等。

更好的移动端体验 #

针对多媒体卡片和代码块做了一些移动端的适应,在小屏幕上更易阅读,具体为:

  • 各类媒体卡片宽度适应为100%,简介字号缩小为$font-size-12,简介框高度缩小4rem
  • 代码高度适应为6em,约4行。

这里,代码块高度设置的比较小(几乎折叠了),主要考虑到读者几乎不会在移动端进行代码的复制或阅读。但是以单行为主的Shell命令仍能完整显示。实现比较简单,直接通过布局断点进行判断,覆盖默认值。

代码高度适应 代码高度适应

图片与多媒体卡片适应 图片与多媒体卡片适应

/* /themes/hugo-book/assets/_custom.scss */
@media screen and (max-width: $mobile-breakpoint) {
  img,
  .db-card,
  .post-preview,
  .video-container {
    width: 100% !important;
  }
  pre {
    max-height: 6em !important;
  }
  .db-card-abstract,
  .db-card-comment {
    font-size: $font-size-12 !important;
    max-height: 4rem !important;
  }
}

注脚标记 #

给引用的角标做个填色样式,更加显眼,也更易于点击。看我右上角1

/* /themes/hugo-book/assets/_custom.scss */
.footnote-ref {
  background-color: var(--color-link);
  color: var(--body-background) !important;
  padding: 0px 4px;
  border-radius: 4px;
  font-size: $font-size-10;
  margin: 0 2px;
}

注脚悬浮显示 #

在网页上上下跳跃阅读脚注体验不佳,即便是提供了必要的锚点链接。鼠标悬浮直接预览注脚内容,会有更好的阅读体验,我也可以放心大胆地用注脚而不是在句子的末尾添加括号说明。原想尝试不依赖Javascript,在Hugo构建时直接嵌入注脚内容,但对Hugo不熟,没能成功。还是暂时用以下方案吧。

<!-- /themes/hugo-book/layouts/partials/docs/inject/body.html -->
<script>
document.addEventListener("DOMContentLoaded", function () {
  const container = document.querySelector('.footnotes');
  if (!container) return;
  const footnotes = {};
  container.querySelectorAll('li[id^="fn:"]').forEach(li => {
    const id = li.id.slice(3);
    let text = li.textContent.trim();
    if (text.endsWith('↩︎')) text = text.slice(0, -2).trim();
    footnotes[id] = text;
  });
  document.querySelectorAll('sup[id^="fnref:"]').forEach(sup => {
    const id = sup.id.slice(6);
    const content = footnotes[id];
    if (content) sup.setAttribute('data-footnote', content);
  });
});
</script>
/* /themes/hugo-book/assets/_custom.scss */
sup[id^="fnref:"] {
  position: relative;
  cursor: help;
  font-size: $font-size-12;
  vertical-align: super;
  line-height: 1.5;
}

sup[id^="fnref:"]::after {
  content: attr(data-footnote);
  position: absolute;
  bottom: calc(100% + 0.5em);
  left: 50%;
  transform: translateX(-50%);

  background: var(--color-link);
  color: var(--body-background);
  padding: 0.25em 0.5em;
  border-radius: $border-radius;
  box-shadow: 0 2px 6px var(--body-font-color);
  white-space: normal;
  width: max-content;
  max-width: 20rem;
  font-size: $font-size-12;
  text-align: left;
  word-break: break-word;
  opacity: 0;
  pointer-events: none;
  z-index: 100;
  transition: opacity 0.2s ease-in-out;
}

sup[id^="fnref:"]:hover::after {
  opacity: 1;
}

还有一种高颜值方案是旁注234,无奈现在我使用的是三栏样式,且我认为目录的优先级更高。在没想好如何美观地兼容旁注和目录之前,还是暂时用上述的方案。

外链标识 #

博文中插入链接时,外站链接和博客内部链接没有区分,给外链加上一个小图标,以便快速区分。标识仅在博文正文中显示。效果对比,如站内博文 低成本的自动化家务管理,站外链接 GitHub - osnsyc/chores-automation

<!-- /themes/hugo-book/layouts/_default/_markup/render-link.html -->
{{- if .Page.Site.Params.BookPortableLinks -}}
  {{- template "portable-link" . -}}
{{- else -}}
  {{- $href := .Destination -}}
  {{- $isExternal := or (strings.HasPrefix $href "http://") (strings.HasPrefix $href "https://") -}}
  <a href="{{ $href | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if $isExternal }} target="_blank" rel="noopener noreferrer"{{ end }}>
    {{ .Text | safeHTML }}
    {{- if $isExternal -}}
    <svg class="external-link-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M 18 13.001953 L 18 19.001953 C 18 20.103516 17.103516 21 16.001953 21 L 4.998047 21 C 3.896484 21 3 20.103516 3 19.001953 L 3 7.998047 C 3 6.896484 3.896484 6 4.998047 6 L 10.998047 6" transform="matrix(0.666667,0,0,0.666667,0,0)"/>
      <path d="M 15 3 L 21 3 L 21 9" transform="matrix(0.666667,0,0,0.666667,0,0)"/>
      <path d="M 10.001953 13.998047 L 21 3" transform="matrix(0.666667,0,0,0.666667,0,0)"/>
    </svg>
    {{- end -}}
  </a>
{{- end -}}
/* /themes/hugo-book/assets/_custom.scss */
.external-link-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-left: 0.125em;
  vertical-align: -0.15em;
  stroke: currentColor;
}

Twikoo主题颜色适应 #

注意到Twikoo的默认主题色(浅蓝)有些别扭,跟博客主题颜色不一致,修改CSS来覆盖默认颜色,自适应亮暗主题。

/* /themes/hugo-book/assets/_custom.scss */
.twikoo .el-button--default {
    color: var(--color-link) !important;
    border-color: var(--color-link) !important;
}

.twikoo .el-button--primary {
    color: var(--body-background) !important;
    background-color: var(--color-link) !important;
    border-color: transparent;
}

.twikoo .tk-icon,
.twikoo .tk-action-icon,
.twikoo .tk-action-icon.tk-action-icon-solid,
.twikoo .tk-action-count,
.twikoo .tk-avatar-img {
    color: var(--color-link) !important;
}

新增Twikoo表情包 #

删除了颜文字表情包,增加了自选的Blob表情包,可以在这个网站选取自己喜欢的表情: Slackmojis ,原图大多是120px的PNG格式文件,显然不符合网站图像的最佳实践(参考本站博文 图片智能压缩与高效写作发布流)。将表情包下载至本地,转换成宽度64px的Webp文件,并上传至CloudFlare的R2存储桶,压缩后平均每个表情文件大小3KB(压缩前约10KB)。

关于owo.json的托管可以查看上一篇装修博文 hugo博客装修小记之二,修改owo.json文件如下

// /themes/hugo-book/static/owo.json
{
  "Blob": {
    "type": "image",
    "container": [
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_smiley.webp\">", "text": "blob_smiley" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_sunglasses.webp\">", "text": "blob_sunglasses" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_joy.webp\">", "text": "blob_joy" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_okhand.webp\">", "text": "blob_okhand" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_kir.webp\">", "text": "blob_kir" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_hearteyes.webp\">", "text": "blob_hearteyes" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_pray.webp\">", "text": "blob_pray" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_thinking_eyes.webp\">", "text": "blob_thinking_eyes" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_sad.webp\">", "text": "blob_sad" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_oohoocry.webp\">", "text": "blob_oohoocry" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_fearful.webp\">", "text": "blob_fearful" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_angry.webp\">", "text": "blob_angry" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_hi.webp\">", "text": "blob_hi" },
      { "icon": "<img src=\"https://img.osnsyc.top/emoji/blob_yes.webp\">", "text": "blob_yes" }
    ]
  },
  "Emoji": {
    "type": "emoji",
    "container": [
      { "icon": "😂", "text": "" },
      { "icon": "😀", "text": "" },
      { "icon": "😅", "text": "" },
      { "icon": "😊", "text": "" },
      { "icon": "🙂", "text": "" },
      { "icon": "🙃", "text": "" },
      { "icon": "😌", "text": "" },
      { "icon": "😍", "text": "" },
      { "icon": "😘 ", "text": "" },
      { "icon": "😜", "text": "" },
      { "icon": "😝", "text": "" },
      { "icon": "😏", "text": "" },
      { "icon": "😒", "text": "" },
      { "icon": "🙄", "text": "" },
      { "icon": "😳 ", "text": "" },
      { "icon": "😡", "text": "" },
      { "icon": "😔", "text": "" },
      { "icon": "😫", "text": "" },
      { "icon": "😱", "text": "" },
      { "icon": "😭", "text": "" },
      { "icon": "💩", "text": "" },
      { "icon": "👻", "text": "" },
      { "icon": "🙌", "text": "" },
      { "icon": "🖕", "text": "" },
      { "icon": "👍", "text": "" },
      { "icon": "👫", "text": "" },
      { "icon": "👬", "text": "" },
      { "icon": "👭", "text": "" },
      { "icon": "🌚", "text": "" },
      { "icon": "🌝", "text": "" },
      { "icon": "🙈", "text": "" },
      { "icon": "💊", "text": "" },
      { "icon": "😶", "text": "" },
      { "icon": "🙏", "text": "" },
      { "icon": "🍦", "text": "" },
      { "icon": "🍉", "text": "" },
      { "icon": "😣", "text": "" }
    ]
  }
}

修改样式,确保表情与文字在同一行,大小为2rem,即32px,原图64px足以保证在高分屏(DPR=2)上清晰显示。

/* /themes/hugo-book/assets/_custom.scss */
.tk-content img, .tk-preview-container img {
    display: inline;
    max-width: 2rem !important;
    vertical-align: bottom !important;
}

解决APlayer导致的中文目录无法跳转问题 #

偶然发现如果页面加载了APlayer播放器,中文目录跳转会失效,搜了下问题所在,居然是陈年未解决的Bug。参考 滑翔闪 韶华尐沐 的博文,原因是APlayer下的smoothscroll插件在处理跳转连接的hash时只对英文处理有效,而中文会转成Unicode码,无法处理,所以跳转就会失效。解决办法是修改APlayer.min.js,定位到defaultPrevented,替换成以下代码(decodeURIComponent处理)。

if (!e.defaultPrevented) {
                            e.preventDefault(), decodeURIComponent(location.hash) !== decodeURIComponent(this.hash) && window.history.pushState(null, null, decodeURIComponent(this.hash));
                            var n = document.getElementById(decodeURIComponent(this.hash).substring(1));
                            if (!n) return;
                            t(n, 500, function(e) {
                                location.replace("#" + e.id)
                            })
                        }

目录跟随高亮 #

Hugo-Book主题的右侧边目录,没有随内容自动高亮的功能。在阅读长文时这项功能还是有帮助的,参考 砖瓦匠杜重 的博文进行了配置,高亮颜色为主题色,左侧加主题色条进行强调,效果如下。

<!-- /themes/hugo-book/layouts/partials/docs/inject/body.html -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/[email protected]/dist/gumshoe.polyfills.min.js"></script>
<script>new Gumshoe('.book-toc a', { nested: true });</script>

也可以将js下载并置于/themes/hugo-book/static文件夹内:

<!-- /themes/hugo-book/layouts/partials/docs/inject/body.html -->
<script src="https://osnsyc.top/gumshoe.polyfills.min.js"></script>

修改目录样式,如果没有定义var(--gray-1000)$padding-32请在/themes/hugo-book/assets/_defaults.scss中自行配置。

/* /themes/hugo-book/assets/_custom.scss */
.book-toc li,
.book-toc ul {
  list-style-type: none;
  padding-left: 0px;
}

.book-toc li > a {
  display: block;
  padding-left: $padding-16;
  color: var(--gray-1000);
}

.book-toc li > a:hover,
.book-toc li > a:focus {
  padding-left: $padding-16;
  color: var(--color-link);
  border-left: 1px solid var(--color-link);
}

.book-toc li.active > a,
.book-toc li.active > a:hover,
.book-toc li.active > a:focus {
  padding-left: $padding-16;
  font-weight: bold;
  color: var(--color-link);
  border-left: 2px solid var(--color-link);
}

.book-toc li li > a {
  padding-left: $padding-32;
}

.book-toc li li > a:hover,
.book-toc li li > a:focus {
  padding-left: $padding-32;
}

.book-toc li li.active > a,
.book-toc li li.active > a:hover,
.book-toc li li.active > a:focus {
  padding-left: $padding-32;
}

.book-toc .nav-link.active + ul {
  display: block;
}

Tag标签样式优化 #

Tag标签和目录都在侧栏受.book-toc控制,刚才修改了目录,索性也将标签样式改一改。Book主题默认的标签样式中,计数离标签文字太远了,翻了好多博客,没找到适合此主题的好看样式,凭着感觉先撸一个吧,以后看到好的样式再抄过来,哈哈哈。修改完后,样式为圆角矩形,按计数降序排列。

<!-- /themes/hugo-book/layouts/partials/docs/taxonomy.html -->
<nav>
  <ul>
  {{ range $term, $_ := .Site.Taxonomies }}
    {{ with $.Site.GetPage (printf "/%s" $term | urlize) }}
    <li class="book-section-flat">
      <h3><strong>{{ .Title | title }}</strong></h3>
      <ul>
      {{ range sort .Pages "Pages" "desc" }}
        <a class="toc-tag" href="{{ .RelPermalink }}">
          <span class="toc-tag-title">{{ .Title }}</span>
          <span class="toc-tag-count">{{ len .Pages }}</span>
        </a>
      {{ end }}
      </ul>
    </li>
    {{ end }}
  {{ end }}
  </ul>
</nav>
/* /themes/hugo-book/assets/_custom.scss */
.toc-tag {
  display: inline-flex;
  align-items: center;
  margin: $padding-4;
  font-size: $font-size-12;
  color: var(--body-font-color);
  line-height: 1.5;
  border-radius: $border-radius;
  border: 1px solid var(--color-link);
  overflow: hidden;
  text-decoration: none;
  cursor: pointer;
  padding: 0;

  .toc-tag-title {
    display: inline-block;
    padding: $padding-2 $padding-4;
    white-space: nowrap;
  }

  .toc-tag-count {
    display: inline-block;
    padding: $padding-2 $padding-4;
    color: var(--color-link);
    font-weight: bold;
    border-left: 1px solid var(--color-link);
    white-space: nowrap;
  }

  &:hover {
    color: var(--body-background);
    border: 1px solid var(--body-font-color);
    background: var(--color-link);
  }

  &:hover .toc-tag-count {
    color: var(--body-background);
    border-left: 1px solid var(--body-background);
    background: var(--color-link);
  }
}
前一篇 低成本的自动化家务管... 随机阅读