VitePress 系列(1):样式美化
主要是针对 vitePress
做的一些样式方面的美化,包括首页彩虹样式动画,以及markdown
方面的引用、容器、记号笔、代码块和代码组等功能的美化。
彩虹背景动画
在 UnoCSS 首页中,它的标题和图片背景有类似彩虹的渐变色动画
具体效果可以看下面这个 GIF
图:

效果还是挺明显的:左侧 UnoCSS
文字、Getting Started
按钮以及右侧 Logo
都有彩虹渐变背景的动画效果
我们同样可以实现这种效果
在 theme/style
新建 rainbow.css
文件,在 rainbow.css
中 写一个名为 rainbow
关键帧
::: details 点我查看代码 <<< @/.vitepress/theme/styles/rainbow.scss :::
接着使用这个关键帧
在 theme/index.ts
中写入代码
ts
/* .vitepress/theme/index.ts */ // [!code focus:3]
// 彩虹背景动画样式
let homePageStyle: HTMLStyleElement | undefined
export default {
extends: DefaultTheme,
enhanceApp({app , router }) {
// [!code focus:8]
// 彩虹背景动画样式
if (typeof window !== 'undefined') {
watch(
() => router.route.data.relativePath,
() => updateHomePageStyle(location.pathname === '/'),
{ immediate: true },
)
}
},
}
// [!code focus:18]
// 彩虹背景动画样式
function updateHomePageStyle(value: boolean) {
if (value) {
if (homePageStyle) return
homePageStyle = document.createElement('style')
homePageStyle.innerHTML = `
:root {
animation: rainbow 12s linear infinite;
}`
document.body.appendChild(homePageStyle)
} else {
if (!homePageStyle) return
homePageStyle.remove()
homePageStyle = undefined
}
}
这段代码的逻辑是这样的:
- 先定义一个动画样式变量
homePageStyle
,类型为HTMLStyleElement
- 创建一个名为
updateHomePageStyle
的函数,函数的作用是根据传入的参数value
来判断是否需要添加动画样式。如果value
为真并且homePageStyle
不存在,则创建一个新的样式元素homePageStyle
,并设置样式内容为动画样式,使用我们之前创建的关键帧rainbow
。然后将homePageStyle
添加到body
元素中。如果value
为假,则移除样式元素 - 之后使用
watch
监听 路由是否变化,如果路由变化,则执行updateHomePageStyle 函数
,在当前页面是首页的情况下,给函数传true
,否则传false
::: details 为什么不直接在全局样式中写 animation ?
主要是性能方面的考虑
如果直接在全局 CSS
中添加动画:
css
:root {
animation: rainbow 12s linear infinite;
}
那么这个动画会在所有页面都运行,即使你已经离开首页(/)
进入其他页面。这会导致:
-
❌ 动画资源浪费(即使不需要该动画时也持续运行)
-
❌ 可能影响性能(尤其是复杂的动画或低端设备上)
我们当前代码中通过 Vue
的 watch
监听路由变化,并调用 updateHomePageStyle(location.pathname === "/")
实现了以下效果:
-
✔️ 按需加载动画,提升性能
只在访问首页
/
时才插入带有动画的<style>
标签,当用户浏览其他页面时,动态移除动画样式,这样可以避免不必要的资源消耗,提升性能 -
✔️ 精确控制动画生命周期
通过手动控制动画样式的添加与移除,可以确保动画状态始终与当前页面匹配,避免出现"页面已切换但动画仍在运行"的不一致行为
💡 类似场景举例
这种做法常见于以下场景:
- 首页背景动画
- 页面加载特效
- 某些页面独有的交互动画
A/B
测试中的特定样式注入
:::
引用颜色更改
在 Markdown
中,我们常用的引用符号是 >
,关于引用的样式我们我们可以稍微改动一下
在 theme/style
新建 blockquote.css
文件,并且复制下面代码,粘贴到 blockquote.css
中
css
/* .vitepress/theme/style/blockquote.css */
.vp-doc blockquote {
border-radius: 10px;
padding: 18px 20px 20px 15px;
position: relative;
background-color: var(--vp-c-gray-soft);
border-left: 6px solid var(--vp-c-green-2);
}
然后在 index.css
中引入生效
css
/* .vitepress/theme/style/index.css */
@import "./blockquote.css";
输入:
md
> 更新时间:2024 年
输出:
更新时间:2024 年
容器颜色
vitePress
中 tip
、warning
、danger
等容器的样式不太好看,这里我们参考Vuepress/hope 主题的容器颜色去实现一套我们自己的方案
在 theme/style
新建 custom-block.css
文件,复制下面代码,粘贴到 custom-block.css
中
::: details 点我查看代码
<<< @/.vitepress/theme/styles/custom-block.scss
:::
更改之前效果:

更改之后效果:

