Skip to content

DOMAIN:IOS_DEVELOPMENT:HIG_AND_LIQUID_GLASS

OWNER: martijn
ALSO_USED_BY: valentin, alexander (design), floris/floor (web-ios consistency)
UPDATED: 2026-03-24
SOURCE: Apple Human Interface Guidelines (2025-2026), WWDC 2025 sessions, Liquid Glass design documentation


HIG:LIQUID_GLASS

What Is Liquid Glass

STANDARD: Apple Human Interface Guidelines — Liquid Glass (introduced WWDC 2025, iOS 26/macOS 26)
NOTE: Liquid Glass is Apple's new design language replacing the flat/frosted aesthetic used since iOS 7

DEFINITION: translucent, light-refracting material that responds to content beneath it
EFFECT: UI elements appear as physical glass surfaces — they refract, tint, and blur the background dynamically
APPLIES_TO: navigation bars, tab bars, toolbars, sidebars, alerts, sheets, controls
SCOPE: system-wide across iOS 26, iPadOS 26, macOS 26, watchOS 26, tvOS 26, visionOS 3

Key Visual Properties

  • Translucency: content behind glass elements is visible (blurred and tinted)
  • Refraction: glass bends the light of underlying content (parallax-like depth)
  • Specular highlights: subtle light reflections that respond to device orientation
  • Color tinting: glass picks up colors from content beneath it
  • Dynamic: appearance changes as content scrolls underneath

Impact on App Development

RULE: apps using standard UIKit/SwiftUI components get Liquid Glass automatically when compiled for iOS 26+
RULE: custom chrome (navigation bars, tab bars) MUST be updated to use Liquid Glass materials
RULE: do NOT fight the system — if the system provides Liquid Glass, adopt it
RULE: heavily customized toolbars/navbars from pre-iOS 26 may look broken — audit and update

CHECK: does the app use custom navigation bar appearance?
IF: yes
THEN: test on iOS 26+ — custom backgrounds may conflict with Liquid Glass
FIX: use .toolbarBackgroundVisibility(.automatic) to let system manage glass

CHECK: does the app overlay custom UI on system bars?
IF: yes
THEN: remove overlays — they break glass refraction effect

Liquid Glass Controls

NEW_IN_IOS_26:
- Glass-style buttons: Button("Action").buttonStyle(.glass) or .glassEffect()
- Glass tab bar: automatic for TabView (standard)
- Glass navigation bar: automatic for NavigationStack (standard)
- Glass sheets: .presentationBackground(.glass) for modal sheets
- Glass sidebar: automatic for NavigationSplitView
- Floating tab bar: tabs can now appear as floating glass pill at bottom

ANTI_PATTERN: applying .glass style to every UI element
FIX: Liquid Glass is for chrome and controls, NOT for content areas. Content should remain solid/clear.

ANTI_PATTERN: using opaque backgrounds on bars that should be glass
FIX: remove .toolbarBackground(.visible, for: .navigationBar) hardcoding — let system decide


HIG:CORE_PRINCIPLES

1. Clarity

RULE: text must be legible at every size
RULE: icons must be precise and recognizable
RULE: adornments are subtle — never compete with content
RULE: negative space gives focus

2. Deference

RULE: UI recedes, content is primary
RULE: translucent/glass elements let content show through
RULE: full-screen content where appropriate (photos, video, maps)

3. Depth

RULE: visual layers communicate hierarchy
RULE: gesture-based transitions reveal depth (swipe back, pull down)
RULE: Liquid Glass adds physical depth to chrome elements


HIG:NAVIGATION_PATTERNS

Tab Bar (Primary)

STANDARD: HIG — Tab Bars
USE_WHEN: 3-5 top-level sections of equal importance
RULE: max 5 tabs on iPhone (More tab for additional items)
RULE: iPad can show more tabs
RULE: tab bar is persistent — visible on all screens
RULE: each tab maintains its own navigation state
RULE: Liquid Glass tab bar is now default in iOS 26 — floats as translucent pill

