给目录添加样式,优化所有css样式

This commit is contained in:
lsy 2025-05-21 14:43:35 +08:00
parent 1e624c7169
commit 02aaa16629
8 changed files with 315 additions and 417 deletions

View File

@ -303,85 +303,6 @@ const hasActiveNavItem = activeItem || activeGroupId || activeSubItem ? true : f
</nav>
</header>
<style is:global>
/* 汉堡菜单动画样式 */
.hamburger-menu {
width: 24px;
height: 24px;
position: relative;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.hamburger-line {
width: 100%;
height: 2px;
background-color: currentColor;
border-radius: 2px;
transition: all 0.3s ease;
transform-origin: center;
}
/* 菜单打开时的样式 */
[aria-expanded="true"] .hamburger-menu .line-1 {
transform: translateY(8px) rotate(45deg);
}
[aria-expanded="true"] .hamburger-menu .line-2 {
opacity: 0;
}
[aria-expanded="true"] .hamburger-menu .line-3 {
transform: translateY(-8px) rotate(-45deg);
}
/* 移动端子菜单展开动画 */
.mobile-menu-arrow {
transition: transform 0.3s ease;
}
/* 移动端菜单图标容器 */
.mobile-menu-icon {
position: relative;
transition: transform 0.3s ease;
}
/* 子菜单展开/收起动画 - 完全重写 */
.mobile-submenu {
height: auto;
max-height: 0;
visibility: hidden;
opacity: 0;
overflow: hidden;
transform: translateY(-10px);
transition:
max-height 0.3s ease,
opacity 0.3s ease,
transform 0.3s ease,
visibility 0s linear 0.3s, /* 延迟visibility变化 */
padding 0.3s ease;
padding-top: 0;
padding-bottom: 0;
}
.mobile-submenu.menu-visible {
max-height: 500px; /* 足够大以容纳所有内容 */
visibility: visible;
opacity: 1;
transform: translateY(0);
transition:
max-height 0.3s ease,
opacity 0.3s ease,
transform 0.3s ease,
visibility 0s linear 0s, /* 立即改变visibility */
padding 0.3s ease;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
</style>
<script is:inline>
// 导航逻辑 - 自销毁模式
(function() {

View File

@ -174,7 +174,7 @@ function getArticleUrl(articleId: string) {
// 预先生成目录结构
function generateTableOfContents(headings: Heading[]) {
if (!headings || headings.length === 0) {
return '<p class="text-secondary-500 dark:text-secondary-400 italic">此文章没有目录</p>';
return '<p class="text-gray-500 dark:text-gray-400 italic">此文章没有目录</p>';
}
// 查找最低级别的标题(数值最小)
@ -232,7 +232,7 @@ function generateTableOfContents(headings: Heading[]) {
if (items.length === 0) return '';
const isTopLevel = level === 0;
let html = `<ul class="space-y-2 toc-list ${isTopLevel ? '' : 'toc-sublist hidden'}" ${level > 0 ? 'aria-expanded="false"' : ''}>`;
let html = `<ul class="toc-list space-y-2 ${isTopLevel ? '' : 'toc-sublist hidden'}" ${level > 0 ? 'aria-expanded="false"' : ''}>`;
items.forEach(item => {
const hasChildren = item.children && item.children.length > 0;
@ -241,15 +241,15 @@ function generateTableOfContents(headings: Heading[]) {
html += `<li class="toc-item" data-depth="${item.depth}">
<div class="toc-item-container">
<a href="#${item.slug}"
class="toc-link block duration-50 ${
class="toc-link ${
isHigherLevel
? "text-secondary-800 dark:text-secondary-200 font-medium"
: "text-secondary-600 dark:text-secondary-400"
}"
? "text-gray-800 dark:text-gray-200 font-medium"
: "text-gray-600 dark:text-gray-400"
} hover:text-primary-600 dark:hover:text-primary-400"
style="padding-left: ${item.depth * 0.75}rem;">
${item.text}
</a>
${hasChildren ? `<button class="toc-toggle ml-1 p-1 text-secondary-400 hover:text-primary-600 dark:hover:text-primary-400" aria-expanded="false">
${hasChildren ? `<button class="toc-toggle text-gray-400 hover:text-primary-600 dark:hover:text-primary-400 ml-1 p-1" aria-expanded="false">
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
@ -531,34 +531,21 @@ const tableOfContents = generateTableOfContents(headings);
<!-- 目录 -->
<section
class="hidden 2xl:block"
class="hidden 2xl:block fixed right-[calc(50%-44rem)] top-20 w-64 z-30 transition-transform duration-300"
id="toc-panel"
>
<div>
<div
class="panel-header"
>
<h3>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h7"
></path>
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl flex flex-col backdrop-blur-sm bg-opacity-95 dark:bg-opacity-95 shadow-lg transition-opacity duration-300">
<div class="border-b border-gray-200 dark:border-gray-700 p-4 pb-3 sticky top-0 z-10 rounded-t-xl bg-white dark:bg-gray-800 bg-opacity-95 backdrop-blur-sm">
<h3 class="font-bold text-primary-700 dark:text-primary-400 flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"></path>
</svg>
文章目录
</h3>
</div>
<div
id="toc-content"
class="scrollbar-thin scrollbar-thumb-primary-200 dark:scrollbar-thumb-primary-800 scrollbar-track-transparent"
class="text-sm p-4 pt-2 overflow-y-auto max-h-[calc(100vh-8rem-42px)] bg-white dark:bg-gray-800 scroll-smooth scrollbar-thin scrollbar-thumb-primary-200 dark:scrollbar-thumb-primary-800 scrollbar-track-transparent"
set:html={tableOfContents}
>
</div>
@ -783,10 +770,8 @@ const tableOfContents = generateTableOfContents(headings);
function checkTocVisibility() {
if (window.innerWidth < 1536) {
tocPanel.classList.add("hidden");
tocPanel.classList.remove("2xl:block");
} else {
tocPanel.classList.remove("hidden");
tocPanel.classList.add("2xl:block");
}
}
@ -804,23 +789,21 @@ const tableOfContents = generateTableOfContents(headings);
const expanded = toggle.getAttribute("aria-expanded") === "true";
toggle.setAttribute("aria-expanded", expanded ? "false" : "true");
// 更新图标旋转
const svg = toggle.querySelector("svg");
if (svg) {
svg.style.transform = expanded ? "" : "rotate(-180deg)";
}
// 切换子菜单显示状态
const listItem = toggle.closest(".toc-item");
if (listItem) {
const sublist = listItem.querySelector(".toc-sublist");
if (sublist) {
if (expanded) {
// 收起子菜单
sublist.classList.add("hidden");
sublist.setAttribute("aria-expanded", "false");
toggle.querySelector("svg").classList.remove("rotate-180");
} else {
// 展开子菜单
sublist.classList.remove("hidden");
sublist.setAttribute("aria-expanded", "true");
toggle.querySelector("svg").classList.add("rotate-180");
}
}
}
@ -849,6 +832,7 @@ const tableOfContents = generateTableOfContents(headings);
behavior: "smooth",
});
// 增强高亮效果
targetElement.classList.add(
"bg-primary-50",
"dark:bg-primary-900/20",
@ -856,7 +840,7 @@ const tableOfContents = generateTableOfContents(headings);
setTimeout(() => {
targetElement.classList.remove(
"bg-primary-50",
"dark:bg-primary-900/20",
"dark:bg-primary-900/20"
);
}, 2000);
}
@ -876,14 +860,15 @@ const tableOfContents = generateTableOfContents(headings);
article.querySelectorAll("h1, h2, h3, h4, h5, h6"),
);
const tocLinks = Array.from(tocContent.querySelectorAll(".toc-link"));
const tocItems = Array.from(tocContent.querySelectorAll(".toc-item"));
// 清除所有活动状态
tocLinks.forEach((link) => {
// 移除活动类
link.classList.remove(
"toc-link-active",
"text-primary-600",
"dark:text-primary-400",
"font-medium",
"font-medium"
);
});
@ -914,9 +899,10 @@ const tableOfContents = generateTableOfContents(headings);
if (activeLink) {
// 高亮当前目录项
activeLink.classList.add(
"toc-link-active",
"text-primary-600",
"dark:text-primary-400",
"font-medium",
"font-medium"
);
// 展开当前激活项的所有父菜单并收集到活动项集合中
@ -929,15 +915,13 @@ const tableOfContents = generateTableOfContents(headings);
const parentToggle = parent.querySelector(".toc-toggle");
if (parentSublist && parentSublist.classList.contains("hidden")) {
// 使用平滑动画展开
parentSublist.classList.remove("hidden");
parentSublist.setAttribute("aria-expanded", "true");
if (parentToggle) {
parentToggle.setAttribute("aria-expanded", "true");
const svg = parentToggle.querySelector("svg");
if (svg) {
svg.style.transform = "rotate(-180deg)";
}
parentToggle.querySelector("svg")?.classList.add("rotate-180");
}
}
@ -945,28 +929,42 @@ const tableOfContents = generateTableOfContents(headings);
parent = parent.parentElement?.closest(".toc-item");
}
// 确保当前激活的目录项在可视区域内
const tocContainer = tocContent;
if (tocContainer) {
const linkOffsetTop = activeLink.offsetTop;
const containerScrollTop = tocContainer.scrollTop;
const containerHeight = tocContainer.clientHeight;
// 如果当前项不在视口内,滚动目录
if (
linkOffsetTop < containerScrollTop ||
linkOffsetTop > containerScrollTop + containerHeight
) {
tocContainer.scrollTop =
linkOffsetTop - containerHeight / 2;
// 确保当前激活的目录项在可视区域内 - 添加平滑滚动
setTimeout(() => {
// 延迟执行确保DOM已更新
if (tocContent) {
// 重新计算activeLink的位置因为父菜单可能已展开
const linkRect = activeLink.getBoundingClientRect();
const containerRect = tocContent.getBoundingClientRect();
// 检查当前项是否在目录容器的可视区域内
const isInView = (
linkRect.top >= containerRect.top &&
linkRect.bottom <= containerRect.bottom
);
// 如果当前激活项不在视口内,滚动目录
if (!isInView) {
// 计算滚动位置,使激活项在容器中居中
const scrollTop = tocContent.scrollTop +
(linkRect.top - containerRect.top) -
(containerRect.height / 2) +
(linkRect.height / 2);
tocContent.scrollTo({
top: scrollTop,
behavior: "smooth"
});
}
}
}
}, 100); // 添加短延迟确保DOM已更新
}
}
}
// 关闭不在当前活动路径上的所有子菜单
tocItems.forEach(item => {
// 关闭不在当前活动路径上的所有子菜单 - 使用平滑动画
const allItems = Array.from(tocContent.querySelectorAll(".toc-item"));
allItems.forEach(item => {
// 如果不在活动路径上且有子菜单
if (!activeItems.has(item)) {
const sublist = item.querySelector('.toc-sublist');
@ -978,10 +976,7 @@ const tableOfContents = generateTableOfContents(headings);
if (toggle) {
toggle.setAttribute('aria-expanded', 'false');
const svg = toggle.querySelector('svg');
if (svg) {
svg.style.transform = '';
}
toggle.querySelector("svg")?.classList.remove("rotate-180");
}
}
}

View File

@ -1,78 +1,56 @@
/* 基础Mermaid样式覆盖 */
.mermaid {
.mermaid * {
background-color: transparent !important;
}
/* Mermaid文本颜色统一 */
.mermaid .label,
.mermaid text,
.mermaid span,
.mermaid .messageText,
.mermaid .loopText,
.mermaid .noteText,
.mermaid .taskText {
.mermaid :is(text, span, div,span,p) {
color: var(--color-secondary-800) !important;
fill: var(--color-secondary-800) !important;
font-family: inherit !important;
}
/* 添加edgeLabel文本颜色样式 */
.mermaid .edgeLabel,
.mermaid .edgeLabel p,
.mermaid .edgeLabel span {
.mermaid :is(.edgeLabel, .edgeLabel p, .edgeLabel div, .edgeLabel span) {
color: var(--color-secondary-800) !important;
fill: var(--color-secondary-800) !important;
background-color: transparent !important;
}
/* 节点样式设置 */
.mermaid .node rect,
.mermaid .node circle,
.mermaid .node ellipse,
.mermaid .node polygon,
.mermaid .node path {
.mermaid :is(.node rect, .node circle, .node ellipse, .node polygon, .node path) {
fill: var(--color-gray-100) !important;
stroke: var(--color-gray-400) !important;
stroke-width: 1px !important;
}
/* 连接线样式 */
.mermaid .edgePath .path,
.mermaid .flowchart-link,
.mermaid line,
.mermaid .messageLine0,
.mermaid .messageLine1 {
.mermaid :is(.edgePath .path, .flowchart-link, line, .messageLine0, .messageLine1) {
stroke: var(--color-gray-600) !important;
stroke-width: 1px !important;
fill: none !important; /* 确保线条没有填充 */
}
/* 箭头填充 */
.mermaid .arrowheadPath,
.mermaid marker path {
.mermaid :is(.arrowheadPath, marker path) {
fill: var(--color-gray-600) !important;
stroke: none !important;
}
/* 文本标签背景 */
.mermaid .edgeLabel rect,
.mermaid .labelBox {
.mermaid :is(.edgeLabel rect, .labelBox) {
fill: white !important;
background-color: white !important;
}
/* 标题样式 */
.mermaid .titleText,
.mermaid .classTitle,
.mermaid .cluster-label text {
.mermaid :is(.titleText, .classTitle, .cluster-label text) {
fill: var(--color-secondary-900) !important;
color: var(--color-secondary-900) !important;
font-weight: bold !important;
}
/* 集群/子图样式 */
.mermaid .cluster rect,
.mermaid .cluster polygon {
.mermaid :is(.cluster rect, .cluster polygon) {
fill: var(--color-gray-50) !important;
stroke: var(--color-gray-400) !important;
stroke-width: 1px !important;
@ -92,22 +70,17 @@
}
/* 甘特图特殊样式 */
.mermaid .section0,
.mermaid .section2 {
.mermaid :is(.section0, .section2) {
fill: var(--color-gray-50) !important;
opacity: 0.5 !important;
}
.mermaid .section1,
.mermaid .section3 {
.mermaid :is(.section1, .section3) {
fill: var(--color-gray-100) !important;
opacity: 0.4 !important;
}
.mermaid .task0,
.mermaid .task1,
.mermaid .task2,
.mermaid .task3 {
.mermaid :is(.task0, .task1, .task2, .task3) {
fill: var(--color-primary-600) !important;
stroke: var(--color-gray-400) !important;
}
@ -119,76 +92,50 @@
}
/* 暗色模式样式 */
[data-theme='dark'] .mermaid .label,
[data-theme='dark'] .mermaid text,
[data-theme='dark'] .mermaid span,
[data-theme='dark'] .mermaid .messageText,
[data-theme='dark'] .mermaid .loopText,
[data-theme='dark'] .mermaid .noteText,
[data-theme='dark'] .mermaid .taskText,
[data-theme='dark'] .mermaid .classLabel .label {
[data-theme='dark'] .mermaid :is(.label, text, span, .messageText, .loopText, .noteText, .taskText, .classLabel .label) {
color: var(--color-secondary-300) !important;
fill: var(--color-secondary-300) !important;
}
/* 暗色模式edgeLabel文本颜色样式 */
[data-theme='dark'] .mermaid .edgeLabel,
[data-theme='dark'] .mermaid .edgeLabel p,
[data-theme='dark'] .mermaid .edgeLabel span {
[data-theme='dark'] .mermaid :is(.edgeLabel, .edgeLabel p, .edgeLabel span) {
color: var(--color-secondary-300) !important;
fill: var(--color-secondary-300) !important;
}
[data-theme='dark'] .mermaid .node rect,
[data-theme='dark'] .mermaid .node circle,
[data-theme='dark'] .mermaid .node ellipse,
[data-theme='dark'] .mermaid .node polygon,
[data-theme='dark'] .mermaid .node path,
[data-theme='dark'] .mermaid .actor {
[data-theme='dark'] .mermaid :is(.node rect, .node circle, .node ellipse, .node polygon, .node path, .actor) {
fill: var(--color-dark-hover) !important;
stroke: var(--color-gray-600) !important;
}
/* 暗色模式连接线样式 - 分开处理 */
[data-theme='dark'] .mermaid .edgePath .path,
[data-theme='dark'] .mermaid .flowchart-link,
[data-theme='dark'] .mermaid line,
[data-theme='dark'] .mermaid .messageLine0,
[data-theme='dark'] .mermaid .messageLine1 {
/* 暗色模式连接线样式 */
[data-theme='dark'] .mermaid :is(.edgePath .path, .flowchart-link, line, .messageLine0, .messageLine1) {
stroke: var(--color-gray-400) !important;
fill: none !important; /* 确保线条没有填充 */
fill: none !important;
}
/* 暗色模式箭头样式 - 分开处理 */
[data-theme='dark'] .mermaid .arrowheadPath,
[data-theme='dark'] .mermaid marker path {
/* 暗色模式箭头样式 */
[data-theme='dark'] .mermaid :is(.arrowheadPath, marker path) {
fill: var(--color-gray-400) !important;
stroke: none !important;
}
[data-theme='dark'] .mermaid .edgeLabel rect,
[data-theme='dark'] .mermaid .labelBox {
[data-theme='dark'] .mermaid :is(.edgeLabel rect, .labelBox) {
fill: var(--color-dark-surface) !important;
background-color: var(--color-dark-surface) !important;
}
[data-theme='dark'] .mermaid .titleText,
[data-theme='dark'] .mermaid .classTitle,
[data-theme='dark'] .mermaid .cluster-label text {
[data-theme='dark'] .mermaid :is(.titleText, .classTitle, .cluster-label text) {
fill: var(--color-secondary-100) !important;
color: var(--color-secondary-100) !important;
}
[data-theme='dark'] .mermaid .cluster rect,
[data-theme='dark'] .mermaid .cluster polygon,
[data-theme='dark'] .mermaid .section0,
[data-theme='dark'] .mermaid .section2 {
[data-theme='dark'] .mermaid :is(.cluster rect, .cluster polygon, .section0, .section2) {
fill: var(--color-dark-card) !important;
stroke: var(--color-gray-600) !important;
}
[data-theme='dark'] .mermaid .section1,
[data-theme='dark'] .mermaid .section3 {
[data-theme='dark'] .mermaid :is(.section1, .section3) {
fill: var(--color-dark-hover) !important;
}
@ -196,10 +143,7 @@
fill: var(--color-primary-300) !important;
}
[data-theme='dark'] .mermaid .task0,
[data-theme='dark'] .mermaid .task1,
[data-theme='dark'] .mermaid .task2,
[data-theme='dark'] .mermaid .task3 {
[data-theme='dark'] .mermaid :is(.task0, .task1, .task2, .task3) {
fill: var(--color-primary-400) !important;
stroke: var(--color-gray-600) !important;
}

View File

@ -195,7 +195,7 @@
color: var(--color-primary-600);
text-decoration: none;
border-bottom: 1px solid var(--color-primary-300);
transition: all 0.2s ease;
transition: border-bottom-color 0.2s ease;
}
.prose a:hover {
@ -220,8 +220,6 @@
border-bottom-color: var(--color-primary-400);
}
/* 收纳内容样式 */
.details-content {
margin-left: 1.5em;
@ -243,7 +241,7 @@
border-radius: 0.5rem;
border: 1px solid var(--color-secondary-200);
background-color: var(--color-gray-50);
transition: all 0.2s ease;
transition: box-shadow 0.2s ease;
overflow: hidden;
}
@ -275,7 +273,7 @@
display: flex;
align-items: center;
gap: 0.75em;
transition: all 0.2s ease;
transition: background 0.2s ease;
background: linear-gradient(to right, var(--color-primary-50), var(--color-gray-50));
border-left: 4px solid var(--color-primary-100);
}
@ -361,13 +359,18 @@
border-left-color: var(--color-primary-400);
}
/* 目录菜单样式 */
/* 目录项样式 */
/* 目录组件样式 */
/* 目录项基础样式 */
.toc-item {
position: relative;
}
.toc-item-container {
display: flex;
align-items: center;
}
/* 目录链接基础样式 */
.toc-link {
flex: 1;
white-space: nowrap;
@ -375,30 +378,38 @@
text-overflow: ellipsis;
padding: 0.25rem 0;
border-radius: 0.25rem;
transition: background-color 0.3s ease;
position: relative;
}
/* 黑暗模式文本颜色 */
.dark .text-secondary-800,
[data-theme="dark"] .text-secondary-800 {
color: var(--color-secondary-200);
/* 目录链接高亮指示器 */
.toc-link-active::before {
content: '';
position: absolute;
left: -0.75rem;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 1rem;
background: linear-gradient(to bottom, var(--color-primary-600), var(--color-primary-400));
border-radius: 0 2px 2px 0;
opacity: 1;
}
.dark .text-secondary-600,
[data-theme="dark"] .text-secondary-600 {
color: var(--color-secondary-400);
[data-theme="dark"] .toc-link-active::before {
background: linear-gradient(to bottom, var(--color-primary-400), var(--color-primary-600));
}
/* 目录链接悬停样式 */
.toc-link:hover {
background-color: rgba(0, 0, 0, 0.05);
color: var(--color-primary-600);
}
.dark .toc-link:hover,
[data-theme="dark"] .toc-link:hover {
background-color: rgba(255, 255, 255, 0.05);
color: var(--color-primary-400);
}
/* 目录切换按钮样式 */
.toc-toggle {
display: inline-flex;
align-items: center;
@ -409,25 +420,33 @@
min-height: 1.5rem;
}
/* 展开/折叠图标动画 */
.toc-toggle svg {
transition: transform 0.3s ease;
}
.toc-toggle[aria-expanded="true"] svg {
transform: rotate(-180deg);
}
/* 目录切换按钮悬停样式 */
.toc-toggle:hover {
background-color: rgba(0, 0, 0, 0.05);
}
.dark .toc-toggle:hover,
[data-theme="dark"] .toc-toggle:hover {
background-color: rgba(255, 255, 255, 0.1);
}
/* 动画效果 */
.toc-sublist.hidden {
max-height: 0;
opacity: 0;
overflow: hidden;
/* 子目录列表样式 */
.toc-list {
list-style-type: none;
transition: padding 0.3s ease;
}
.toc-sublist:not(.hidden) {
max-height: 1000px;
opacity: 1;
/* 子目录展开/收起动画 */
.toc-sublist {
transition: max-height 0.3s ease, opacity 0.3s ease;
}
/* 目录面板样式 */
@ -437,99 +456,41 @@
top: 5rem;
width: 16rem;
z-index: 30;
transition: opacity 0.3s ease, transform 0.3s ease;
}
#toc-panel > div {
background-color: white;
border: 1px solid var(--color-gray-200);
border-radius: 0.75rem;
display: flex;
flex-direction: column;
backdrop-filter: blur(4px);
background-opacity: 0.95;
}
.dark #toc-panel > div,
[data-theme="dark"] #toc-panel > div {
background-color: var(--color-gray-800);
border-color: var(--color-gray-700);
background-opacity: 0.95;
}
#toc-panel .panel-header {
border-bottom: 1px solid var(--color-secondary-100);
padding: 1rem;
padding-bottom: 0.75rem;
position: sticky;
top: 0;
z-index: 10;
border-top-left-radius: 0.75rem;
border-top-right-radius: 0.75rem;
background-color: white;
background-opacity: 0.95;
backdrop-filter: blur(4px);
}
.dark #toc-panel .panel-header,
[data-theme="dark"] #toc-panel .panel-header {
border-bottom-color: var(--color-gray-700);
background-color: var(--color-gray-800);
}
#toc-panel h3 {
font-weight: 700;
color: var(--color-primary-700);
display: flex;
align-items: center;
gap: 0.5rem;
}
.dark #toc-panel h3,
[data-theme="dark"] #toc-panel h3 {
color: var(--color-primary-400);
@media (max-width: 1535px) {
#toc-panel.hidden {
opacity: 0;
transform: translateX(10px);
pointer-events: none;
}
}
/* 目录内容容器样式 */
#toc-content {
font-size: 0.875rem;
padding: 1rem;
padding-top: 0.5rem;
overflow-y: auto;
max-height: calc(100vh - 8rem - 42px);
background-color: white;
scroll-behavior: smooth;
}
.dark #toc-content,
[data-theme="dark"] #toc-content {
background-color: var(--color-gray-800);
/* 目录内容滚动条样式 */
#toc-content::-webkit-scrollbar {
width: 4px;
}
/* 目录列表样式 */
.toc-list {
list-style-type: none;
#toc-content::-webkit-scrollbar-track {
background: transparent;
}
/* 黑暗模式适配 */
.dark .text-secondary-800,
[data-theme="dark"] .text-secondary-800 {
color: var(--color-secondary-200);
#toc-content::-webkit-scrollbar-thumb {
background-color: var(--color-primary-200);
border-radius: 4px;
}
.dark .text-secondary-600,
[data-theme="dark"] .text-secondary-600 {
color: var(--color-secondary-400);
}
.dark .text-primary-600,
[data-theme="dark"] .text-primary-600 {
color: var(--color-primary-400);
}
/* 扩展目录高亮样式 */
.toc-link.text-primary-600 {
font-weight: 500;
}
.dark .toc-link.text-primary-600,
[data-theme="dark"] .toc-link.text-primary-600 {
font-weight: 500;
[data-theme="dark"] #toc-content::-webkit-scrollbar-thumb {
background-color: var(--color-primary-800);
}

View File

@ -4,95 +4,6 @@
/* 定义深色模式选择器 */
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
/* 加载旋转动画 - 无遮罩版本 */
.loading-spinner-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none; /* 允许点击穿透 */
}
/* 激活状态 */
.loading-spinner-container.is-active {
opacity: 1;
visibility: visible;
}
/* 旋转动画元素 */
.loading-spinner {
width: 50px;
height: 50px;
border: 3px solid transparent;
border-top-color: var(--color-primary-500);
border-radius: 50%;
animation: spin 1s linear infinite;
position: relative;
/* 添加背景色以增强可见性 */
background-color: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
padding: 15px;
}
/* 深色模式下旋转动画颜色 */
[data-theme='dark'] .loading-spinner {
border-top-color: var(--color-primary-400);
background-color: rgba(15, 23, 42, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
}
.loading-spinner:before,
.loading-spinner:after {
content: '';
position: absolute;
border: 3px solid transparent;
border-radius: 50%;
}
.loading-spinner:before {
top: -3px;
left: -3px;
right: -3px;
bottom: -3px;
border-top-color: var(--color-primary-300);
animation: spin 1.5s linear infinite;
}
.loading-spinner:after {
top: 6px;
left: 6px;
right: 6px;
bottom: 6px;
border-top-color: var(--color-primary-600);
animation: spin 0.75s linear infinite;
}
/* 深色模式下的内外圈颜色 */
[data-theme='dark'] .loading-spinner:before {
border-top-color: var(--color-primary-200);
}
[data-theme='dark'] .loading-spinner:after {
border-top-color: var(--color-primary-500);
}
/* 旋转动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@theme {
/* 主色调 - 使用更现代的蓝紫色 */
--color-primary-50: #f5f7ff;

View File

@ -60,4 +60,81 @@
.nav-selector[data-has-active="true"] #nav-primary-highlight,
.nav-selector[data-has-active="true"] #nav-secondary-highlight {
opacity: 1;
}
/* 汉堡菜单动画样式 */
.hamburger-menu {
width: 24px;
height: 24px;
position: relative;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.hamburger-line {
width: 100%;
height: 2px;
background-color: currentColor;
border-radius: 2px;
transition: all 0.3s ease;
transform-origin: center;
}
/* 菜单打开时的样式 */
[aria-expanded="true"] .hamburger-menu .line-1 {
transform: translateY(8px) rotate(45deg);
}
[aria-expanded="true"] .hamburger-menu .line-2 {
opacity: 0;
}
[aria-expanded="true"] .hamburger-menu .line-3 {
transform: translateY(-8px) rotate(-45deg);
}
/* 移动端子菜单展开动画 */
.mobile-menu-arrow {
transition: transform 0.3s ease;
}
/* 移动端菜单图标容器 */
.mobile-menu-icon {
position: relative;
transition: transform 0.3s ease;
}
/* 子菜单展开/收起动画 - 完全重写 */
.mobile-submenu {
height: auto;
max-height: 0;
visibility: hidden;
opacity: 0;
overflow: hidden;
transform: translateY(-10px);
transition:
max-height 0.3s ease,
opacity 0.3s ease,
transform 0.3s ease,
visibility 0s linear 0.3s, /* 延迟visibility变化 */
padding 0.3s ease;
padding-top: 0;
padding-bottom: 0;
}
.mobile-submenu.menu-visible {
max-height: 500px; /* 足够大以容纳所有内容 */
visibility: visible;
opacity: 1;
transform: translateY(0);
transition:
max-height 0.3s ease,
opacity 0.3s ease,
transform 0.3s ease,
visibility 0s linear 0s, /* 立即改变visibility */
padding 0.3s ease;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}

View File

@ -33,4 +33,93 @@ html.is-changing .transition-fade,
html.is-changing .swup-transition-article,
html.is-changing #article-content {
opacity: 1;
}
/* 加载旋转动画 - 无遮罩版本 */
.loading-spinner-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none; /* 允许点击穿透 */
}
/* 激活状态 */
.loading-spinner-container.is-active {
opacity: 1;
visibility: visible;
}
/* 旋转动画元素 */
.loading-spinner {
width: 50px;
height: 50px;
border: 3px solid transparent;
border-top-color: var(--color-primary-500);
border-radius: 50%;
animation: spin 1s linear infinite;
position: relative;
/* 添加背景色以增强可见性 */
background-color: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
padding: 15px;
}
/* 深色模式下旋转动画颜色 */
[data-theme='dark'] .loading-spinner {
border-top-color: var(--color-primary-400);
background-color: rgba(15, 23, 42, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
}
.loading-spinner:before,
.loading-spinner:after {
content: '';
position: absolute;
border: 3px solid transparent;
border-radius: 50%;
}
.loading-spinner:before {
top: -3px;
left: -3px;
right: -3px;
bottom: -3px;
border-top-color: var(--color-primary-300);
animation: spin 1.5s linear infinite;
}
.loading-spinner:after {
top: 6px;
left: 6px;
right: 6px;
bottom: 6px;
border-top-color: var(--color-primary-600);
animation: spin 0.75s linear infinite;
}
/* 深色模式下的内外圈颜色 */
[data-theme='dark'] .loading-spinner:before {
border-top-color: var(--color-primary-200);
}
[data-theme='dark'] .loading-spinner:after {
border-top-color: var(--color-primary-500);
}
/* 旋转动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -22,7 +22,7 @@
}
/* 暗色模式下使用不同颜色变量 */
.dark .theme-ripple {
[data-theme="dark"] .theme-ripple {
background-color: rgba(var(--theme-ripple-color, 200, 200, 200), 0.15);
}