更改之后加了左边框、图标,看着好看多了
导航毛玻璃
在 theme/style
文件夹,然后新建 blur.css
并填入如下代码
css
/* .vitepress\theme\style\blur.css */
:root {
/* 首页下滑后导航透明 */
.VPNavBar:not(.has-sidebar):not(.home.top) {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* 搜索框透明 */
.DocSearch-Button {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
/* Feature透明 */
.VPFeature {
border: none;
box-shadow: 0 10px 30px 0 rgb(0 0 0 / 15%);
background-color: transparent;
}
/* 文档页侧边栏顶部透明 */
.curtain {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
@media (min-width: 960px) {
/* 文档页导航中间透明 */
.VPNavBar:not(.home.top) .content-body {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
}
/* 移动端大纲栏透明 */
.VPLocalNav {
background-color: rgba(255, 255, 255, 0);
backdrop-filter: blur(10px);
}
}
最后引入 index.css
中 即可看到效果
css
/* style/index.css */
@import "./blur.css";
更改之前效果:

更改之后效果:

相比较更改之前导航栏纯白的背景,更改之后的导航栏有一个毛玻璃的效果,体验感会更好
记号笔
在某些整段的文字中,我们可以用记号笔,划出重点。这里的记号笔效果参考了尤大的个人主页
在 theme/style
新建 marker.css
文件,将下面代码,复制粘贴到 marker.css
中
css
/* .vitepress/theme/style/marker.css */
/* 尤雨溪主页记号笔效果 不喜欢可自行调整 */
.marker {
white-space: nowrap;
position: relative;
}
.marker:after {
content: "";
position: absolute;
z-index: -1;
top: 66%;
left: 0em;
right: 0em;
bottom: 0;
transition: top 200ms cubic-bezier(0, 0.8, 0.13, 1);
background-color: rgba(79, 192, 141, 0.5);
}
.marker:hover:after {
top: 0%;
}
然后在 index.css
中引入生效
css
/* .vitepress/theme/style/index.css */
@import "./marker.css";
输入:
md
<sapn class="marker">这里是尤雨溪的主页样式,鼠标放在我上面看效果</sapn>
输出:
这里是尤雨溪的主页样式,鼠标放在我上面看效果
代码块
将代码块改成 Mac 风格,三个小圆点
在 .vitepress/theme/style
目录新建一个 vp-code.css
文件,复制下面代码,粘贴到 vp-code.css
保存
css
/* .vitepress/theme/style/vp-code.css */
/* 代码块:增加留空边距 增加阴影 */
.vp-doc div[class*="language-"] {
box-shadow: 0 10px 30px 0 rgb(0 0 0 / 40%);
padding-top: 20px;
}
/* 代码块:添加macOS风格的小圆点 */
.vp-doc div[class*="language-"]::before {
content: "";
display: block;
position: absolute;
top: 12px;
left: 12px;
width: 12px;
height: 12px;
background-color: #ff5f56;
border-radius: 50%;
box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
z-index: 1;
}
/* 代码块:下移行号 隐藏右侧竖线 */
.vp-doc .line-numbers-wrapper {
padding-top: 40px;
border-right: none;
}
/* 代码块:重建行号右侧竖线 */
.vp-doc .line-numbers-wrapper::after {
content: "";
position: absolute;
top: 40px;
right: 0;
border-right: 1px solid var(--vp-code-block-divider-color);
height: calc(100% - 60px);
}
.vp-doc div[class*="language-"].line-numbers-mode {
margin-bottom: 20px;
}
然后在 index.css
中引入生效
css
/* .vitepress/theme/style/index.css */
@import "./vp-code.css";
更改之前效果:

更改之后效果:

更改之后加了边框阴影和顶部左侧的小圆点,更好看了
代码组
在更改代码块的基础上,更改代码组样式
在 .vitepress/theme/style
目录新建一个 vp-code-group.css
文件,复制下面代码,粘贴到 vp-code-group.css
保存
css
/* .vitepress/theme/style/vp-code-group.css */
/* 代码组:tab间距 */
.vp-code-group .tabs {
padding-top: 20px;
}
/* 代码组:添加样式及阴影 */
.vp-code-group {
color: var(--vp-c-black-soft);
border-radius: 8px;
box-shadow: 0 10px 30px 0 rgb(0 0 0 / 40%);
}
/* 代码组:添加macOS风格的小圆点 */
.vp-code-group .tabs::before {
content: " ";
position: absolute;
top: 12px;
left: 12px;
height: 12px;
width: 12px;
background: #fc625d;
border-radius: 50%;
box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
}
/* 代码组:修正倒角、阴影、边距 */
.vp-code-group div[class*="language-"].vp-adaptive-theme.line-numbers-mode {
border-radius: 8px;
box-shadow: none;
padding-top: 0px;
}
/* 代码组:隐藏小圆点 */
.vp-code-group div[class*="language-"].vp-adaptive-theme.line-numbers-mode::before {
display: none;
}
/* 代码组:修正行号位置 */
.vp-code-group .line-numbers-mode .line-numbers-wrapper {
padding-top: 20px;
}
/* 代码组:修正行号右侧竖线位置 */
.vp-code-group .line-numbers-mode .line-numbers-wrapper::after {
top: 24px;
height: calc(100% - 45px);
}
/* 代码组(无行号):修正倒角、阴影、边距 */
.vp-code-group div[class*="language-"].vp-adaptive-theme {
border-radius: 8px;
box-shadow: none;
padding-top: 0px;
}
/* 代码组(无行号):隐藏小圆点 */
.vp-code-group div[class*="language-"].vp-adaptive-theme::before {
display: none;
}
然后在 index.css
中引入生效
css
/* .vitepress/theme/style/index.css */
@import "./vp-code-group.css";