目录
article
Hugo 中设置单个引用图片的样式
Hugo 中设置单个引用图片样式的邪修方案
Markdown 中引入图片时,经常需要调整图片的宽度,但是原生的 Markdown 中并不支持单独对某个图片进行样式设置。

尝试过如下几个方案,但都不是很理想。
- 在每个图片外部包裹一个
<div>元素,在<div>上设置样式; - 将每个图片裁剪为合适的大小;
- 将图片应用改为使用
<img>元素;
从兼容性来说,上面的几种方案还是蛮好的,即使切换 Markdown 的渲染组件或者更换博客的框架,基本上都不会有什么影响。
但缺点就是使用起来不太方便,改用 <img> 写法的话,还会失去 Markdown 格式文件引用的优点(比如 VS Code 中只是在修改文件名时自动更新图片引用路径)。简单说就是不够方便。
于是思考有没有比较简洁的方案,最终采用了如下方案:在图片引用的后面增加 #{style-key}={style-value} 格式的参数。

刚开始考虑的是通过 QueryString 格式(
?{style-key}=${style-value})的参数传递图片样式,也可以正常渲染,但是在 VS Code 中自动修改引用地址时,会将 QueryString 部分自动移除了。
第二步就是修改渲染的代码,在渲染时将这些样式应用到图片元素上。
Hugo 支持通过渲染钩子自定义 Markdown 渲染行为,可以通过在主题的 /layouts/_markup 目录下创建 render-image.html 文件来自定义图片渲染行为。
我这里是基于 Lotus Docs 主题进行修改的。
修改后的代码如下:
<div class="img-container">
{{- $style := slice -}}
{{- $cleanUrl := .Destination -}}
{{- $fragment := "" -}}
{{- /* 处理 URL 片段(#后面的部分) */ -}}
{{- if in .Destination "#" -}}
{{- $parts := split .Destination "#" -}}
{{- $cleanUrl = index $parts 0 -}}
{{- if gt (len $parts) 1 -}}
{{- $fragment = index $parts 1 -}}
{{- /* 直接解析片段中的键值对,避免 urls.Parse 处理%字符的问题 */ -}}
{{- $params := split $fragment "&" -}}
{{- range $param := $params -}}
{{- $keyValue := split $param "=" -}}
{{- if eq (len $keyValue) 2 -}}
{{- $key := index $keyValue 0 -}}
{{- $value := index $keyValue 1 -}}
{{- /* 检查是否为常见 CSS 样式属性 */ -}}
{{- if in (slice "width" "height" "max-width" "max-height" "min-width" "min-height" "border" "border-radius" "opacity" "margin" "margin-top" "margin-right" "margin-bottom" "margin-left" "padding" "padding-top" "padding-right" "padding-bottom" "padding-left" "display" "float" "position" "top" "right" "bottom" "left" "z-index" "transform" "transition" "filter" "box-shadow" "background" "background-color") $key -}}
{{- $style = $style | append (printf "%s:%s" $key $value) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $styleStr := delimit $style ";" -}}
{{- $styleAttr := cond (gt (len $styleStr) 0) (printf "style=\"%s\"" $styleStr) "" -}}
{{ if .PlainText }}
<figure>
<img src="{{ $cleanUrl }}" alt="{{ .Title }}" loading="lazy" {{ $styleAttr | safeHTMLAttr }}>
<figcaption>{{ .PlainText | markdownify }}</figcaption>
</figure>
{{ else }}
<img src="{{ $cleanUrl }}" alt="{{ .Title }}" loading="lazy" {{ $styleAttr | safeHTMLAttr }}>
{{ end }}
</div>
最终渲染的效果:
<div class="img-container">
<img src="./1.png" alt="" loading="lazy" style="max-width:500px">
</div>
其它的 Markdown 渲染框架,也可以通过类似的方案来实现自定义图片样式。