Shadow: essentie, schaduwen creëren in mobiele applicaties

Auteur: IT Sectr Gepubliceerd: 2026-02-28 Leestijd: 9 min

Shadow (schaduw) — een visueel effect in mobiele interfaces dat de illusie van diepte en hiërarchie tussen elementen creëert. Schaduwen laten zien welk element hoger in het Z-vlak ligt en dus belangrijker of interactiever is. Volgens Material Design Guidelines (Google, 2026) gebruiken systeemschaduwen vijf belangrijke hoogtes (elevation): 0 dp (plat), 1–4 dp (knoppen), 6–12 dp (kaarten), 16–24 dp (dialoogvensters), 24+ dp (modale vensters). Lees meer over de hoogte van elementen in het artikel over Elevation.

Belangrijkste punten

  • Schaduw (shadow) — een visueel effect dat diepte creëert door het gebied onder het element donkerder te maken met vervaging aan de randen.
  • Op iOS worden schaduwen ingesteld via de eigenschappen van CALayer: shadowColor, shadowOffset, shadowRadius, shadowOpacity.
  • In Android worden schaduwen beheerd via elevation (Material Design) of aangepaste weergave via OutlineProvider.
  • Jetpack Compose ondersteunt schaduwen via Modifier.shadow() en elevation in Card/Surface.
  • In Flutter worden schaduwen geïmplementeerd via BoxShadow in BoxDecoration of via PhysicalModel.

Wat is een schaduw in UI?

Schaduw (shadow) in gebruikersinterfaces — een visueel effect dat verlichting en diepte nabootst. Een schaduw wordt gecreëerd door een donkere vervaagde kopie van het element te tekenen die verschoven is ten opzichte van het origineel. In mobiel ontwerp vervullen schaduwen drie functies: ze tonen hiërarchie (hoger element — langere schaduw), signaleren interactiviteit (knoppen met schaduw zien er klikbaar uit), scheiden inhoud van achtergrond (kaarten met schaduw worden gelezen als aparte blokken).

In Material Design van Google zijn schaduwen onlosmakelijk verbonden met het concept elevation (hoogte). Elk element neemt een bepaalde hoogte in de Z-coördinaat in, en de schaduw is de projectie van verlichting van bovenaf. De Human Interface Guidelines van Apple schrijven geen strikt systeem van hoogtes voor, maar raden aan schaduwen te gebruiken voor visuele hiërarchie en diepte in interfaces.

Volgens onderzoek van Nielsen Norman Group (2024) verkorten correct geplaatste schaduwen de zoektijd van een interactief element met 24%. Schaduwen helpen ook gebruikers met visuele beperkingen om de grenzen van elementen te onderscheiden. Overmatig gebruik van schaduwen (3+ niveaus op een scherm) verhoogt echter de cognitieve belasting en verslechtert de waarneming.

Schaduwen op iOS: CALayer en SwiftUI

Op iOS worden schaduwen geïmplementeerd via de eigenschappen van CALayer: shadowColor bepaalt de kleur van de schaduw, shadowOffset — de verschuiving in CGSize (x, y), shadowRadius — de vervagingsradius, shadowOpacity — de dekking van 0 tot 1. Voor prestaties wordt ook aanbevolen shadowPath in te stellen — UIBezierPath die de vorm van de schaduw beschrijft, zodat Core Animation deze niet automatisch hoeft te berekenen.

swift
// UIKit: schaduw configureren via CALayer
import UIKit

let cardView = UIView()
cardView.backgroundColor = .systemBackground
cardView.layer.cornerRadius = 12

// Schaduw configureren
cardView.layer.shadowColor = UIColor.black.cgColor
cardView.layer.shadowOpacity = 0.15
cardView.layer.shadowOffset = CGSize(width: 0, height: 4)
cardView.layer.shadowRadius = 8

"> Optimalisatie: expliciete shadowPath
cardView.layer.shadowPath = UIBezierPath(
    roundedRect: cardView.bounds,
    cornerRadius: 12
).cgPath

In SwiftUI worden schaduwen ingesteld via de modifier .shadow() met parameters color, radius, x, y. SwiftUI past automatisch shadowPath toe en beheert de weergaveprestaties. Voor geavanceerde schaduwen (binnenschaduwen, meerdere schaduwen) gebruikt u overlay() met LinearGradient.

