Back to list
ravnhq

swiftui-liquid-glass

by ravnhq

A shared repository of AI tools, workflows, and development knowledge, including reusable agents, skills, and commands that teams can pull into their projects.

0🍴 0📅 Jan 19, 2026

SKILL.md


name: swiftui-liquid-glass description: Guide for adopting Apple's Liquid Glass design system in SwiftUI apps (iOS 26+, macOS Tahoe 26+). Covers glassEffect modifiers, GlassEffectContainer, morphing transitions, platform-specific patterns, and anti-patterns to avoid. license: MIT metadata: version: 1.0.0 model: claude-opus-4-5-20251101 platforms: iOS 26+, iPadOS 26+, macOS Tahoe 26+, watchOS 26+, tvOS 26+

Liquid Glass

Adopt Apple's Liquid Glass design system correctly in SwiftUI.


Triggers

Use this skill when:

  • Building or updating SwiftUI apps for iOS 26+ / macOS Tahoe 26+
  • Implementing glass effects, floating toolbars, or morphing UI
  • User mentions "liquid glass", "glass effect", "iOS 26 design"
  • Reviewing code that uses .glassEffect() or GlassEffectContainer
  • Migrating existing apps to the new Apple design language

Quick Reference

APIPurposeExample
.glassEffect()Basic glass (capsule)view.glassEffect()
.glassEffect(.regular.tint(.blue))Tinted glassColor emphasis
.glassEffect(.regular.interactive())Touch-responsiveButtons, controls
.glassEffect(.clear, in: .circle)High transparencyMedia overlays
GlassEffectContainerGroup + morphMultiple glass views
.glassEffectID(_:in:)Morphing identityAnimated transitions
.buttonStyle(.glass)Translucent buttonStandard actions
.buttonStyle(.glassProminent)Opaque buttonPrimary actions

Core Principle

Glass is for NAVIGATION, not CONTENT.

+----------------------------------------+
|  Glass Layer (toolbars, controls, FAB) |  <-- .glassEffect() HERE
+----------------------------------------+
|                                        |
|  Content Layer (lists, media, text)    |  <-- NEVER glass
|                                        |
+----------------------------------------+

Glass Effect Basics

Minimal Usage

Button("Action") { }
    .padding()
    .glassEffect()  // Default: .regular variant, .capsule shape

Full Signature

.glassEffect(
    _ style: GlassEffectStyle = .regular,
    in shape: some Shape = .capsule,
    isEnabled: Bool = true
)

Variants

VariantTransparencyUse Case
.regularMediumMost UI elements (default)
.clearHighOver media-rich backgrounds
.identityNoneConditional disabling

.clear Requirements (all must be met):

  1. Element is over media-rich content
  2. Content won't suffer from dimming
  3. Content above glass is bold/bright

Tinting

.glassEffect(.regular.tint(.blue))
.glassEffect(.regular.tint(.purple.opacity(0.6)))

Interactive (iOS only)

.glassEffect(.regular.interactive())  // Enables touch feedback

Interactive behaviors:

  • Scale on press
  • Bounce animation
  • Shimmer effect
  • Touch-point illumination

Shapes

ShapeCodePlatform Preference
Capsule.capsule (default)iOS/iPadOS primary
Circle.circleIcon buttons
Rounded RectRoundedRectangle(cornerRadius: 16)macOS preference
Concentric.rect(cornerRadius: .containerConcentric)Nested elements
Ellipse.ellipseSpecial cases

Platform-Specific Shapes

#if os(iOS)
.glassEffect(in: .capsule)  // iOS favors capsules
#else
.glassEffect(in: RoundedRectangle(cornerRadius: 8))  // macOS: rounded rect for small controls
#endif

GlassEffectContainer

Required when using multiple glass effects. Provides:

  • Automatic blending of overlapping shapes
  • Consistent blur/lighting
  • Smooth morphing transitions
  • Better rendering performance

Basic Usage

GlassEffectContainer {
    HStack(spacing: 16) {
        Button("Home") { }
            .glassEffect()
        Button("Search") { }
            .glassEffect()
        Button("Profile") { }
            .glassEffect()
    }
    .padding()
}

Spacing Parameter

Controls merge distance—elements within this distance morph together:

GlassEffectContainer(spacing: 40) {
    // Elements within 40pt blend/morph
}

Morphing Transitions

