Vanilla Breeze

Mobile

How to build mobile-native experiences with Vanilla Breeze: safe areas, app shells, bottom sheets, touch targets, forms, and horizontal scroll.

Philosophy

Most CSS frameworks ignore mobile-specific concerns, leaving you to bolt on safe areas, touch targets, and viewport fixes. VB takes the opposite approach: mobile support ships inside the core.

  • Default — every page gets 44px touch targets on coarse pointers, 100dvh body height, smooth scrolling, and responsive layout collapse. No attributes required.
  • Enhanced — pages designed for mobile add viewport-fit=cover to unlock safe-area tokens, use data-page-layout="app-shell" for bottom-nav shells, and use <dialog data-position="bottom"> for action sheets.
  • Granular — individual inputs get the right virtual keyboard via inputmode, autocomplete, and enterkeyhint.

Because VB’s design tokens drive all sizing and spacing, the @media (pointer: coarse) query only needs to set --size-touch-min: 2.75rem — every button, input, and select automatically adapts.

The viewport-fit Unlock

Modern phones have notches, Dynamic Islands, and home indicators that occupy real pixels. To respect these areas, add viewport-fit=cover to your viewport meta tag:

This activates VB’s safe-area tokens, which are defined automatically in the token layer:

What auto-consumes safe areas

Element Token used
dialog[data-position="bottom"] --safe-bottom (padding)
data-page-layout="app-shell" nav (mobile) --safe-bottom (padding)

For custom fixed bars or sticky footers, apply safe-area tokens manually using calc().

What Works Already

These mobile features are built into VB’s core — no extra attributes or configuration needed.

Concern VB solution
Touch targets @media (pointer: coarse) enforces 44px min on buttons, inputs, selects
Full-height pages body { min-block-size: 100dvh }
Tap highlight -webkit-tap-highlight-color: transparent in reset
iOS text zoom text-size-adjust: none in reset
Smooth scrolling scroll-behavior: smooth (respects reduced-motion)
Sidebar collapse data-layout="sidebar" wraps naturally (intrinsic CSS, no media query)
Column ↔ row flip data-layout="switcher" flips at configurable threshold
Split stack data-layout="split" stacks at < 48rem
Hover-only motion @media (hover: none) disables hover lift/scale
Scroll snap Built into data-layout="reel" and <carousel-wc>
Scroll containment overscroll-behavior: contain on dialogs and sticky nav/aside

App Shell Pattern

The data-page-layout="app-shell" layout creates a header/main/nav grid. On screens narrower than 48rem, the nav automatically moves below main — becoming a bottom navigation bar. Safe-area bottom padding is applied automatically.

See also: Application Shells pattern

Bottom Sheet

VB’s native <dialog> styling includes a bottom drawer variant. It slides up from the bottom, has rounded top corners, respects safe areas, and prevents scroll chaining — all with zero JavaScript beyond the native showModal() API.

The commandfor / command attributes use the Invokers API to open and close the dialog declaratively. In browsers that don’t support Invokers yet, fall back to document.getElementById('my-sheet').showModal().

Drag to Dismiss

Add data-gesture="dismiss-down" to enable swipe-down-to-close on mobile. The gesture library tracks the drag, applies opacity falloff, and closes the sheet when the swipe threshold is met. Buttons and links inside remain interactive.

See also: Dialog element docsBottom Sheet snippet

Mobile Forms

The single biggest mobile form improvement is using the right HTML attributes. These are native HTML — not VB features — but VB’s <form-field> component makes them easy to use correctly.

The attributes that matter

Attribute What it does on mobile
type="email" Shows keyboard with @ key prominent
type="tel" Shows numeric dialpad
inputmode="numeric" Numeric keyboard without spinners (use for credit cards, ZIP codes)
autocomplete="email" Enables one-tap autofill from saved contacts
autocomplete="cc-number" iOS shows camera to scan physical card; Android offers Google Pay
autocomplete="one-time-code" iOS shows SMS suggestion bar above keyboard
enterkeyhint="next" Shows “Next” on the Enter key (guides user through the form)
enterkeyhint="send" Shows “Send” on the last field

See also: autocomplete reference, inputmode reference, enterkeyhint reference

Hero and Horizontal Scroll

Viewport height units

VB’s cover layout supports three viewport height units:

Value Unit Use when
data-layout-min="100svh" Small viewport height Hero sections — always fits when browser chrome is visible
data-layout-min="100dvh" Dynamic viewport height Full-screen app panels — updates as chrome hides on scroll
data-layout-min="100vh" Legacy viewport height Fallback — broken on mobile (ignores browser chrome)

Horizontal card reel

The data-layout="reel" provides a horizontal scroll-snap container. It includes scroll-snap-type: x mandatory, momentum scrolling, and hidden scrollbars. Use it for card feeds, feature showcases, and image galleries.

Browser Support

Feature Chrome Firefox Safari Edge
env(safe-area-inset-*) 69+ 65+ 11.2+ 79+
dvh / svh 108+ 101+ 15.4+ 108+
overscroll-behavior 63+ 59+ 16+ 18+
scroll-snap-type 69+ 68+ 11+ 79+
@media (pointer: coarse) 41+ 64+ 9+ 12+
Invokers API (commandfor) 135+ No No 135+

All core features have 95%+ support on current mobile browsers. The Invokers API is the newest; for broader support, use element.showModal() as a JavaScript fallback.

Scroll Animations

Elements can reveal as they enter the viewport using CSS scroll-driven animations. No JavaScript required — the browser handles timing, throttling, and compositing.

Available animations

Value Effect
fade-upFades in while translating up from 2rem
fade-inOpacity fade only
slide-leftFades in while translating from 2rem right
scale-upFades in from 95% scale

Uses animation-timeline: view() (Chrome 115+, Safari 18+). Unsupported browsers show elements statically — no content is hidden. Animations are disabled when prefers-reduced-motion: reduce is active.

See this in action across the corporate site demo:

Auto-Hiding Header

Headers can hide on scroll-down and reappear on scroll-up — the same pattern as Instagram and Medium.

The CSS adds a smooth translateY(-100%) transition. The JS (auto-loaded when the attribute is present) toggles a data-hidden attribute based on scroll direction.

Contrast with data-scroll-shrink, which shrinks the header but keeps it visible.

Sticky CTA

Two patterns for keeping a call-to-action always reachable:

Sticky bottom bar

Floating action button

Both respect safe-area bottom insets automatically.

Frosted Glass Nav

Add the frosted class to nav.bottom for an iOS-style translucent bottom navigation bar:

Uses backdrop-filter: blur(12px) saturate(180%) with a semi-transparent background. Falls back gracefully to a solid background in unsupported browsers.

Mobile Forms (Advanced)

Phase 3 of the mobile strategy adds keyboard-aware scrolling and optimized form layout for checkout-grade flows.

Keyboard-aware scrolling

Add data-keyboard-aware to a form and inputs will auto-scroll into view when the virtual keyboard opens:

The form.mobile class forces single-column stacking below 48rem and full-width submit buttons on touch devices. The footer.sticky sticks above the virtual keyboard using env(keyboard-inset-height).

Multi-step checkout

Combine form.mobile with data-wizard for step-by-step flows:

Form patterns

See the side-by-side comparison of common form mistakes vs best practices:

Device Showcase

Every mobile demo rendered inside realistic device mockups — iPhone, Pixel, Galaxy, and iPad.

Corporate Homepage (iPhone 16)
App Shell (Pixel 9)
Checkout (Galaxy S24)
Mobile Form (iPhone SE, safe areas)
Pharma Biosite (iPhone 16 Pro Max)