From 09abf45c1302c56b9ba8ad268dd19381316aa533 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sun, 16 Aug 2026 00:03:17 +0900 Subject: [PATCH] docs: add ADR-LAYOUT-HEIGHT-PROPAGATION standard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Defines height propagation chain for all pages - Establishes PageLayout → QueryBoundary → Content pattern - Documents KsSplitter master-detail implementation - Includes verification checklist for new pages - Rationale: flex children need 'min-height: 0' to respect parent constraints --- docs/ADR-LAYOUT-HEIGHT-PROPAGATION.md | 171 ++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 docs/ADR-LAYOUT-HEIGHT-PROPAGATION.md diff --git a/docs/ADR-LAYOUT-HEIGHT-PROPAGATION.md b/docs/ADR-LAYOUT-HEIGHT-PROPAGATION.md new file mode 100644 index 00000000..454e8550 --- /dev/null +++ b/docs/ADR-LAYOUT-HEIGHT-PROPAGATION.md @@ -0,0 +1,171 @@ +# ADR: Layout Height Propagation Standard + +**Status:** ACCEPTED +**Date:** 2026-08-16 +**Authors:** Claude Code + +--- + +## Context + +Multi-level frontend layouts (PageLayout → QueryBoundary → content) require explicit height propagation to ensure: +1. **Single-screen principle**: First load fits viewport without scroll +2. **Internal scrolling**: Only nested containers scroll, not the page +3. **Consistent behavior**: All pages follow the same height rules + +Previous bugs stemmed from missing `flex: 1; min-height: 0;` constraints at various levels. + +--- + +## Decision + +Establish a **required height propagation chain** for all pages: + +``` +PageLayout (.ks-page__content) + ├─ height: 100% + ├─ min-height: 0 + └─ display: flex + + ↓ (child must propagate height) + +QueryStateBoundary (.ks-query-boundary) + ├─ flex: 1 + ├─ height: 100% + ├─ min-height: 0 + └─ display: flex + + ↓ (child must propagate height) + +Content Container (grid, splitter, or flex child) + ├─ flex: 1 (if flex child) + ├─ height: 100% (if direct child of flex parent) + ├─ min-height: 0 (always required for flex children) + └─ overflow: (auto|hidden) + + ↓ (internal scrollable panes) + +Internal Panes (.items, .detail-panel, etc.) + ├─ flex: 1 + ├─ min-height: 0 + └─ overflow-y: auto +``` + +--- + +## Rationale + +1. **Flex layout principle**: Flex children must have `min-height: 0` to respect parent constraints +2. **Height inheritance**: `height: 100%` only works when parent has explicit height +3. **Single responsibility**: Each layer only enforces its own constraints, children handle overflow + +--- + +## Implementation + +### For Grid-Based Pages (.ks-stack) + +```css +.ks-stack { + display: grid; + gap: var(--ks-space-4); + flex: 1; /* Required: flex child must expand */ + min-height: 0; /* Required: allow internal scroll */ + height: 100%; /* Required: inherit parent height */ +} +``` + +### For Master-Detail Pages (KsSplitter) + +```vue + + + + +``` + +**Key**: KsSplitter pane uses `overflow: hidden`; each slot's scrollable child must have `overflow-y: auto; min-height: 0`. + +### For Flex-Column Containers + +```css +.container { + display: flex; + flex-direction: column; + flex: 1; /* Expand to fill parent */ + min-height: 0; /* Allow internal overflow */ + height: 100%; /* Inherit parent height (optional if flex: 1 works) */ +} + +.child { + flex: 1; /* Share space with siblings */ + min-height: 0; /* Don't prevent scrolling */ + overflow-y: auto;/* Internal scroll */ +} +``` + +--- + +## Standard CSS Classes (Optional Utilities) + +Defined in `frontend/src/design-system/base.css`: + +```css +.ks-flex-column-1 { display: flex; flex-direction: column; flex: 1; min-height: 0; } +.ks-flex-row-1 { display: flex; flex-direction: row; flex: 1; min-height: 0; } +.ks-overflow-auto { overflow-y: auto; } +``` + +**Note**: These are *opt-in* utilities. Prefer explicit CSS in scoped styles for clarity. + +--- + +## Related Artifacts + +- **Commits:** + - 61ca979: `.ks-stack` flex: 1 fix + - b299939: ApprovalQueue flex layout + - 05e2791: ApprovalQueue → KsSplitter refactor + - 4ff5aaf: `.request-detail` height fix + - a1eccad: Standard CSS class definitions + +- **Updated Components:** + - VersionGovernancePage.vue + - ApprovalQueue.vue (KsSplitter migration) + - ModelOperationsPage.vue + +- **Memory:** [[layout_standardization_framework]] + +--- + +## Verification Checklist + +For each new page: +- [ ] First load fits viewport (no page scroll) +- [ ] Internal panes have `overflow-y: auto; min-height: 0` +- [ ] Height chain: PageLayout → QueryBoundary → content +- [ ] Master-detail uses KsSplitter or equivalent flex layout +- [ ] All flex children have `flex: 1; min-height: 0` + +--- + +## Future Considerations + +1. **Breakpoints**: Responsive layouts (mobile) may need `flex-direction: column` at small widths +2. **Height variants**: Consider separate classes for different flex ratios (1:2, 1:1, etc.) +3. **Template enforcement**: CI/CD gate to catch missing height constraints + +--- + +## Questions? + +See CLAUDE.md §"Frontend: Vue 3 + Vite + KBX Foundation v4" for component architecture.