swift
// SwiftUI: schaduw via shadow modifier
import SwiftUI

VStack {
    Text("Kaart met schaduw")
        .padding()
        .background(Color.white)
        .cornerRadius(16)
        .shadow(
            color: .black.opacity(0.15),
            radius: 10,
            x: 0,
            y: 4
        )
}

Prestaties van schaduwen op iOS: als shadowPath niet is ingesteld, berekent Core Animation de schaduw op basis van de laagvorm in elk frame, wat vertragingen kan veroorzaken tijdens animaties. Stel voor statische elementen altijd shadowPath in. Gebruik voor geanimeerde elementen shouldRasterize = true op CALayer om de schaduw in een aparte laag te cachen. In SwiftUI wordt rasterisatie beheerd via .drawingGroup().

Schaduwen in Android: elevation en aangepaste schaduwen

In Android worden schaduwen in Material Design geïmplementeerd via elevation — de eigenschap van View die de hoogte van het element in de Z-coördinaat bepaalt. Het systeem tekent automatisch een schaduw op basis van elevation en outlineProvider (de contour van het element). Hoe hoger de elevation, hoe groter en vager de schaduw. Voor Views die niet overerven van Material Design (bijv. AppCompat) werken schaduwen alleen met ingeschakelde hardwareversnelling.

xml
<!-- XML: elevation via attributen -->
<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">
    <!-- Inhoud van kaart -->
</androidx.cardview.widget.CardView>

Voor aangepaste schaduwen in het Android View-systeem wordt OutlineProvider gebruikt. ViewOutlineProvider maakt het mogelijk een willekeurige vorm in te stellen via outline.setRoundRect() of outline.setPath(). Zonder OutlineProvider wordt de schaduw getekend op basis van de rechthoekige vorm van de View, wat geen rekening houdt met afronding van hoeken.

kotlin
// Kotlin: aangepaste OutlineProvider voor schaduw
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  // hoekradius
        )
    }
}
myView.elevation = 8f  // schaduwhoogte in px
myView.translationZ = 4f  // extra hoogte bij indrukken

In Jetpack Compose worden schaduwen beheerd via Modifier.shadow() en elevation in Card- en Surface-componenten. Modifier.shadow() accepteert elevation en shape. In tegenstelling tot het View-systeem tekent Compose schaduwen in zijn eigen weergavepijplijn, wat een voorspelbaarder gedrag geeft op alle Android-versies.

kotlin
// Jetpack Compose: schaduw via Modifier.shadow
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 met aangepaste schaduw")
}

Aanbevelingen voor het gebruik van schaduwen

Correct gebruik van schaduwen verbetert de perceptie van de interface, onjuist gebruik — creëert visuele ruis en verslechtert de prestaties. Material Design definieert vijf niveaus van elevation: 0 dp (geen schaduw), 1–4 dp (knoppen, chips), 6–12 dp (kaarten, menu's), 16–24 dp (dialoogvensters, onderste panelen), 24+ dp (modale vensters, FAB).

NiveauElevationElementenKenmerk van schaduw
00 dpTekst, pictogrammen, achtergrondGeen schaduw, platte laag
11–4 dpKnoppen, invoerveldenLichte schaduw, kleine verschuiving
26–12 dpKaarten, SnackbarMatige schaduw, merkbare vervaging
316–24 dpDialoogvensters, menu'sDiepe schaduw, grote vervaging
424+ dpModale venstersMaximale schaduw, element zweeft

Gebruiksregels: (1) gebruik geen schaduwen voor elementen die geen aandacht moeten trekken (achtergronden, scheidingslijnen), (2) de hoogte van de schaduw moet overeenkomen met het belang van het element — hoe belangrijker, hoe hoger, (3) verlaag bij het indrukken van een knop elevation geanimeerd voor tactiele feedback, (4) vermijd schaduwen op donkere achtergronden — gebruik overlay (lichter/donkerder maken) in plaats van schaduw. In Material You (Android 12+) passen schaduwen zich aan het thema aan: op een donkere achtergrond wordt elevation vervangen door een kleurlaag (surface tint).

Schaduwen in Flutter: BoxShadow en PhysicalModel

In Flutter worden schaduwen geïmplementeerd via BoxShadow binnen BoxDecoration. BoxShadow accepteert color, offset, blurRadius en spreadRadius. Flutter ondersteunt meerdere schaduwen: het doorgeven van een lijst BoxShadow maakt het mogelijk complexe effecten te creëren — bijvoorbeeld een externe schaduw + interne oplichting. PhysicalModel — een alternatief dat een fysieke schaduw simuleert op basis van vorm (BeveledRectangleBorder, CircleBorder).

dart
// Flutter: schaduw via BoxDecoration + BoxShadow
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('Container met schaduw'),
)

