macOS 26 の Liquid Glass では、NavigationStack 配下の ScrollView がツールバーに到達していれば、自動的にグラデーションブラー(スクロールエッジエフェクト)が適用されます。しかし ScrollView の外側に .padding() があると、エフェクトが無効化され、従来型のツールバー表示になる仕様があるようです。
これで丸2日間、Claude Code Opus 4.6と一緒にハマりまくってました。というわけで、備忘録を残しておきます。同じ問題に遭遇したら、このページをClaude Codeに教えてあげてください。
スクロールエッジエフェクトとは
macOS 26 で導入された Liquid Glass デザインでは、スクロール可能なコンテンツがツールバーの下を通過するとき、境界線の代わりにグラデーションブラーで自然にフェードします。これは NavigationStack + ScrollView(または List)の組み合わせで自動的に有効になります。
参考: WWDC25 Session 323 — Liquid Glass in SwiftUI (7:49〜11:10)
問題の再現
NG padding が ScrollView の外側
struct ContentView: View {
let columns = [GridItem(.adaptive(minimum: 150))]
var body: some View {
NavigationStack {
ScrollView {
LazyVGrid(columns: columns, spacing: 12) {
ForEach(0..<100) { i in
RoundedRectangle(cornerRadius: 8)
.fill(.quaternary)
.frame(height: 120)
.overlay { Text("Item \(i)") }
}
}
}
.padding(24) // ← ここが原因
.navigationTitle("Demo")
.toolbar {
ToolbarItem(placement: .automatic) {
Button("Star", systemImage: "star") {}
}
}
}
}
}結果: ツールバーとコンテンツの境界が従来どおりのシャープな線になります。
OK padding を ScrollView の内側に移動
struct ContentView: View {
let columns = [GridItem(.adaptive(minimum: 150))]
var body: some View {
NavigationStack {
ScrollView {
LazyVGrid(columns: columns, spacing: 12) {
ForEach(0..<100) { i in
RoundedRectangle(cornerRadius: 8)
.fill(.quaternary)
.frame(height: 120)
.overlay { Text("Item \(i)") }
}
}
.padding(24) // ← 内側に移動
}
.navigationTitle("Demo")
.toolbar {
ToolbarItem(placement: .automatic) {
Button("Star", systemImage: "star") {}
}
}
}
}
}結果: Liquid Glass のグラデーションブラーが正しく表示されます。
なぜ起きるのか
スクロールエッジエフェクトは、システムが ScrollView のフレームがツールバー領域と接しているかどうか を検知して自動適用しています。

外側の .padding() は ScrollView 自体のフレームを縮めるため、ScrollView が NavigationStack のコンテンツ領域を完全に埋めなくなります。
注意点として、水平・垂直を問わず、方向に関係なくエフェクトが無効化されます。横方向だけのpaddingだとしても、無効になることに注意が必要です。おそらく、Toolbarとすべての領域が接していないとダメ、ということでしょう。

まとめ
| 外側 padding | 内側 padding | |
|---|---|---|
| ScrollView のフレーム | 縮む | ウィンドウ幅いっぱい |
| ツールバーとの接触 | 離れる | 接する |
| スクロールエッジエフェクト | 無効 | 有効 |
Liquid Glass のスクロールエッジエフェクトを活かすには、ScrollView を画面端まで広げ、余白はコンテンツ側で確保することが重要です。これは List や ScrollView に共通する原則です。

