shelving
Version:
Toolkit for using data in JavaScript.
67 lines (58 loc) • 2.52 kB
CSS
@import "../style/base.css";
/* Low-priority padding/flex defaults live in `@layer defaults` so consumers can override them */
/* with normal-specificity selectors without needing `:where()` tricks. */
@layer defaults {
.layout {
/* Top/bottom use `layout-spacing` and left/right use `layout-padding` */
padding: var(--layout-spacing, var(--space-normal)) var(--layout-padding, var(--space-normal));
/* Default page padding (with safe-area additions). */
padding-top: calc(var(--layout-spacing, var(--space-normal)) + max(var(--layout-inset-top, 0px), env(safe-area-inset-top, 0px)));
padding-bottom: calc(
var(--layout-spacing, var(--space-normal)) +
max(var(--layout-inset-bottom, 0px), env(safe-area-inset-bottom, 0px))
);
padding-left: calc(var(--layout-padding, var(--space-normal)) + max(var(--layout-inset-left, 0px), env(safe-area-inset-left, 0px)));
padding-right: calc(var(--layout-padding, var(--space-normal)) + max(var(--layout-inset-right, 0px), env(safe-area-inset-right, 0px)));
/* Grow to fill the body. */
flex: 1;
}
}
@layer components {
/*
* Lock the document and let .layout own the page scroll.
*
* `.layout` says "this element is the main layout container, not <body>".
* When .layout appears anywhere in the page:
* - <html> and <body> are pinned to the viewport (no rubber-band on iOS).
* - <body> stacks its children vertically (flex column).
* - The .layout element grows to fill the body (flex: 1) and is the only scroll container.
*/
html:has(.layout) {
margin: 0;
padding: 0;
height: 100vh;
height: 100dvh; /** Make the height dynamically expand/contract as the address bar shows/hides on iOS. */
width: 100vw;
width: 100dvw;
overflow: hidden;
overflow-wrap: break-word; /* Break overlong words only as a last resort; `anywhere` would also break mid-word to fit narrow table/flex columns. */
}
body:has(.layout) {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
/* Lock body to prevent iOS Safari triggering viewport scrolling on focus change. */
position: fixed;
inset: 0;
/* Layout-specific bg hook. Typography and page bg come from the body baseline in style/base.css. */
background: var(--layout-body-bg, var(--color-white));
}
.layout {
/* Own the page's vertical scroll. */
overflow: hidden auto;
scroll-behavior: smooth;
/* `contain` keeps the elastic bounce on the layout itself but stops the scroll chain leaking up to the locked body. */
overscroll-behavior: contain;
}
}