前言

最近我在博客中开辟了一个新栏目——“Admire”

为了庄重地记录这些人物,我不想只写一篇普通的流水账文章,而是希望它像一张“人物名片”:平时简洁明了,点击后能展开详细的生平往事。同时,为了尊重图片版权,我还特别设计了杂志风格的悬停版权标识。

今天就分享一下如何在 Hexo (以 Butterfly 主题为例) 中实现这个功能。


效果预览

  • 卡片布局:左图右文,展示姓名、生卒年和荣誉标签。
  • 交互详情:点击卡片底部,平滑展开时间轴风格的生平事迹。
  • 版权保护:鼠标悬停在头像上时,底部优雅浮现图片作者和协议链接。

实现步骤

我们将采用模块化的思路,把样式(CSS)和逻辑(JS)分离,这样以后新建人物页面时,只需要复制 HTML 模板即可。

第一步:编写通用 CSS

在博客根目录 source/css/ 下新建文件 admire.css

这个文件定义了卡片的布局、黑白滤镜效果、展开动画以及那层“杂志级”的渐变版权遮罩。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* source/css/admire.css */

.admire-container {
max-width: 100%;
margin: 20px auto;
color: var(--font-color);
}

/* 卡片主体 */
.admire-card {
display: flex;
background: var(--card-bg);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
cursor: pointer;
border: 1px solid var(--borderColor);
position: relative;
}

/* 左侧头像区域 */
.admire-portrait {
width: 180px;
min-height: 220px;
flex-shrink: 0;
position: relative; /* 关键:为版权绝对定位做参照 */
background-color: #333;
}

.admire-portrait img {
width: 100%;
height: 100%;
object-fit: cover;
filter: grayscale(100%); /* 默认黑白 */
transition: filter 0.5s ease;
margin: 0 !important;
display: block;
}

.admire-card:hover .admire-portrait img {
filter: grayscale(0%); /* 悬停彩色 */
}

/* 版权标识(悬停浮现) */
.admire-credit {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 100%);
padding: 20px 10px 5px 0;
text-align: right;
opacity: 0;
transform: translateY(5px);
transition: all 0.3s ease;
pointer-events: none;
z-index: 10;
}

.admire-portrait:hover .admire-credit {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}

.admire-credit a {
color: rgba(255, 255, 255, 0.8) !important;
font-size: 10px;
text-decoration: none !important;
}

/* 右侧信息与详情展开样式 */
.admire-info {
padding: 20px 30px;
display: flex;
flex-direction: column;
justify-content: center;
flex-grow: 1;
}

.admire-name {
font-size: 2.2em;
font-weight: 700;
margin: 0 0 5px 0;
line-height: 1.2;
}

.admire-years {
font-size: 14px;
opacity: 0.7;
letter-spacing: 1px;
margin-bottom: 15px;
font-family: monospace;
}

.admire-details {
max-height: 0;
overflow: hidden;
opacity: 0;
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
margin-top: 20px;
border-left: 2px solid var(--borderColor);
margin-left: 25px;
padding-left: 30px;
}

.admire-details.open {
max-height: 3000px;
opacity: 1;
margin-bottom: 40px;
}
````

### 第二步:编写交互 JS

在 `source/js/` 下新建文件 `admire.js`。

这段代码非常简单,只负责处理点击时的 CSS 类名切换。

```javascript
/* source/js/admire.js */
function toggleAdmireDetails(cardElement) {
const details = cardElement.nextElementSibling;

if (!details || !details.classList.contains('admire-details')) return;

// 切换箭头旋转状态
cardElement.classList.toggle('active');

// 切换内容展开状态
if (details.classList.contains('open')) {
details.classList.remove('open');
} else {
details.classList.add('open');
}
}

第三步:配置主题引入

Butterfly 主题为例,打开主题配置文件 _config.butterfly.yml,找到 inject 配置项:

1
2
3
4
5
inject:
head:
- <link rel="stylesheet" href="/css/admire.css">
bottom:
- <script src="/js/admire.js"></script>

提示:如果你使用的是其他主题,也可以直接在 Markdown 文件的最顶部手动写入这两行 HTML 代码。


如何使用

现在配置都完成了,以后每次要写新人物时,只需要按以下格式新建页面即可。

  • 建议路径source/admire/人物拼音/index.md

Markdown 模板

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
---
title: "我所敬佩的人:某某某"
layout: page
aside: false
---

<div class="admire-container">

<div class="admire-card" onclick="toggleAdmireDetails(this)">
<div class="admire-portrait">
<img src="图片链接" alt="人物名">

<div class="admire-credit">
<a href="来源链接" target="_blank">© 作者 / 协议</a>
</div>
</div>

<div class="admire-info">
<h2 class="admire-name">人物名</h2>
<div class="admire-years">19xx — 20xx</div>
<div class="admire-action">点击查看生平往事</div>
</div>
</div>

<div class="admire-details">
<div class="admire-timeline-item">
<div class="admire-year-heading">年份</div>
<div class="admire-content">事迹内容...</div>
</div>
</div>

</div>

⚠️ 避坑指南:缩进问题

这是我在开发过程中踩过最大的坑!

在 Markdown 中写 HTML 时,千万不要缩进!千万不要缩进!

❌ 错误写法(会被渲染成代码块):

1
2
<div class="admire-container">
<div class="admire-card">

✅ 正确写法(顶格写):

1
2
<div class="admire-container">
<div class="admire-card">

如果你的页面显示出了黑底的代码文字,请在编辑器中选中所有 HTML 代码,按 Shift + Tab 直到它们全部顶格。


结语

通过这次折腾,不仅美化了博客,更学会了如何用技术手段优雅地展示内容。希望这个教程对想做类似栏目的朋友有帮助!