VitePress 系列(1):样式美化

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
  }
}

这段代码的逻辑是这样的:

  1. 先定义一个动画样式变量 homePageStyle ,类型为 HTMLStyleElement
  2. 创建一个名为 updateHomePageStyle 的函数,函数的作用是根据传入的参数 value 来判断是否需要添加动画样式。如果 value 为真并且 homePageStyle 不存在,则创建一个新的样式元素 homePageStyle ,并设置样式内容为动画样式,使用我们之前创建的关键帧 rainbow 。然后将 homePageStyle 添加到 body 元素中。如果 value 为假,则移除样式元素
  3. 之后使用 watch 监听 路由是否变化,如果路由变化,则执行 updateHomePageStyle 函数,在当前页面是首页的情况下,给函数传 true,否则传 false

::: details 为什么不直接在全局样式中写 animation ?

主要是性能方面的考虑

如果直接在全局 CSS 中添加动画:

css 复制代码
:root {
  animation: rainbow 12s linear infinite;
}

那么这个动画会在所有页面都运行,即使你已经离开首页(/)进入其他页面。这会导致:

  • ❌ 动画资源浪费(即使不需要该动画时也持续运行)

  • ❌ 可能影响性能(尤其是复杂的动画或低端设备上)

我们当前代码中通过 Vuewatch 监听路由变化,并调用 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 年

容器颜色

vitePresstipwarningdanger 等容器的样式不太好看,这里我们参考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";
相关推荐
meng半颗糖1 小时前
vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度
前端·javascript·css·vue.js·elementui·vue3
teeeeeeemo2 小时前
CSS3 动画基础与技巧
前端·css·笔记·css3
年纪轻轻就扛不住2 小时前
CSS3 渐变效果
前端·css·css3
我科绝伦(Huanhuan Zhou)3 小时前
MOP数据库备份脚本生成工具
前端·css·数据库
海的诗篇_3 小时前
前端开发面试题总结-vue2框架篇(三)
前端·javascript·css·面试·vue·html
断竿散人3 小时前
⚡CSS动画性能优化:60fps丝滑体验的终极秘籍
前端·css·性能优化
默默地离开4 小时前
文档流之css布局块(盒子模型)
前端·css
markyankee1014 小时前
CSS 核心技术解析:从选择器到属性值的完整指南
css
Hilaku7 小时前
🧨公司非要用 Tailwind,我觉得这玩意儿不如 inline-style
前端·javascript·css