六月十二日

六月十二日

Jun 12 ·
7 Min Read

日记

今天继续捣鼓博客,不过最终证明还是白忙活一场。甚至不得不在 GiHub 网页的 CodeSpace 里回滚到之前版本。

# 1. 强制回滚到指定版本(hash 可以只写前 7 位)
git reset --hard 5ed640a
# 2. 强制推送到 GitHub(覆盖远程仓库)
git push --force

🛠️ Slate Blog 自定义修改指南

项目地址: SlateDesign/slate-blog

本文档汇总了对 Slate Blog 主题的所有自定义修改代码。你可以直接复制以下代码块应用到对应文件中。

📑 目录

  1. 全局字体配置
  2. 自定义 CSS 样式
  3. 头像组件重构
  4. 首页布局升级
  5. 交互脚本注入
  6. 新增文章列表页
  7. 修改汇总概览

1. 全局字体配置

📂 文件: src/assets/style/common.css
📝 操作: 在文件开头添加以下代码

/* ==========================================
全局字体声明 (作用于主页和所有页面)
========================================== */
@font-face {
font-family: 'StarRail';
src: url('/fonts/StarRailttf.otf') format('opentype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* 强制全局所有元素使用星穹铁道字体 */
html, body, body * {
font-family: 'StarRail', system-ui, -apple-system, sans-serif !important;
}
/* ==========================================
↓ 下面是 common.css 原来的代码,请保持不动 ↓
========================================== */

2. 自定义 CSS 样式

📂 文件: src/assets/style/blog.css
📝 操作: 在文件末尾追加以下代码

/* ================= 新增自定义样式 ================= */
/* 1. 剧透文本样式 (Spoiler) */
.spoiler {
filter: blur(5px);
background-color: rgba(128, 128, 128, 0.2);
border-radius: 3px;
transition: filter 0.4s ease, background-color 0.4s ease;
cursor: pointer;
padding: 0 2px;
}
@media (hover: hover) {
.spoiler:not(.revealed):hover {
filter: blur(0);
background-color: transparent;
}
}
.spoiler.revealed {
filter: blur(0) !important;
background-color: transparent !important;
}
/* 2. 红色光晕特效 (Red Glow) */
.red-glow {
display: inline-block;
padding: 2px 4px;
box-shadow:
0 0 10px 5px rgba(255, 0, 0, 0.8),
0 0 20px 8px rgba(255, 0, 0, 0.6),
0 0 30px 12px rgba(255, 0, 0, 0.4);
}
/* 3. 优惠/折扣高亮 (Discount Highlight) */
.highlight-discount {
display: inline;
padding: 4px 8px;
border-radius: 8px;
background-color: #f8d7da;
color: #dc3545;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}
/* 4. Bearblog 风格柔和高亮 (Bear Highlight) */
.highlight-bear {
display: inline;
padding: 4px 8px;
border-radius: 8px;
background-color: #EDEDEB;
color: #DE6E7A;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}
/* 5. 红色粗下划线 (Underline) */
.highlight-underline {
text-decoration: underline;
text-decoration-color: #dc3545;
text-decoration-thickness: 2px;
}
/* 6. 原生 Mark 标签荧光笔效果 */
mark {
margin: 0 -0.4em;
padding: 0em 0.4em;
border-radius: 0.8em 0.3em;
background: transparent;
background-image: linear-gradient(
to right,
rgba(255, 225, 0, 0.1),
rgba(255, 225, 0, 0.7) 4%,
rgba(255, 225, 0, 0.3)
);
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}

3. 头像组件重构

3.1 更新 Header 组件

📂 文件: src/components/layouts/Header.astro
📝 操作: 完全替换原有内容

---
import slateConfig from '~@/slate.config';
import Avatar from '../Avatar/Avatar.astro';
interface Props {
avatar?: string;
avatarBack?: string;
}
const {
avatar = slateConfig.avatar!,
avatarBack = slateConfig.avatarBack || slateConfig.avatar!
} = Astro.props;
---
<header>
<div class="mb-9">
<Avatar
frontSrc={avatar}
backSrc={avatarBack}
alt={slateConfig.title}
size={56}
/>
</div>
</header>

3.2 新建 Avatar 组件

📂 文件: src/components/Avatar/Avatar.astro
📝 操作: 🆕 新建文件

---
import slateConfig from '~@/slate.config';
interface Props {
frontSrc?: string;
backSrc?: string;
alt?: string;
size?: number;
}
const {
frontSrc = slateConfig.avatar!,
backSrc = slateConfig.avatarBack || slateConfig.avatar!,
alt = slateConfig.title,
size = 56,
} = Astro.props;
const sizePx = `${size}px`;
---
<div class="avatar-flip-container" style={`width: ${sizePx}; height: ${sizePx};`}>
<div class="avatar-flipper">
<div class="avatar-front">
<img
src={frontSrc}
alt={alt}
class="avatar-img"
width={size}
height={size}
loading="eager"
/>
</div>
<div class="avatar-back">
<img
src={backSrc}
alt={`${alt} (back)`}
class="avatar-img"
width={size}
height={size}
loading="lazy"
/>
</div>
</div>
</div>
<style>
.avatar-flip-container {
perspective: 1000px;
cursor: pointer;
flex-shrink: 0;
display: inline-block;
}
.avatar-flipper {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
transform-style: preserve-3d;
}
.avatar-flip-container.flipped .avatar-flipper {
transform: rotateY(180deg);
}
.avatar-front,
.avatar-back {
position: absolute;
inset: 0;
backface-visibility: hidden;
border-radius: 50%;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
}
.avatar-back {
transform: rotateY(180deg);
}
.avatar-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
border-radius: 50%;
}
</style>
<script>
const containers = document.querySelectorAll('.avatar-flip-container');
containers.forEach(container => {
container.addEventListener('click', () => {
container.classList.toggle('flipped');
});
});
</script>

4. 首页布局升级

📂 文件: src/pages/index.astro
📝 操作: 完全替换原有内容

---
import { getCollection } from 'astro:content';
import i18next from '@/i18n';
import Search from '@/components/search';
import PageLayout from '@/components/layouts/PageLayout.astro';
import slateConfig from '~@/slate.config';
const postCollection = await getCollection('post', ({ data }) => {
return import.meta.env.DEV || data.draft !== true;
});
const tagCounts = postCollection.reduce<Record<string, number>>(
(res, post) => {
const postTags = post.data.tags;
if (!postTags || !postTags.length) return res;
postTags.forEach((tag) => {
if (tag.trim() === '') return;
if (res[tag]) { res[tag]++; } else { res[tag] = 1; }
});
return res;
},
{ [i18next.t('common.all')]: postCollection.length },
);
const tags = Object.keys(tagCounts).map((tag) => ({ name: tag, count: tagCounts[tag] }));
const posts = [...postCollection]
.sort((a, b) => {
const dateA = (a.data.pubDate || a.data.published || new Date(0)).getTime();
const dateB = (b.data.pubDate || b.data.published || new Date(0)).getTime();
return dateB - dateA;
})
.map((post) => ({
id: post.id,
slug: post.slug,
url: `/blog/${post.data.permalink || post.slug}`,
data: post.data,
displayDate: post.data.pubDate || post.data.published,
}));
---
<PageLayout>
<!-- 顶部区域布局 -->
<section class="relative mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between sm:mb-10">
<div class="flex flex-col gap-3">
<!-- 🟢 终端胶囊 1:标题 (更大尺寸 + 宽度自适应) -->
<div class="inline-flex w-fit items-center gap-2.5 rounded-full border border-border/40 bg-muted/20 px-5 py-2 font-mono text-base shadow-sm transition-all hover:shadow-md dark:border-slate-700/80 dark:bg-slate-900/70 sm:text-lg">
<!-- 粉色脉冲圆点 --> <span class="relative flex h-3 w-3">
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-pink-400 opacity-75"></span>
<span class="relative inline-flex h-3 w-3 rounded-full bg-pink-500 shadow-[0_0_8px_rgba(236,72,153,0.6)]"></span>
</span>
<span class="text-pink-500 font-bold">~</span>
<span class="font-medium text-slate-800 dark:text-slate-200">{slateConfig.title}</span>
<span class="text-slate-400 dark:text-slate-500">$</span>
</div>
<!-- 🔵 终端胶囊 2:描述 (更大尺寸 + 宽度自适应) -->
<div class="inline-flex w-fit items-center gap-2.5 rounded-full border border-border/40 bg-muted/20 px-5 py-2 font-mono text-sm shadow-sm transition-all hover:shadow-md dark:border-slate-700/80 dark:bg-slate-900/70 sm:text-base">
<!-- 蓝色脉冲圆点 -->
<span class="relative flex h-2.5 w-2.5">
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-blue-400 opacity-75"></span>
<span class="relative inline-flex h-2.5 w-2.5 rounded-full bg-blue-500 shadow-[0_0_8px_rgba(59,130,246,0.6)]"></span>
</span>
<span class="text-blue-500 font-bold">~</span>
<span class="text-slate-600 dark:text-slate-400">{slateConfig.description}</span>
<span class="text-slate-400 dark:text-slate-500">$</span>
</div>
</div>
<!-- 搜索框 -->
<div class="w-full sm:w-auto sm:min-w-[240px]">
<Search client:only="react" className="w-full sm:w-auto" />
</div>
</section>
<!-- 文章列表 -->
<section class="mb-16">
<div class="text-base text-slate12">
{posts.map((item) => (
<a class="flex cursor-pointer flex-col justify-between rounded-lg py-2.5 transition-all active:scale-[0.995] active:bg-slate4 sm:flex-row sm:items-center sm:px-2 sm:hover:bg-slate3" href={item.url} title={item.data.title}>
<span class="shrink-0">{item.data.title}</span>
<span class="mx-8 hidden h-px w-full grow border-t border-dashed border-slate6 sm:flex" />
<span class="shrink-0 text-slate8">
{item.displayDate?.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}
</span>
</a>
))}
</div>
</section>
<!-- 标签列表 - 已修复点击功能,All 标签跳转到首页 -->
<section class="mb-16">
<ul class="flex flex-wrap gap-2 text-base text-slate10">
{
tags.map(({ name, count }) => { const isAllTag = name === i18next.t('common.all');
return (
<li>
<a
href={isAllTag ? '/' : `/tags/${encodeURIComponent(name.toLowerCase().replace(/\s+/g, '-'))}`}
class="block cursor-pointer rounded-full bg-slate3 px-4 py-2 text-slate10 transition-all hover:bg-slate4 hover:text-slate11"
>
{name}
<sup class="text-[10px] text-slate8">{count}</sup>
</a>
</li>
);
})
}
</ul>
</section>
</PageLayout>

5. 交互脚本注入

📂 文件: src/components/layouts/PageLayout.astro
📝 操作: 在 </body> 标签前追加以下脚本

<!-- 剧透文本点击揭晓交互 -->
<script is:inline>
document.addEventListener('DOMContentLoaded', () => {
const spoilers = document.querySelectorAll('.spoiler');
spoilers.forEach(spoiler => {
spoiler.addEventListener('click', function() {
this.classList.toggle('revealed');
});
});
});
</script>

6. 修改汇总概览

文件路径操作类型主要修改内容
src/assets/style/common.css✏️ 追加全局字体声明 (StarRail)
src/assets/style/blog.css✏️ 追加6 种自定义高亮/特效样式
src/components/layouts/Header.astro🔄 替换集成新的 Avatar 组件
src/components/Avatar/Avatar.astro🆕 新建3D 翻转头像组件
src/pages/index.astro🔄 替换终端胶囊风格首页布局
src/components/layouts/PageLayout.astro✏️ 追加Spoiler 点击交互脚本
Last edited Jun 12