Fluid shape transitions require three components:

  1. GlassEffectContainer grouping
  2. @Namespace for identity tracking
  3. .glassEffectID(_:in:) modifier

Example: Expandable Toolbar

struct ExpandableToolbar: View {
    @State private var isExpanded = false
    @Namespace private var animation

    var body: some View {
        GlassEffectContainer(spacing: 30) {
            HStack(spacing: 12) {
                Button {
                    withAnimation(.bouncy) {
                        isExpanded.toggle()
                    }
                } label: {
                    Image(systemName: isExpanded ? "chevron.left" : "plus")
                }
                .glassEffect(.regular.interactive())
                .glassEffectID("toggle", in: animation)

                if isExpanded {
                    Button("Edit") { }
                        .glassEffect()
                        .glassEffectID("edit", in: animation)

                    Button("Share") { }
                        .glassEffect()
                        .glassEffectID("share", in: animation)

                    Button("Delete") { }
                        .glassEffect(.regular.tint(.red))
                        .glassEffectID("delete", in: animation)
                }
            }
            .padding()
        }
    }
}

Button Styles

// Translucent - standard actions
Button("Cancel") { }
    .buttonStyle(.glass)

// Opaque/emphasized - primary actions
Button("Done") { }
    .buttonStyle(.glassProminent)

Modifier Order

Apply .glassEffect() AFTER appearance modifiers:

// CORRECT
Text("Label")
    .font(.headline)
    .foregroundStyle(.white)
    .padding()
    .glassEffect()

// WRONG - glass applied before styling
Text("Label")
    .glassEffect()
    .font(.headline)  // Won't work as expected

Accessibility

Liquid Glass automatically adapts to accessibility settings:

SettingAdaptation
Reduce TransparencyIncreased frosting
Increase ContrastStark colors/borders
Reduce MotionToned down animations

Manual Override (if needed)

@Environment(\.accessibilityReduceTransparency) var reduceTransparency

.glassEffect(reduceTransparency ? .identity : .regular)

Anti-Patterns

Don'tWhyInstead
Glass on content (lists, tables)Obscures readabilityGlass on navigation only
Multiple glass views without containerPerformance + no morphingUse GlassEffectContainer
Inconsistent shapes across appVisual fragmentationPick one shape family
Skip animation on state changesJarring transitionsAlways use withAnimation
.clear over dimmable contentContent becomes unreadableUse .regular
.interactive() without purposeConfusing affordancesOnly for tappable elements
Glass on every viewVisual noiseSelective, purposeful use

Common Patterns

Floating Action Button

GlassEffectContainer {
    Button {
        // action
    } label: {
        Image(systemName: "plus")
            .font(.title2)
            .foregroundStyle(.white)
    }
    .frame(width: 56, height: 56)
    .glassEffect(.regular.interactive(), in: .circle)
}

Toolbar

GlassEffectContainer {
    HStack {
        ToolbarButton(icon: "pencil")
        ToolbarButton(icon: "trash")
        Spacer()
        ToolbarButton(icon: "square.and.arrow.up")
    }
    .padding(.horizontal)
    .padding(.vertical, 8)
}

struct ToolbarButton: View {
    let icon: String
    var body: some View {
        Button { } label: {
            Image(systemName: icon)
                .frame(width: 44, height: 44)
        }
        .glassEffect(.regular.interactive())
    }
}

Segmented Control

GlassEffectContainer(spacing: 0) {
    HStack(spacing: 0) {
        ForEach(options, id: \.self) { option in
            Button(option) {
                withAnimation(.bouncy) {
                    selected = option
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 8)
            .glassEffect(selected == option ? .regular : .identity)
        }
    }
}

Platform Requirements

PlatformMinimum Version
iOS26.0+
iPadOS26.0+
macOSTahoe 26.0+
watchOS26.0+
tvOS26.0+
Xcode26+

Verification Checklist

Before shipping Liquid Glass UI:

  • Glass applied only to navigation layer, not content
  • All multiple glass views wrapped in GlassEffectContainer
  • .glassEffect() applied after appearance modifiers
  • Consistent shape usage (capsule vs rounded rect)
  • State changes wrapped in withAnimation
  • .interactive() only on tappable elements
  • Tested with Reduce Transparency enabled
  • Tested on target platforms

References


Sources

Score

Total Score

55/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

0/5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon