fix: 侧栏顶部虚化遮罩与半透明卡片

- 新增固定侧栏遮罩层,滚动后淡入,blur(14px) + 透明渐变,不随吸底 transform 移动
- 侧栏资料/服务/导航卡改为 64% 半透明 + 毛玻璃
- 修正只输出 -webkit-backdrop-filter 导致不生效的问题
- 验证:遮罩 top=148、blur 生效、卡片 alpha=0.64
This commit is contained in:
2026-10-31 16:00:45 +08:00
parent 4304fd75b4
commit 50aea29ea6
4 changed files with 83 additions and 21 deletions
+40 -20
View File
@@ -220,6 +220,22 @@ export default function AppNext() {
}
const onScroll = () => setScrolled(body.scrollTop > 4)
// 独立渐隐层:固定在滚动区顶部,不随侧栏 transform 移动
const fade = document.createElement('div')
fade.className = 'sidebar-fade'
fade.setAttribute('aria-hidden', 'true')
document.body.appendChild(fade)
const updateFade = () => {
if (!(sider instanceof HTMLElement)) return
const rect = sider.getBoundingClientRect()
fade.style.left = `${rect.left}px`
fade.style.width = `${rect.width}px`
fade.style.top = `${body.getBoundingClientRect().top}px`
fade.classList.toggle('is-visible', body.scrollTop > 4 && rect.width > 0)
}
const updateSticky = () => {
const viewport = body.clientHeight
const maxLeft = Math.max(0, sider instanceof HTMLElement ? sider.offsetHeight - viewport : 0)
@@ -227,6 +243,7 @@ export default function AppNext() {
if (sider instanceof HTMLElement) {
sider.style.transform = offset > 0 ? `translateY(${offset}px)` : ''
}
updateFade()
}
body.addEventListener('scroll', onScroll, { passive: true })
@@ -243,6 +260,7 @@ export default function AppNext() {
body.removeEventListener('scroll', updateSticky)
window.removeEventListener('resize', updateSticky)
observer.disconnect()
fade.remove()
body.id = ''
body.style.overflowY = ''
body.style.overflowX = ''
@@ -627,26 +645,28 @@ export default function AppNext() {
/>
}
sider={
<div className="sidebar sidebar-home">
{site.sidebar.show_profile !== false && <ProfileCard profile={site.profile} />}
{site.sidebar.show_service !== false && (
<ServicePanel
projects={projects}
live={live}
refreshing={refreshing}
onRefresh={refresh}
/>
)}
<div className="nav-card">
<Menu
items={sidebarItems}
activeKey={activeKey}
itemHeight={39}
onSelect={(key) => {
if (key === 'home') navigate('/')
else navigate(`/g/${encodeURIComponent(key.slice(2))}`)
}}
/>
<div className="sidebar-wrap">
<div className="sidebar sidebar-home">
{site.sidebar.show_profile !== false && <ProfileCard profile={site.profile} />}
{site.sidebar.show_service !== false && (
<ServicePanel
projects={projects}
live={live}
refreshing={refreshing}
onRefresh={refresh}
/>
)}
<div className="nav-card">
<Menu
items={sidebarItems}
activeKey={activeKey}
itemHeight={39}
onSelect={(key) => {
if (key === 'home') navigate('/')
else navigate(`/g/${encodeURIComponent(key.slice(2))}`)
}}
/>
</div>
</div>
</div>
}