Add tablet landscape layout and allow PWA horizontal orientation.
Split mobile and tablet breakpoints, restore desktop-style reading on landscape tablets, and lock Android tablet apps to landscape. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+1
-1
@@ -22,7 +22,7 @@ export function createPwaPlugin() {
|
|||||||
theme_color: '#0f3460',
|
theme_color: '#0f3460',
|
||||||
background_color: '#1a1a2e',
|
background_color: '#1a1a2e',
|
||||||
display: 'standalone',
|
display: 'standalone',
|
||||||
orientation: 'portrait-primary',
|
orientation: 'any',
|
||||||
scope: '/',
|
scope: '/',
|
||||||
start_url: '/',
|
start_url: '/',
|
||||||
categories: ['books', 'education'],
|
categories: ['books', 'education'],
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function onBeforeInstallPrompt(event: Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
isMobile.value = window.matchMedia('(max-width: 768px)').matches
|
isMobile.value = window.matchMedia('(max-width: 767px)').matches
|
||||||
|
|
||||||
if (sessionStorage.getItem('install-app-dismissed') === '1') {
|
if (sessionStorage.getItem('install-app-dismissed') === '1') {
|
||||||
dismissed.value = true
|
dismissed.value = true
|
||||||
@@ -172,7 +172,7 @@ function dismiss() {
|
|||||||
color: var(--vp-c-text-2);
|
color: var(--vp-c-text-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 767px) {
|
||||||
.install-app {
|
.install-app {
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ html {
|
|||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
@media (max-width: 767px) {
|
||||||
.VPContent {
|
.VPContent {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
@@ -174,6 +174,57 @@ html {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 平板竖屏:介于手机与桌面之间 */
|
||||||
|
@media (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
|
||||||
|
.VPDoc .container {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-doc {
|
||||||
|
font-size: 17px;
|
||||||
|
padding: 12px 0 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDocFooter .pager-link {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 平板横屏:恢复桌面式双栏阅读 */
|
||||||
|
@media (min-width: 768px) and (orientation: landscape) {
|
||||||
|
.VPDoc .aside,
|
||||||
|
.VPDoc .aside-container {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDoc.has-aside .content-container {
|
||||||
|
max-width: 688px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDoc .container {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-doc {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.85;
|
||||||
|
padding: 16px 0 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDocFooter .pager-link {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDocFooter .prev-next {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPDocFooter .pager-link {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.VPNavBarTitle .title {
|
.VPNavBarTitle .title {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import DefaultTheme from 'vitepress/theme'
|
||||||
import { h, defineComponent } from 'vue'
|
import { h, defineComponent } from 'vue'
|
||||||
import InstallApp from './InstallApp.vue'
|
import InstallApp from './InstallApp.vue'
|
||||||
|
import { initTabletLandscape } from './tablet-landscape'
|
||||||
import './custom.css'
|
import './custom.css'
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
import('virtual:pwa-register').then(({ registerSW }) => {
|
import('virtual:pwa-register').then(({ registerSW }) => {
|
||||||
registerSW({ immediate: true })
|
registerSW({ immediate: true })
|
||||||
})
|
})
|
||||||
|
initTabletLandscape()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 旧 markdown 的 <font> 标签改为 div,避免手机端布局溢出 */
|
/** 旧 markdown 的 <font> 标签改为 div,避免手机端布局溢出 */
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/** Android 平板 PWA 安装后默认锁定横屏 */
|
||||||
|
export function initTabletLandscape() {
|
||||||
|
if (typeof window === 'undefined') return
|
||||||
|
|
||||||
|
function tryLockLandscape() {
|
||||||
|
const isStandalone =
|
||||||
|
window.matchMedia('(display-mode: standalone)').matches ||
|
||||||
|
(window.navigator as Navigator & { standalone?: boolean }).standalone
|
||||||
|
|
||||||
|
if (!isStandalone || !/Android/i.test(navigator.userAgent)) return
|
||||||
|
|
||||||
|
const shortestSide = Math.min(window.screen.width, window.screen.height)
|
||||||
|
if (shortestSide < 600) return
|
||||||
|
|
||||||
|
const lock = screen.orientation?.lock?.bind(screen.orientation)
|
||||||
|
if (!lock) return
|
||||||
|
|
||||||
|
lock('landscape-primary').catch(() => {
|
||||||
|
lock('landscape').catch(() => {})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tryLockLandscape()
|
||||||
|
window.addEventListener('orientationchange', tryLockLandscape)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user