v0.0.49 데스크톱 3단 스크롤 — 사이드 푸터 고정
그리드 높이를 뷰포트에 맞추고 중앙만 스크롤해 좌우 사이드 하단이 항상 보이도록 한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -72,6 +72,8 @@
|
||||
|
||||
@layer components {
|
||||
.site-shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
color: var(--site-text);
|
||||
background: var(--site-bg);
|
||||
@@ -103,7 +105,7 @@
|
||||
}
|
||||
|
||||
.site-main {
|
||||
min-height: calc(100vh - 57px);
|
||||
min-height: 0;
|
||||
border-left: 1px solid var(--site-line);
|
||||
border-right: 1px solid var(--site-line);
|
||||
background: var(--site-bg);
|
||||
@@ -114,7 +116,7 @@
|
||||
}
|
||||
|
||||
.site-sidebar {
|
||||
min-height: calc(100vh - 57px);
|
||||
min-height: 0;
|
||||
background: var(--site-panel);
|
||||
color: var(--site-text);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ const { data: navigation } = await useFetch('/api/navigation', {
|
||||
|
||||
<template>
|
||||
<aside
|
||||
class="left-sidebar site-sidebar hidden overflow-hidden border-r border-[var(--site-line)] transition-[width,opacity,border-color] duration-300 ease-out lg:flex lg:flex-col"
|
||||
class="left-sidebar site-sidebar hidden min-h-0 max-h-full overflow-hidden border-r border-[var(--site-line)] transition-[width,opacity,border-color] duration-300 ease-out lg:flex lg:h-full lg:flex-col"
|
||||
:class="menuOpen ? 'w-[287px] opacity-100' : 'w-0 opacity-0 border-transparent'"
|
||||
>
|
||||
<div class="left-sidebar__scroll min-h-0 flex-1 overflow-y-auto">
|
||||
@@ -87,7 +87,7 @@ const { data: navigation } = await useFetch('/api/navigation', {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="left-sidebar__footer flex items-center justify-between px-1 py-4 text-xs">
|
||||
<footer class="left-sidebar__footer flex shrink-0 items-center justify-between border-t border-[var(--site-line)] px-1 py-4 text-xs">
|
||||
<nav class="left-sidebar__footer-nav flex gap-4">
|
||||
<NuxtLink
|
||||
v-for="item in navigation.footer"
|
||||
|
||||
@@ -19,7 +19,7 @@ const { data: siteSettings } = await useFetch('/api/site-settings', {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside class="right-sidebar site-sidebar hidden w-[287px] border-l border-[var(--site-line)] lg:flex lg:flex-col">
|
||||
<aside class="right-sidebar site-sidebar hidden min-h-0 max-h-full w-[287px] overflow-hidden border-l border-[var(--site-line)] lg:flex lg:h-full lg:flex-col">
|
||||
<div class="right-sidebar__scroll min-h-0 flex-1 overflow-y-auto">
|
||||
<div class="right-sidebar__block site-sidebar-section py-5 pl-5 pr-0">
|
||||
<div class="right-sidebar__profile flex items-center gap-3">
|
||||
@@ -179,7 +179,7 @@ const { data: siteSettings } = await useFetch('/api/site-settings', {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="right-sidebar__footer py-4 pl-5 pr-0 text-xs site-muted">
|
||||
<footer class="right-sidebar__footer shrink-0 border-t border-[var(--site-line)] py-4 pl-5 pr-0 text-xs site-muted">
|
||||
{{ siteSettings.copyrightText }}
|
||||
</footer>
|
||||
</aside>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-05-08 v0.0.49
|
||||
|
||||
### 데스크톱 3단 레이아웃 스크롤 영역 분리
|
||||
|
||||
Thred 참고 화면처럼 긴 본문이 있을 때도 좌·우 사이드 하단(푸터)이 뷰포트 기준으로 고정되도록, 그리드 행 높이를 `calc(100vh - 헤더)`로 제한하고 `grid-template-rows: minmax(0,1fr)`로 자식이 넘치지 않게 한다. 세로 스크롤은 중앙 `main`에만 두어 사이드바는 내부 스크롤 영역과 고정 푸터로 나눈다.
|
||||
|
||||
## 2026-05-08 v0.0.48
|
||||
|
||||
### Twitter/X 공식 embed iframe과 북마크·회원가입 마크다운 블록
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
| 파일 | 화면 |
|
||||
|------|------|
|
||||
| layouts/default.vue | 메인, 목록, 태그 페이지 |
|
||||
| layouts/post.vue | 개별 게시물 |
|
||||
| layouts/default.vue | 메인, 목록, 태그 페이지 — 데스크톱에서 그리드 높이 고정·중앙 컬럼 스크롤 |
|
||||
| layouts/post.vue | 개별 게시물 — 위와 동일한 3단 스크롤 규칙 |
|
||||
| layouts/admin.vue | 관리자 전체, 글 작성/수정 화면의 전체 화면 편집 모드와 문서 스크롤 잠금 |
|
||||
| layouts/page.vue | 고정 페이지 전체 화면 |
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
| 파일 | 화면 위치 |
|
||||
|------|-----------|
|
||||
| components/site/SiteHeader.vue | 모든 공개 페이지 상단 |
|
||||
| components/site/LeftSidebar.vue | 메인 화면 왼쪽, 네비게이션과 태그 목록, 테마 전환 버튼, 열림/닫힘 폭 전환 애니메이션, 세로 바→원형 hover 표시 |
|
||||
| components/site/RightSidebar.vue | 메인 화면 오른쪽, 사이트 설정 표시, 좌측 경계 보더, 링크 hover 인터랙션 |
|
||||
| components/site/LeftSidebar.vue | 왼쪽 사이드바, 상단 스크롤 영역·하단 푸터(고정), 네비·태그·테마, 열림/닫힘 애니메이션 |
|
||||
| components/site/RightSidebar.vue | 오른쪽 사이드바, 상단 스크롤 영역·하단 카피라이트(고정), Follow·추천 링크 |
|
||||
| components/site/MainColumn.vue | 메인 화면 중앙 |
|
||||
| components/site/PostCard.vue | 목록의 게시물 카드, 대표 이미지 썸네일, 카드 hover 인터랙션 |
|
||||
| components/site/TagHeader.vue | 태그 페이지 헤더 |
|
||||
|
||||
12
docs/spec.md
12
docs/spec.md
@@ -17,10 +17,12 @@
|
||||
|
||||
| 요소 | 크기/속성 |
|
||||
|------|-----------|
|
||||
| Header | 높이 57px |
|
||||
| Left Aside | 너비 287px, 최소 높이 calc(100vh - 57px), 패딩 12px 12px 12px 0 |
|
||||
| Main | 너비 720px, 패딩 32px 24px (헤더), 16px 24px (섹션) |
|
||||
| Right Aside | 너비 287px, 최소 높이 calc(100vh - 57px), 패딩 20px 0 20px 20px |
|
||||
| Header | 높이 57px, `shrink-0` |
|
||||
| Shell | `min-height: 100vh`, `flex` 세로 컬럼 |
|
||||
| 그리드(데스크톱 `lg+`) | 높이 `calc(100vh - 57px)`, `grid-template-rows: minmax(0,1fr)`, `overflow: hidden` — 본문 길이와 무관하게 뷰포트 높이에 고정 |
|
||||
| Left Aside | 너비 287px, 컬럼 높이 100%, 상단 영역 `flex-1 overflow-y-auto`, 하단 푸터(네비·테마) `shrink-0`로 항상 열 하단에 고정 |
|
||||
| Main | 너비 720px, 데스크톱에서만 `overflow-y: auto`로 **중앙 컬럼만** 세로 스크롤 |
|
||||
| Right Aside | 너비 287px, Left와 동일하게 상단 스크롤 + 하단 카피라이트 고정 |
|
||||
|
||||
### 메뉴 토글
|
||||
|
||||
@@ -489,6 +491,6 @@ APP_PORT=43118
|
||||
|
||||
## 버전 관리
|
||||
|
||||
- 현재 버전: v0.0.48
|
||||
- 현재 버전: v0.0.49
|
||||
- 첫 커밋 이후 변경사항을 커밋할 때마다 패치 버전 증가
|
||||
- 메이저/마이너 버전은 구조 변경 또는 기능 묶음 단위로 결정
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# 업데이트 이력
|
||||
|
||||
## v0.0.49
|
||||
|
||||
- 데스크톱(`lg+`) 공개 레이아웃을 뷰포트 높이에 고정하고 중앙 컬럼만 세로 스크롤되도록 변경.
|
||||
- 좌·우 사이드바는 열 높이 안에서 본문만 스크롤하고 푸터(링크·테마·카피라이트)는 항상 열 하단에 고정.
|
||||
|
||||
## v0.0.48
|
||||
|
||||
- 공개 본문에 Thred형 북마크 카드(`ProseBookmark`, `:::bookmark`)와 회원가입 CTA(`ProseSignup`, `:::signup`) 추가.
|
||||
|
||||
@@ -4,13 +4,16 @@ const { menuOpen } = useMenuState()
|
||||
|
||||
<template>
|
||||
<div class="site-shell public-layout">
|
||||
<SiteHeader />
|
||||
<SiteHeader class="shrink-0" />
|
||||
<div
|
||||
class="public-layout__grid mx-auto grid min-h-[calc(100vh-57px)] max-w-[1294px] grid-cols-1 bg-[var(--site-bg)] px-4 transition-[grid-template-columns,max-width] duration-300 ease-out lg:px-0 lg:[grid-template-columns:287px_minmax(0,720px)_287px]"
|
||||
class="public-layout__grid mx-auto grid w-full max-w-[1294px] flex-1 grid-cols-1 bg-[var(--site-bg)] px-4 transition-[grid-template-columns,max-width] duration-300 ease-out lg:grid lg:min-h-0 lg:h-[calc(100vh-57px)] lg:max-h-[calc(100vh-57px)] lg:flex-none lg:overflow-hidden lg:px-0 lg:[grid-template-columns:287px_minmax(0,720px)_287px] lg:[grid-template-rows:minmax(0,1fr)]"
|
||||
:class="menuOpen ? '' : 'max-w-[1007px] lg:[grid-template-columns:0_minmax(0,720px)_287px]'"
|
||||
>
|
||||
<LeftSidebar :menu-open="menuOpen" />
|
||||
<main class="site-main w-full lg:w-[720px]" :class="{ 'site-main--menu-closed': !menuOpen }">
|
||||
<main
|
||||
class="site-main min-h-0 w-full overflow-x-hidden lg:h-full lg:max-h-full lg:overflow-y-auto lg:overscroll-y-contain lg:w-[720px]"
|
||||
:class="{ 'site-main--menu-closed': !menuOpen }"
|
||||
>
|
||||
<slot />
|
||||
</main>
|
||||
<RightSidebar />
|
||||
|
||||
@@ -4,13 +4,16 @@ const { menuOpen } = useMenuState()
|
||||
|
||||
<template>
|
||||
<div class="site-shell post-layout">
|
||||
<SiteHeader />
|
||||
<SiteHeader class="shrink-0" />
|
||||
<div
|
||||
class="post-layout__grid mx-auto grid min-h-[calc(100vh-57px)] max-w-[1294px] grid-cols-1 bg-[var(--site-bg)] px-4 transition-[grid-template-columns,max-width] duration-300 ease-out lg:px-0 lg:[grid-template-columns:287px_minmax(0,720px)_287px]"
|
||||
class="post-layout__grid mx-auto grid w-full max-w-[1294px] flex-1 grid-cols-1 bg-[var(--site-bg)] px-4 transition-[grid-template-columns,max-width] duration-300 ease-out lg:grid lg:min-h-0 lg:h-[calc(100vh-57px)] lg:max-h-[calc(100vh-57px)] lg:flex-none lg:overflow-hidden lg:px-0 lg:[grid-template-columns:287px_minmax(0,720px)_287px] lg:[grid-template-rows:minmax(0,1fr)]"
|
||||
:class="menuOpen ? '' : 'max-w-[1007px] lg:[grid-template-columns:0_minmax(0,720px)_287px]'"
|
||||
>
|
||||
<LeftSidebar :menu-open="menuOpen" />
|
||||
<main class="site-main w-full lg:w-[720px]" :class="{ 'site-main--menu-closed': !menuOpen }">
|
||||
<main
|
||||
class="site-main min-h-0 w-full overflow-x-hidden lg:h-full lg:max-h-full lg:overflow-y-auto lg:overscroll-y-contain lg:w-[720px]"
|
||||
:class="{ 'site-main--menu-closed': !menuOpen }"
|
||||
>
|
||||
<slot />
|
||||
</main>
|
||||
<RightSidebar />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sori.studio",
|
||||
"version": "0.0.48",
|
||||
"version": "0.0.49",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user