Technical guide
25

Technical guide · Published Oct 9, 2025

I Had to Turn Down Liquid Glass to Test It Properly

The full Liquid Glass effect became distracting while I built with it. Here is how I handled Reduce Motion and Dynamic Type in SwiftUI.

A field-guide drawing of a California black bear
In this article3 sections

I started building a UI with iOS 26’s Liquid Glass design language: .glassEffect() modifiers, blur animations, refraction, and parallax. After a while, the full effect became distracting even to me. That made Reduce Motion part of the implementation, not a cleanup task. This first part covers Reduce Motion and Dynamic Type. Part 2 covers VoiceOver and testing.

What Liquid Glass Does

iOS 26 introduces Liquid Glass, Apple’s unified design language influenced by visionOS. It replaces iOS 7’s flat design with rounded, translucent elements that refract, blur, and respond to motion, content, and user input.

The effect combines refraction, light response, morphing, and adaptive blur. Larger glass elements simulate thicker glass with deeper shadows and more pronounced lensing.

Important iOS 26’s Liquid Glass design can cause accessibility issues if not handled properly. Blur, refraction, and parallax effects may trigger motion sickness for users with vestibular disorders.

Leaving blur, refraction, and parallax untested creates accessibility problems. Three settings matter here: Reduce Motion, Reduce Transparency, and VoiceOver.

Apple built accessibility into Liquid Glass directly. Reduce Motion decreases glass effect intensity, disables elastic properties, and removes parallax and refraction animations. Reduce Transparency makes Liquid Glass “frostier” and more opaque, obscuring more content behind glass to improve contrast. Combined settings (Reduce Transparency + Reduce Motion + Dark Mode) deliver the best visibility, performance, and battery life. Liquid Glass then behaves more like iOS 25’s flat design.

Disable Liquid Glass Animations with Reduce Motion

When users enable Reduce Motion, disable or simplify blur animations, parallax, refraction, and elastic morphing. Liquid Glass’s dynamic refraction and morphing animations can trigger motion sickness in users with vestibular disorders.

Implementation:

struct AnimatedBadge: View {
    @Environment(\.accessibilityReduceMotion) private var reduceMotion
    @State private var animate = false

    var body: some View {
        let animation = reduceMotion
            ? .none
            : .easeInOut(duration: 0.8).repeatForever(autoreverses: true)

        Circle()
            .fill(Color.blue)
            .frame(width: 12, height: 12)
            .scaleEffect(animate ? 1.2 : 1.0)
            .onAppear {
                guard !reduceMotion else { return }
                withAnimation(animation) {
                    animate = true
                }
            }
    }
}

The pattern: read @Environment(\.accessibilityReduceMotion), set animation to .none when enabled, and early return in onAppear to prevent state changes.

Liquid Glass with Reduce Motion:

struct GlassCard: View {
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    var body: some View {
        VStack {
            Text("Content")
        }
        .padding()
        .background {
            if reduceMotion {
                // Fallback: simple blur without morphing
                RoundedRectangle(cornerRadius: 16)
                    .fill(.ultraThinMaterial)
            } else {
                // Full Liquid Glass effect
                RoundedRectangle(cornerRadius: 16)
                    .glassEffect(.regular.interactive())
            }
        }
    }
}

When Reduce Motion is on, replace .glassEffect() with .ultraThinMaterial or .regularMaterial. You keep the blur without the morphing and refraction.

Warning Do not wrap the Reduce Motion check in onAppear alone. If the user toggles Reduce Motion while your app is open, @Environment updates the view automatically but onAppear does not re-fire.

Scalable Text with Dynamic Type

Dynamic Type lets users adjust text size system-wide. SwiftUI text styles (.headline, .body, .caption) scale automatically, but you still need to handle layout constraints. Users with visual impairments rely on larger sizes up to accessibility5.

Implementation:

Text(item.name)
    .font(.headline)
    .fontWeight(.semibold)
    .lineLimit(2)
    .multilineTextAlignment(.leading)
    .dynamicTypeSize(...DynamicTypeSize.accessibility5)

Use SwiftUI’s built-in text styles instead of fixed point sizes. The range operator ...DynamicTypeSize.accessibility5 caps the maximum text size. Allow at least 2 lines to prevent truncation at larger sizes. Test with Settings -> Accessibility -> Display & Text Size -> Larger Text.

Capping Dynamic Type: You can cap at a maximum size when unlimited scaling breaks layouts:

Text("Fixed Layout Text")
    .font(.body)
    .dynamicTypeSize(.medium...DynamicTypeSize.xxxLarge)

This allows scaling up to xxxLarge, but it also prevents the larger accessibility sizes. I treat that cap as a last resort after trying to make the layout adapt.

Continue to Part 2 for VoiceOver support and testing strategies.

One quick signal

Did this earn your time?

What was missing?

Thanks. That gives me something concrete to check.