Shadow (árnyék) — egy vizuális effekt a mobil felületeken, amely az elemek közötti mélység és hierarchia illúzióját kelti. Az árnyékok megmutatják, hogy melyik elem van magasabban a Z-síkban, és ezért fontosabb vagy interaktívabb. A Material Design Guidelines (Google, 2026) szerint a rendszerárnyékok öt kulcsfontosságú magasságot (elevation) használnak: 0 dp (lapos), 1–4 dp (gombok), 6–12 dp (kártyák), 16–24 dp (párbeszédablakok), 24+ dp (modális ablakok). Bővebben az elemek magasságáról olvasson az Elevationról szóló cikkben.
Főbb pontok
Árnyék (shadow) a felhasználói felületeken — egy vizuális effekt, amely a megvilágítást és mélységet utánozza. Az árnyékot az elem egy sötét elmosott másolatának megrajzolásával hozzák létre, amely el van tolva az eredetihez képest. A mobil designban az árnyékok három funkciót töltenek be: mutatják a hierarchiát (magasabb elem — hosszabb árnyék), jelzik az interaktivitást (az árnyékos gombok kattinthatónak tűnnek), elválasztják a tartalmat a háttértől (az árnyékos kártyák különálló blokkként olvashatók).
A Google Material Designjában az árnyékok elválaszthatatlanul kapcsolódnak az elevation (magasság) koncepciójához. Minden elem egy bizonyos magasságot foglal el a Z-koordinátában, és az árnyék a felülről érkező megvilágítás vetülete. Az Apple Human Interface Guidelines nem ír elő szigorú magassági rendszert, de javasolja az árnyékok használatát a vizuális hierarchia és mélység létrehozásához a felületeken.
A Nielsen Norman Group (2024) kutatása szerint a megfelelően elhelyezett árnyékok 24%-kal csökkentik az interaktív elem megtalálásának idejét. Az árnyékok segítenek a látássérült felhasználóknak is az elemek határainak megkülönböztetésében. Az árnyékok túlzott használata (3+ szint egy képernyőn) azonban növeli a kognitív terhelést és rontja az érzékelést.
iOS-en az árnyékok a CALayer tulajdonságain keresztül valósulnak meg: a shadowColor beállítja az árnyék színét, a shadowOffset — az eltolást CGSize-ban (x, y), a shadowRadius — az elmosás sugarát, a shadowOpacity — az átlátszatlanságot 0-tól 1-ig. A teljesítmény érdekében ajánlott a shadowPath — az árnyék alakját leíró UIBezierPath beállítása is, hogy a Core Animation ne számolja ki automatikusan.
// UIKit: árnyék beállítása CALayer-en keresztül
import UIKit
let cardView = UIView()
cardView.backgroundColor = .systemBackground
cardView.layer.cornerRadius = 12
// Árnyék beállítása
cardView.layer.shadowColor = UIColor.black.cgColor
cardView.layer.shadowOpacity = 0.15
cardView.layer.shadowOffset = CGSize(width: 0, height: 4)
cardView.layer.shadowRadius = 8
"> Optimalizáció: explicit shadowPath
cardView.layer.shadowPath = UIBezierPath(
roundedRect: cardView.bounds,
cornerRadius: 12
).cgPath
SwiftUI-ban az árnyékok a .shadow() módosítóval állíthatók be a color, radius, x, y paraméterekkel. A SwiftUI automatikusan alkalmazza a shadowPath-ot és kezeli a megjelenítés teljesítményét. Speciális árnyékokhoz (belső árnyékok, többszörös árnyékok) használja az overlay() függvényt LinearGradient-tel.
// SwiftUI: árnyék a shadow módosítón keresztül
import SwiftUI
VStack {
Text("Kártya árnyékkal")
.padding()
.background(Color.white)
.cornerRadius(16)
.shadow(
color: .black.opacity(0.15),
radius: 10,
x: 0,
y: 4
)
}
Árnyékok teljesítménye iOS-en: ha a shadowPath nincs beállítva, a Core Animation minden képkockában kiszámítja az árnyékot a réteg alakja alapján, ami lassulást okozhat animáció közben. Statikus elemeknél mindig állítsa be a shadowPath-ot. Animált elemeknél használja a shouldRasterize = true értéket a CALayer-en, hogy az árnyék egy külön rétegbe legyen gyorsítótárazva. SwiftUI-ban a raszterizáció a .drawingGroup() segítségével kezelhető.
Androidon a Material Design árnyékai az elevation — a View tulajdonságán keresztül valósulnak meg, amely az elem magasságát állítja be a Z-koordinátában. A rendszer automatikusan lerajzolja az árnyékot az elevation és az outlineProvider (az elem kontúrja) alapján. Minél magasabb az elevation, annál nagyobb és elmosódottabb az árnyék. Azoknál a View-knél, amelyek nem örökölnek a Material Design-ból (pl. AppCompat), az árnyékok csak bekapcsolt hardveres gyorsítással működnek.
<!-- XML: elevation attribútumokon keresztül -->
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp"
app:cardElevation="6dp">
<!-- Kártya tartalma -->
</androidx.cardview.widget.CardView>
Egyéni árnyékokhoz az Android View rendszerben az OutlineProvider-t használják. A ViewOutlineProvider lehetővé teszi tetszőleges alakzat beállítását az outline.setRoundRect() vagy outline.setPath() segítségével. OutlineProvider nélkül az árnyék a View téglalap alakja alapján rajzolódik ki, ami nem veszi figyelembe a sarkok lekerekítését.
// Kotlin: egyéni OutlineProvider árnyékhoz
import android.graphics.Outline
import android.view.View
import android.view.ViewOutlineProvider
val myView: View = findViewById(R.id.myView)
myView.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(
0, 0, view.width, view.height,
12f // sarok sugara
)
}
}
myView.elevation = 8f // árnyék magassága px-ben
myView.translationZ = 4f // további magasság lenyomáskor
Jetpack Compose-ban az árnyékokat a Modifier.shadow() és az elevation kezeli a Card és Surface komponensekben. A Modifier.shadow() elfogadja az elevation-t és a shape-t. A View rendszertől eltérően a Compose a saját megjelenítési csővezetékében rajzolja az árnyékokat, ami kiszámíthatóbb viselkedést biztosít az Android összes verzióján.
// Jetpack Compose: árnyék a Modifier.shadow-on keresztül
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Card(
modifier = Modifier.shadow(
elevation = 6.dp,
shape = RoundedCornerShape(12.dp),
clip = false
),
colors = CardDefaults.cardColors(containerColor = Color.White)
) {
Text("Card egyéni árnyékkal")
}
Az árnyékok helyes használata javítja a felület érzékelését, a helytelen használat vizuális zajt kelt és rontja a teljesítményt. A Material Design öt elevation szintet határoz meg: 0 dp (árnyék nélkül), 1–4 dp (gombok, chipek), 6–12 dp (kártyák, menük), 16–24 dp (párbeszédablakok, alsó panelek), 24+ dp (modális ablakok, FAB).
| Szint | Elevation | Elemek | Árnyék jellemzői |
|---|---|---|---|
| 0 | 0 dp | Szöveg, ikonok, háttér | Árnyék nélkül, lapos réteg |
| 1 | 1–4 dp | Gombok, beviteli mezők | Könnyű árnyék, kis eltolás |
| 2 | 6–12 dp | Kártyák, Snackbar | Mérsékelt árnyék, észrevehető elmosás |
| 3 | 16–24 dp | Párbeszédablakok, menük | Mély árnyék, nagy elmosás |
| 4 | 24+ dp | Modális ablakok | Maximális árnyék, az elem lebeg |
Jó gyakorlat szabályai: (1) ne használjon árnyékot olyan elemekhez, amelyek nem vonhatják magukra a figyelmet (hátterek, elválasztók), (2) az árnyék magasságának meg kell felelnie az elem fontosságának — minél fontosabb, annál magasabb, (3) gombnyomáskor animáltan csökkentse az elevation-t a tapintási visszajelzés érdekében, (4) kerülje az árnyékokat sötét háttereken — használjon overlay-t (világosítás/sötétítés) árnyék helyett. A Material You-ban (Android 12+) az árnyékok alkalmazkodnak a témához: sötét háttéren az elevation-t színes réteg (surface tint) helyettesíti.
A Flutterben az árnyékok a BoxDecoration-on belüli BoxShadow segítségével valósulnak meg. A BoxShadow elfogadja a color, offset, blurRadius és spreadRadius paramétereket. A Flutter támogatja a többszörös árnyékokat: a BoxShadow lista átadása lehetővé teszi összetett effektusok létrehozását — például külső árnyék + belső megvilágítás. PhysicalModel — egy alternatíva, amely fizikai árnyékot szimulál az alak alapján (BeveledRectangleBorder, CircleBorder).
// Flutter: árnyék BoxDecoration + BoxShadow segítségével
import 'package:flutter/material.dart';
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
offset: Offset(0, 4),
blurRadius: 8.0,
spreadRadius: 0,
),
],
),
child: Text('Konténer árnyékkal'),
)
// PhysicalModel fizikai árnyékhoz
PhysicalModel(
color: Colors.white,
elevation: 6.0,
shadowColor: Colors.black.withOpacity(0.2),
borderRadius: BorderRadius.circular(12.0),
child: Text('Fizikai modell árnyékkal'),
)
Teljesítmény: A többszörös árnyékkal rendelkező BoxShadow minden változásnál újrarajzolást (repaint) okozhat. Statikus elemekhez használja a PhysicalModel-t — ez egy külön rétegben gyorsítótárazza az árnyékot (RepaintBoundary). A Flutter 3.16+-ban hozzáadták a Material 3 elevation támogatását adaptív árnyékokkal, amelyek a témától függően változtatják a színt és az elmosást (világos/sötét).
Gyakran Ismételt Kérdések
Elevation — az elem numerikus magassága a Z-koordinátában, míg a shadow (árnyék) — az e magasság által létrehozott vizuális effekt. Androidon az elevation — a View tulajdonsága, amely automatikusan generálja az árnyékot. A designban az elevation és a shadow gyakran felcserélhető kifejezésként használatos, de technikailag az elevation az ok, a shadow pedig az okozat.
Ellenőrizze: (1) a View rendelkezik-e elevation értékkel 0 felett, (2) be van-e állítva outlineProvider (ha a View nem a Material könyvtárból származik), (3) be van-e kapcsolva a hardveres gyorsítás (android:hardwareAccelerated="true" a manifestben). A CardView automatikusan kezeli az outlineProvider-t. Egyéni View-knél hívja meg a view.outlineProvider = ViewOutlineProvider.BACKGROUND kódot.
A CALayer nem támogatja közvetlenül a belső árnyékokat. Használjon kombinációt: CAGradientLayer fekete színnel és átlátszósággal a maszkon (mask) belül, vagy helyezzen el egy UIImageView-t raszteres belső árnyékkal. SwiftUI-ban a belső árnyék overlay segítségével valósul meg LinearGradient-tel és blendMode(.multiply) paraméterrel.
Androidon használja a translationZ értéket az animációhoz: nyugalmi állapotban elevation = 2 dp, lenyomáskor translationZ = 4 dp (teljes magasság 6 dp). iOS-en animálja a shadowOffset és shadowRadius értékeket egyidejűleg a gomb transzformációjával. SwiftUI-ban használja a withAnimation-t az elevation Modifier.shadow()-on keresztüli megváltoztatásával. Flutterben — AnimatedContainer a BoxShadow megváltoztatásával.
A Material Design legfeljebb három elevation szintet javasol egy képernyőn. Ha több árnyékos elem van — csoportosítsa őket azonos magasságú csoportokba. A túl sok árnyék vizuális zajt kelt és csökkenti a megjelenítés teljesítményét a középkategóriás és belépő szintű eszközökön.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is