给目录添加样式,优化所有css样式
This commit is contained in:
parent
1e624c7169
commit
02aaa16629
@ -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() {
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
/* 暗色模式下使用不同颜色变量 */
|
||||
.dark .theme-ripple {
|
||||
[data-theme="dark"] .theme-ripple {
|
||||
background-color: rgba(var(--theme-ripple-color, 200, 200, 200), 0.15);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user