adaptive-ui-checklist
Installation
SKILL.md
Adaptive UI checklist
A layout is correct only if it is correct at every size, not on the phone it was drawn on. Typical failure: a two-image collage is pinned to opposite corners of a box that fills the spare height. It looks right on a 16:9 phone, and on a 19.5:9 phone the extra height becomes a large gap between the images, because the images are sized by width and stop growing.
This skill is a short review checklist. For the platform APIs read the platform skill when one is installed (adaptive for Android, edge-to-edge for insets); this file says what to check and how to prove it.
Rules
- Never pin related elements to corners of leftover space. Do not place two related elements with opposite alignments (top-start and bottom-end) or with fractions of the free height: the distance between them then grows with the screen. Size the group from its own content (widths, aspect ratios, text), then place the group (center it, or anchor it to one edge) and let the spare room become margin. Spacing between related elements is a fixed value or derives from their own size, never from the free height.
- Constrain, do not stretch. Give every flexible element a cap (max width, min and max height,
weightplus an upper bound,max-width,clamp()). On a tablet or an unfolded foldable a phone layout that fills the window looks wrong: center the content in a bounded column or use two panes. - Pick the layout from the window, not the device. Classify the window width (compact below 600 dp, medium 600 to 840 dp, expanded 840 dp and above) and treat a short height (below about 480 dp, a phone in landscape) as its own case. Never branch on the device model or the platform name. Compose:
BoxWithConstraints, window size class,currentWindowAdaptiveInfo(). SwiftUI:horizontalSizeClass,verticalSizeClass,ViewThatFits,GeometryReaderonly where needed. Web: container queries, media queries on the viewport,clamp(),dvh. - Foldables. Folding, unfolding and tabletop posture change the window while a screen is open: keep state in the view model or in saved state (never only in a local variable), assume no fixed orientation or size, and recompute from the constraints on every pass. Keep text, buttons and key images out of the hinge or fold area: on Android read the fold with Jetpack WindowManager (
FoldingFeature, separating or occluding), on the web use the viewport-segments and device-posture features where the browser supports them, and in a separating fold prefer two panes with the hinge between them. A cover screen is narrow and very tall (about 23:9, 340 to 360 dp wide); an unfolded inner screen is nearly square (about 840x700 dp). Both must work. iPad multitasking (Split View, Stage Manager) gives arbitrary window sizes and is the closest iOS case. - Aspect ratio range. Phones from 16:9 (short, 320x568) to 23:9; tablets 4:3 to 3:2; unfolded folds near 1:1. Images and crops keep their aspect ratio and are never distorted or cropped differently on another size.
- Text. Font scale 1.0, 1.3 and 2.0 (Dynamic Type up to the largest accessibility sizes) must not clip or overlap: rows grow, text wraps or ends with an ellipsis, no fixed height around text. Test the longest translations and the scripts you ship (Chinese, Japanese, Korean, long Spanish or German titles, 4+ digit numbers, right-to-left if supported).
- Insets and touch. Edge to edge: respect status bar, display cutout, navigation bar, home indicator and rounded corners through insets, never constants. Touch targets at least 48 dp (44 pt on iOS).
- No hard-coded device sizes. No
if (width == 411), no magic number that only fits one phone. A constant is allowed only as a cap, a minimum or the spacing between two elements.