【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(二)
分析了在 /layouts/_default/single.html 进行布局,介绍了 <main>,<div>,<article> 三个标签,以及侧边栏 <sidebar> 和 <article> 应该怎样做两栏布局,下面继续
搭建私人博客
上篇 blog 提到了 Flex/Grid 布局,下面详细分析下
Flexbox(弹性盒)布局和 Grid(网格)布局是现代 CSS 中最主流的两种二维布局模型,可以用来控制网页元素如何排列,对齐,伸缩和响应屏幕大小,像侧边栏 + 正文内容这种两栏布局,通常采用 Flexbox 布局来并排显示
Flexbox 布局
其核心思想在于让容器内的子元素,沿一个主轴(水平或垂直)自动伸缩,对齐和换行 ,其基本用法如下,比如接上篇 blog 的 <div> 容器 .post-witch-sidebar
css
.post-with-sidebar {
display: flex; /* 启用 Flex 布局 */
gap: 20px; /* 子元素间距 */
}
此时,它的直接子元素(也就是 sidebar 和 article)会默认水平从左到右排列,并且可以分别设置宽度,是否伸缩等,比如下面这个更具体点的例子
html
<div class="post-with-sidebar">
<aside>Sidebar</aside>
<article>Main Content</article>
</div>
css
.post-with-sidebar {
display: flex;
}
.post-with-sidebar > aside {
width: 250px;
flex-shrink: 0; /* 不允许缩小 */
}
.post-with-sidebar > article {
flex: 1; /* 占据剩余空间 */
}
其效果会让侧边栏固定 250px 宽度,文章区域自动填满右边剩余宽度,能够自动适应不同屏幕
Grid 布局
其核心思想在于把容器划分为行和列组成的网格,然后把子元素精准放置到指定格子中 ,基本用法如下,还是以 .post-witch-sidebar 为例
css
.post-with-sidebar {
display: grid;
grid-template-columns: 250px 1fr; /* 一列250px,一列自适应 */
gap: 20px;
}
这样,子元素就会自动按顺序填入网格单元格中,其效果和 Flexbox 类似,但 Grid 更适合复杂二维布局(比如杂志排版,仪表盘等)
总之,Flex 和 Grid 各有其特点,可以根据不同场景,选择不同的布局方式,比如
- 一维布局:一行或一列,Flexbox 更合适,比如导航栏,或者侧边栏 + 主内容这种两栏布局
- 二维布局:多行多列,精确定位,Grid 更合适,比如图片画廊,卡片网格等
- 对齐,居中,伸缩:Flexbox 更直观
通常情况下,侧边栏 + 主内容这种场景中,Flexbox 是更常见,更轻量的选择
不过要注意,无论是 Flex 还是 Grid,只有容器的直接子元素才会成为 flex item 或 grid item,比如像下面这个情况
html
<div class="post-with-sidebar">
<aside>...</aside> <!-- 参与布局 -->
<article>...</article> <!-- 参与布局 -->
</div>
这里 sidebar 和 article 是 .post-with-sidebar 的直接子元素,是 OK 的,但是如果是下面这种情况,就不行了
html
<div class="post-with-sidebar">
<div>
<aside>...</aside> <!-- 不是直接子元素,不受 flex/grid 控制 -->
</div>
<article>...</article>
</div>
所以这里可以看到,sidebar 和 article 都是 .post-with-sidebar 的直接子元素

OK,下面再来看 single.html 里面引用到的 partial 模块 sidebar-related-posts.html,在路径 layouts/partials/ 中创建侧边栏模板 sidebar-related-posts.html

sidebar-related-posts.html 里面的内容如下
go
{{ $currentPage := . }}
{{ $relatedPages := slice }}
{{ with $currentPage.GetTerms "categories" }}
{{ range . }}
{{ $relatedPages = $relatedPages | union .Pages }}
{{ end }}
{{ end }}
{{ if $relatedPages }}
<div class="sidebar-related">
<h4>相关分类文章</h4>
<ul>
{{ range first 10 (shuffle (uniq $relatedPages)) }}
{{ if ne .Permalink $currentPage.Permalink }}
<li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
{{ end }}
{{ end }}
</ul>
</div>
{{ end }}
这段侧边栏的模板可以在文章页面中,动态生成【相关文章】列表,其核心逻辑是找出与当前文章属于相同分类的其他文章,打乱顺序后,取最多 10 篇,排除自己这篇,作为相关推荐,下面来详细看下
第一部分:初始化变量
go
{{ $currentPage := . }}
将当前上下文(也就是当前文章页面)赋值给变量 $currentPage,方便后续引用
go
{{ $relatedPages := slice }}
创建一个空的 slice(Hugo 中的列表/数组),用于存放找到的相关文章
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog