Hugo图片显示优化

Hugo 默认会直接渲染 Markdown 图片。对于尺寸较大的图片,可以通过图片渲染钩子统一添加容器,再使用 CSS 改善图片的显示效果。

本文以 PaperMod 主题为例,使用纯 CSS 实现图片悬停放大,不引入 JavaScript 或第三方库。这样可以避免 CDN 加载失败对页面功能造成影响。

现有方案的问题

如果只在 CSS 中使用 :active,图片仅会在鼠标按住时放大,移动端也很难触发;而且这种方式只是放大当前图片,不会显示更高分辨率的原图。

本文的方案只改善页面中的显示效果:图片保持响应式宽度,鼠标悬停时平滑放大,并通过阴影提示当前状态。它不会改变图片文件本身,也不会在移动端产生额外操作。

实施步骤

1. 创建图片渲染钩子

在站点根目录创建 layouts/_default/_markup/render-image.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{{/*
  将 Markdown 图片包裹在 figure 中,为 CSS 悬停效果提供容器。
  同时把图片的 alt 文本显示为图片说明。
*/}}
<figure class="zoom-container">
    <img src="{{ .Destination | safeURL }}"
         alt="{{ .PlainText | safeHTML }}"
         {{- with .Title }} title="{{ . }}"{{ end -}}
         loading="lazy" />

    {{- with .PlainText -}}
        <figcaption>{{ . }}</figcaption>
    {{- end -}}
</figure>

该钩子会自动处理文章中的 Markdown 图片,例如 ![图片说明](image.jpg),无需修改文章正文。

2. 添加 CSS

assets/css/extended/blank.css 中加入以下样式。如果文件中已经存在图片相关规则,请替换为下面的规则,避免旧的 :active 样式相互影响。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* 图片容器 */
.post-content .zoom-container {
    display: block;
    margin: 25px 0;
    text-align: center;
}

/* 图片的初始状态和过渡效果 */
.post-content .zoom-container img {
    max-width: 100%;
    height: auto;
    display: inline-block;
    border-radius: 5px;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* 鼠标悬停时放大图片 */
.post-content .zoom-container:hover img {
    transform: scale(1.2);
    cursor: zoom-in;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
    position: relative;
    z-index: 10;
}

/* 图片说明 */
.post-content .zoom-container figcaption {
    margin-top: 10px;
    font-size: 0.9em;
    color: var(--secondary);
    text-align: center;
    font-style: italic;
}

如果之前还使用了自定义的 PaperMod 布局宽度,可以继续保留原文件中的变量定义,例如:

1
2
3
4
5
:root {
    --nav-width: 1380px;
    --article-width: 650px;
    --toc-width: 300px;
}

效果与注意事项

重新启动 hugo server 并刷新页面后:

  1. 图片宽度不会超过文章内容区域,并会随屏幕宽度变化。
  2. 图片有 alt 文本时,该文本会显示在图片下方。
  3. 鼠标悬停时图片会平滑放大,并显示放大光标和阴影。
  4. 移动设备通常没有悬停状态,图片仍会按正常尺寸显示,不影响阅读。

放大比例和动画时间分别由 scale(1.2)0.3s 控制,可以根据文章布局调整。由于放大后的图片可能覆盖相邻内容,建议不要把比例设置得过大。