// PhysicalModel voor fysieke schaduw
PhysicalModel(
    color: Colors.white,
    elevation: 6.0,
    shadowColor: Colors.black.withOpacity(0.2),
    borderRadius: BorderRadius.circular(12.0),
    child: Text('Fysiek model met schaduw'),
)

Prestaties: BoxShadow met meerdere schaduwen kan bij elke wijziging hertekenen (repaint) veroorzaken. Gebruik voor statische elementen PhysicalModel — het cached de schaduw in een aparte laag (RepaintBoundary). In Flutter 3.16+ is ondersteuning toegevoegd voor Material 3 elevation met adaptieve schaduwen die van kleur en vervaging veranderen afhankelijk van het thema (licht/donker).

Veelgestelde vragen

Wat is het verschil tussen elevation en schaduw?

Elevation — is de numerieke hoogte van een element in de Z-coördinaat, en shadow (schaduw) — het visuele effect dat door deze hoogte wordt gecreëerd. In Android is elevation een eigenschap van View die automatisch een schaduw genereert. In ontwerp worden elevation en shadow vaak als uitwisselbare termen gebruikt, maar technisch is elevation de oorzaak en shadow het gevolg.

Waarom wordt de schaduw niet weergegeven op Android?

Controleer: (1) of View een elevation groter dan 0 heeft, (2) of outlineProvider is ingesteld (als View niet uit de Material-bibliotheek komt), (3) of hardwareversnelling is ingeschakeld (android:hardwareAccelerated="true" in het manifest). CardView beheert outlineProvider automatisch. Voor aangepaste Views roept u view.outlineProvider = ViewOutlineProvider.BACKGROUND aan.

Hoe maak ik een inner shadow op iOS?

CALayer ondersteunt geen binnenschaduwen direct. Gebruik een combinatie: CAGradientLayer met zwarte kleur en transparantie binnen de mask (mask), of plaats een UIImageView met een raster-binnenschaduw. In SwiftUI wordt een binnenschaduw geïmplementeerd via overlay met LinearGradient en blendMode(.multiply).

Hoe animeer ik een schaduw bij het indrukken van een knop?

In Android gebruikt u translationZ voor animatie: in rusttoestand elevation = 2 dp, bij indrukken translationZ = 4 dp (totale hoogte 6 dp). Op iOS animeert u shadowOffset en shadowRadius gelijktijdig met de transformatie van de knop. In SwiftUI gebruikt u withAnimation met wijziging van elevation via Modifier.shadow(). In Flutter — AnimatedContainer met wijziging van BoxShadow.

Hoeveel schaduwen kunnen er op één scherm worden gebruikt?

Material Design raadt niet meer dan drie niveaus van elevation op één scherm aan. Als er meer elementen met schaduw zijn — combineer ze in groepen met dezelfde hoogte. Een overmatig aantal schaduwen creëert visuele ruis en vermindert de weergaveprestaties op apparaten uit het middensegment en budgetsegment.

Samenvatting

  • Schaduw (shadow) — een visueel diepte-effect gebaseerd op elevation van het element in de Z-coördinaat.
  • Op iOS worden schaduwen geconfigureerd via CALayer: shadowColor, shadowOffset, shadowRadius, shadowOpacity.
  • In Android worden schaduwen beheerd via elevation en OutlineProvider voor aangepaste vorm.
  • Material Design definieert vijf niveaus van elevation: 0, 1–4, 6–12, 16–24 en 24+ dp.
  • Jetpack Compose gebruikt Modifier.shadow() en elevation in Card/Surface voor het beheren van schaduwen.
  • Flutter implementeert schaduwen via BoxShadow (BoxDecoration) en PhysicalModel (fysieke schaduw).
  • Optimalisatie: stel shadowPath in (iOS), outlineProvider (Android), gebruik PhysicalModel (Flutter).

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook