Improve mobile reading layout and typography

Make classic text chapters easier to read on phones with responsive styles, collapsed sidebar groups, and less intrusive install prompts on doc pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-05 17:57:57 +08:00
parent c9f78ef25f
commit a8907d6cc0
5 changed files with 208 additions and 11 deletions
+14 -1
View File
@@ -41,9 +41,22 @@ export default defineConfig({
['meta', { name: 'mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' }],
[
'meta',
{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0, viewport-fit=cover',
},
],
],
themeConfig: {
logo: { src: '/favicon.ico', width: 24, height: 24 },
sidebarMenuLabel: '目录',
returnToTopLabel: '回到顶部',
docFooter: {
prev: '上一篇',
next: '下一篇',
},
nav: [
{ text: '首页', link: '/' },
{ text: '五行', link: '/金、木、水、火、土 - 五行/' },
@@ -52,7 +65,7 @@ export default defineConfig({
{ text: '中医', link: '/中医宝典/' },
],
sidebar: generateSidebar(),
outline: { level: [2, 4] },
outline: { level: [2, 3], label: '本页目录' },
search: {
provider: 'local',
},
+2 -2
View File
@@ -85,7 +85,7 @@ export function generateSidebar(): Record<string, SidebarItem[]> {
if (rootFiles.length > 0) {
groups.push({
text: '典籍',
collapsed: false,
collapsed: true,
items: rootFiles.map((file) => ({
text: titleFromFilename(file.name),
link: toLink(file.name),
@@ -103,7 +103,7 @@ export function generateSidebar(): Record<string, SidebarItem[]> {
if (items.length === 0) continue
groups.push({
text: dir.name,
collapsed: false,
collapsed: true,
items,
})
}
+31 -8
View File
@@ -1,9 +1,12 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute } from 'vitepress'
const route = useRoute()
const showAndroidInstall = ref(false)
const showIOSHint = ref(false)
const dismissed = ref(false)
const isMobile = ref(false)
let deferredPrompt: BeforeInstallPromptEvent | null = null
interface BeforeInstallPromptEvent extends Event {
@@ -11,11 +14,22 @@ interface BeforeInstallPromptEvent extends Event {
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>
}
const visible = computed(
() => !dismissed.value && (showAndroidInstall.value || showIOSHint.value),
)
const isDocPage = computed(() => route.path !== '/')
const visible = computed(() => {
if (dismissed.value) return false
if (isMobile.value && isDocPage.value) return false
return showAndroidInstall.value || showIOSHint.value
})
onMounted(() => {
isMobile.value = window.matchMedia('(max-width: 768px)').matches
if (sessionStorage.getItem('install-app-dismissed') === '1') {
dismissed.value = true
return
}
const isStandalone =
window.matchMedia('(display-mode: standalone)').matches ||
(window.navigator as Navigator & { standalone?: boolean }).standalone
@@ -45,6 +59,7 @@ async function installApp() {
function dismiss() {
dismissed.value = true
sessionStorage.setItem('install-app-dismissed', '1')
}
</script>
@@ -55,7 +70,7 @@ function dismiss() {
可将道德经安装到桌面 App 一样使用
</p>
<p v-else class="install-app__text">
iPhone点击 Safari 底部分享按钮选择添加到主屏幕
iPhoneSafari 底部分享 添加到主屏幕阅读更方便
</p>
<div class="install-app__actions">
<button
@@ -76,8 +91,8 @@ function dismiss() {
.install-app {
position: fixed;
right: 16px;
bottom: 16px;
z-index: 100;
bottom: calc(16px + env(safe-area-inset-bottom, 0));
z-index: 50;
max-width: min(92vw, 360px);
}
@@ -104,8 +119,8 @@ function dismiss() {
.install-app__primary,
.install-app__ghost {
border-radius: 8px;
padding: 8px 12px;
font-size: 13px;
padding: 10px 14px;
font-size: 14px;
cursor: pointer;
}
@@ -120,4 +135,12 @@ function dismiss() {
background: transparent;
color: var(--vp-c-text-2);
}
@media (max-width: 768px) {
.install-app {
left: 12px;
right: 12px;
max-width: none;
}
}
</style>
+160
View File
@@ -0,0 +1,160 @@
:root {
--vp-font-family-base: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
'Noto Sans SC', 'Source Han Sans SC', sans-serif;
}
/* 旧版 markdown 里的 <font size="4"> 在手机上过大 */
.vp-doc font {
font-size: inherit !important;
}
.vp-doc {
line-height: 1.85;
letter-spacing: 0.02em;
word-break: break-word;
}
.vp-doc h1 {
font-size: clamp(1.45rem, 5vw, 2rem);
line-height: 1.35;
}
.vp-doc h2 {
font-size: clamp(1.2rem, 4.2vw, 1.55rem);
margin-top: 1.6em;
padding-bottom: 0.35em;
border-bottom: 1px solid var(--vp-c-divider);
}
.vp-doc h3 {
font-size: clamp(1.05rem, 3.6vw, 1.25rem);
}
.vp-doc p {
margin: 1em 0;
}
/* 道德经等用缩进写的“伪代码块”,改成正文排版 */
.vp-doc pre {
white-space: pre-wrap;
word-break: break-word;
overflow-x: auto;
font-family: var(--vp-font-family-base);
font-size: 1rem;
line-height: 1.9;
padding: 14px 16px;
border-radius: 10px;
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg-soft);
}
.vp-doc :not(pre) > code {
font-size: 0.92em;
word-break: break-word;
}
.vp-doc img {
display: block;
max-width: 100% !important;
height: auto !important;
margin: 1em auto;
border-radius: 8px;
}
.vp-doc table {
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
font-size: 0.92rem;
}
.vp-doc blockquote {
margin: 1.2em 0;
padding: 0.8em 1em;
border-radius: 8px;
}
/* 底部上一篇 / 下一篇:加大触控区域 */
.VPDocFooter .pager-link {
min-height: 48px;
padding: 12px 14px;
border-radius: 10px;
}
.VPDocFooter .pager-link .title {
font-size: 0.95rem;
line-height: 1.45;
}
@media (max-width: 960px) {
.VPContent {
padding-top: 0;
}
.VPDoc .container {
padding: 0 14px;
}
.VPDoc .content {
max-width: 100%;
}
.vp-doc {
padding: 12px 0 88px;
font-size: 17px;
}
.vp-doc h1 {
margin-bottom: 0.6em;
}
/* 手机隐藏右侧大纲,避免挤压正文 */
.VPDoc .aside {
display: none;
}
.VPDoc.has-aside .content-container {
max-width: 100%;
}
/* 侧边栏目录项加大点击区域 */
.VPSidebarItem .text {
line-height: 1.5;
padding-top: 4px;
padding-bottom: 4px;
}
.VPSidebarItem.level-0 > .item > .text {
font-size: 15px;
}
/* 顶栏留白,适配刘海屏 */
.VPNavBar {
padding-top: env(safe-area-inset-top, 0);
}
/* 搜索框不占太多宽度 */
.VPNavBarSearch {
flex-shrink: 1;
}
}
@media (max-width: 640px) {
.VPNavBarTitle .title {
font-size: 15px;
}
.vp-doc {
font-size: 18px;
line-height: 1.9;
}
.vp-doc pre {
font-size: 17px;
padding: 12px 14px;
}
.VPDocFooter {
padding-bottom: calc(12px + env(safe-area-inset-bottom, 0));
}
}
+1
View File
@@ -1,6 +1,7 @@
import DefaultTheme from 'vitepress/theme'
import { h } from 'vue'
import InstallApp from './InstallApp.vue'
import './custom.css'
if (typeof window !== 'undefined') {
import('virtual:pwa-register').then(({ registerSW }) => {