fix: 双栏非对称吸底滚动与对齐

- 去掉首页侧栏额外 padding,左右两栏初始顶部对齐
- 隐藏 #page-scroll 滚动条
- 左侧到底后用 translateY 补偿吸附在视口底部,右侧继续滚动;右侧先到底时两栏同步
- ResizeObserver 重算吸附阈值
- 验证:初始 top 148/148;滚动后左栏 top 144 固定、bottom 900;无滚动条
This commit is contained in:
2026-10-31 15:51:57 +08:00
parent 54fd0edf84
commit 4304fd75b4
4 changed files with 46 additions and 2 deletions
+15
View File
@@ -1299,6 +1299,21 @@ a.entry-href:hover {
min-width: 0;
}
/* 首页:左右栏共用一个滚动区,左侧到底后吸底 */
#page-scroll {
scrollbar-width: none;
-ms-overflow-style: none;
}
#page-scroll::-webkit-scrollbar {
display: none;
}
.sidebar-home {
padding-top: 0;
will-change: transform;
}
.sidebar-divider {
margin: var(--su-space-2) 0;
border-top: 1px dashed var(--su-border-strong);
+22 -1
View File
@@ -216,14 +216,33 @@ export default function AppNext() {
if (sider instanceof HTMLElement) {
sider.style.overflow = 'visible'
sider.style.height = 'auto'
sider.style.alignSelf = 'flex-start'
}
const onScroll = () => setScrolled(body.scrollTop > 4)
const updateSticky = () => {
const viewport = body.clientHeight
const maxLeft = Math.max(0, sider instanceof HTMLElement ? sider.offsetHeight - viewport : 0)
const offset = Math.max(0, body.scrollTop - maxLeft)
if (sider instanceof HTMLElement) {
sider.style.transform = offset > 0 ? `translateY(${offset}px)` : ''
}
}
body.addEventListener('scroll', onScroll, { passive: true })
body.addEventListener('scroll', updateSticky, { passive: true })
window.addEventListener('resize', updateSticky)
const observer = new ResizeObserver(updateSticky)
observer.observe(content)
if (sider instanceof HTMLElement) observer.observe(sider)
onScroll()
updateSticky()
return () => {
body.removeEventListener('scroll', onScroll)
body.removeEventListener('scroll', updateSticky)
window.removeEventListener('resize', updateSticky)
observer.disconnect()
body.id = ''
body.style.overflowY = ''
body.style.overflowX = ''
@@ -235,6 +254,8 @@ export default function AppNext() {
if (sider instanceof HTMLElement) {
sider.style.overflow = ''
sider.style.height = ''
sider.style.alignSelf = ''
sider.style.transform = ''
}
}
}, [])
@@ -606,7 +627,7 @@ export default function AppNext() {
/>
}
sider={
<div className="sidebar">
<div className="sidebar sidebar-home">
{site.sidebar.show_profile !== false && <ProfileCard profile={site.profile} />}
{site.sidebar.show_service !== false && (
<ServicePanel