IF: fewer than 3 sections
THEN: do not use tab bar — use direct navigation
IF: more than 5 sections
THEN: prioritize top 4-5, put rest in "More" or redesign information architecture

STANDARD: HIG — Navigation
USE_WHEN: hierarchical content (list → detail → sub-detail)
RULE: always provide back navigation (system handles via swipe-back gesture)
RULE: navigation title describes current location
RULE: large title collapses to inline title on scroll
RULE: in iOS 26, navigation bar uses Liquid Glass

STANDARD: HIG — Sidebars
USE_WHEN: multi-column layout on iPad or Mac (sidebar → content → detail)
RULE: collapses to single column on iPhone automatically
RULE: sidebar uses Liquid Glass material
RULE: 2-column or 3-column depending on content depth

STANDARD: HIG — Sheets
USE_WHEN: focused task that user completes or cancels (create, edit, compose)
RULE: sheet dismissal via swipe-down gesture
RULE: use .presentationDetents for half-sheet patterns
RULE: confirmation before dismissing sheets with unsaved changes
RULE: in iOS 26, sheets can use Liquid Glass background


HIG:TYPOGRAPHY

STANDARD: HIG — Typography
FONT: SF Pro (system default, do NOT bundle — it's a system font)
FONT: SF Mono (code/monospace)
FONT: SF Pro Rounded (playful contexts)
FONT: New York (serif, editorial contexts)

Text Styles (Use These, Not Fixed Sizes)

Style Default Size Use For
.largeTitle 34pt Screen titles (rare)
.title 28pt Section titles
.title2 22pt Sub-section titles
.title3 20pt Card titles
.headline 17pt semibold Row titles, emphasis
.body 17pt Primary content
.callout 16pt Explanatory text
.subheadline 15pt Secondary text
.footnote 13pt Tertiary text, timestamps
.caption 12pt Labels, annotations
.caption2 11pt Smallest readable text

Dynamic Type

RULE: ALL text must support Dynamic Type — no fixed font sizes
RULE: use Text("Hello").font(.body) — NEVER Text("Hello").font(.system(size: 17))
RULE: test at ALL accessibility sizes (Settings → Accessibility → Larger Text)
RULE: layout must not break at the largest Dynamic Type size
RULE: images that contain text alternatives must also scale

TOOL: Xcode → Environment Overrides → Dynamic Type slider
CHECK: does UI remain usable at the 5 largest accessibility sizes?
CHECK: does text truncate or overlap at large sizes?
CHECK: do touch targets remain tappable at large sizes?

ANTI_PATTERN: using fixed font sizes (UIFont.systemFont(ofSize: 17))
FIX: use UIFont.preferredFont(forTextStyle: .body) or SwiftUI .font(.body)

ANTI_PATTERN: constraining view heights with fixed values
FIX: use content-hugging priorities and let text dictate height


HIG:COLOR_SYSTEM

Semantic Colors (Always Use These)

Color Purpose Light Mode Dark Mode
.label Primary text Black White
.secondaryLabel Secondary text Gray Light gray
.tertiaryLabel Tertiary text Lighter gray Darker light gray
.systemBackground Primary background White Black
.secondarySystemBackground Grouped/card bg Light gray Dark gray
.tertiarySystemBackground Third level bg White Darker gray
.separator Divider lines Adapted Adapted
.systemFill Thin overlay Adapted Adapted
.tintColor Interactive elements Blue (default) Blue (default)

RULE: ALWAYS use semantic colors — NEVER hardcode hex values for UI chrome
RULE: custom brand colors are OK for branding elements but must have dark mode variants
RULE: ALWAYS define both light and dark mode colors in asset catalog
RULE: ALWAYS test in dark mode
RULE: ALWAYS test with Increase Contrast accessibility setting

ANTI_PATTERN: using Color.white for backgrounds
FIX: use Color(.systemBackground) — adapts to dark mode

ANTI_PATTERN: using Color.black for text
FIX: use Color(.label) — adapts to dark mode and accessibility

High Contrast

RULE: test with Settings → Accessibility → Increase Contrast
CHECK: all text has minimum 4.5:1 contrast ratio against background (WCAG AA)
CHECK: interactive elements are distinguishable from decorative elements
CHECK: focus indicators are visible


HIG:ACCESSIBILITY

VoiceOver

RULE: ALL interactive elements must have accessibility labels
RULE: images must be decorative (.accessibilityHidden(true)) or have descriptions
RULE: custom controls must declare traits (.accessibilityAddTraits(.isButton))
RULE: grouping: related elements should be combined (.accessibilityElement(children: .combine))
RULE: order: reading order must be logical (.accessibilitySortPriority())
RULE: actions: custom swipe actions (.accessibilityAction())

CHECK: navigate entire app with VoiceOver enabled
CHECK: every screen is usable without seeing the screen
CHECK: form fields have proper labels and error descriptions
CHECK: state changes are announced (.accessibilityValue())

TOOL: Xcode → Accessibility Inspector
TOOL: iPhone → Settings → Accessibility → VoiceOver

Dynamic Type

SEE: typography section above
RULE: support ALL Dynamic Type sizes including accessibility sizes (up to ~310% of default)

Reduce Motion

RULE: check UIAccessibility.isReduceMotionEnabled or @Environment(\.accessibilityReduceMotion)
IF: reduce motion is ON
THEN: replace animations with cross-dissolves
THEN: disable parallax effects
THEN: disable auto-playing video

Reduce Transparency

RULE: check UIAccessibility.isReduceTransparencyEnabled
IF: reduce transparency is ON
THEN: system replaces translucent materials with opaque backgrounds
THEN: Liquid Glass effects are replaced with solid backgrounds
NOTE: the system handles this for standard components — only custom glass needs manual handling

Color Blindness

RULE: never convey information through color alone
RULE: pair color indicators with icons, labels, or patterns
CHECK: status indicators (red/green) must have secondary indicator (icon, text)

Minimum Touch Targets

RULE: 44x44 points minimum for ALL tappable elements
CHECK: buttons, links, toggles, icons all meet minimum size
ANTI_PATTERN: small icon buttons without adequate hit area
FIX: use .frame(minWidth: 44, minHeight: 44) or .contentShape(Rectangle())


HIG:IOS_VS_WEB_DIFFERENCES

NOTE: critical for agents transitioning from web development mindset

Aspect Web iOS Native
Navigation URL-based, browser back button Stack-based, swipe-back gesture
Layout CSS flexbox/grid, responsive breakpoints Auto Layout / SwiftUI layout, trait collections
Typography CSS font-size (px/rem), custom fonts Text Styles, Dynamic Type, system fonts
Colors CSS variables, media query prefers-color-scheme Semantic colors, automatic dark mode
Animations CSS transitions, requestAnimationFrame Core Animation, SwiftUI .animation(), 60fps GPU
Touch click events, hover states tap gestures, long press, swipe, no hover (except iPad pointer)
Scrolling overflow: scroll, virtual scrolling UIScrollView/List, rubber-banding, momentum
Modals CSS overlay, z-index UISheetPresentationController, detents, swipe dismiss
Icons SVG, icon fonts SF Symbols (2000+ system icons, weight/scale adaptive)
State persistence localStorage, cookies UserDefaults, Keychain, SwiftData, file system
Loading states Skeleton screens, spinners ProgressView, pull-to-refresh (.refreshable)

RULE: do NOT replicate web patterns on iOS — use platform-native patterns
RULE: iOS users expect: swipe-back, pull-to-refresh, swipe actions on rows, haptic feedback
ANTI_PATTERN: implementing a hamburger menu on iOS
FIX: use tab bar (bottom) for top-level nav, NavigationStack for hierarchy