Shadow (anino) — isang biswal na epekto sa mga mobile interface na lumilikha ng ilusyon ng lalim at hierarchy sa pagitan ng mga elemento. Ipinapakita ng mga anino kung aling elemento ang mas mataas sa Z-plane at samakatuwid ay mas mahalaga o interactive. Ayon sa Material Design Guidelines (Google, 2026), ang mga system shadow ay gumagamit ng limang pangunahing taas (elevation): 0 dp (patag), 1–4 dp (mga button), 6–12 dp (mga card), 16–24 dp (mga dialog), 24+ dp (mga modal window). Magbasa pa tungkol sa taas ng mga elemento sa artikulo tungkol sa Elevation.
Mga Pangunahing Punto
Anino (shadow) sa mga user interface — isang biswal na epekto na ginagaya ang ilaw at lalim. Ang anino ay nilikha sa pamamagitan ng pagguhit ng madilim na malabong kopya ng elemento na inilipat mula sa orihinal. Sa mobile design, ang mga anino ay may tatlong function: nagpapakita ng hierarchy (mas mataas na elemento — mas mahabang anino), nagpapahiwatig ng interaktibidad (mga button na may anino ay mukhang naki-click), naghihiwalay ng nilalaman mula sa background (mga card na may anino ay binabasa bilang magkakahiwalay na bloke).
Sa Material Design ng Google, ang mga anino ay hindi mapaghihiwalay na nauugnay sa konsepto ng elevation (taas). Ang bawat elemento ay sumasakop sa isang tiyak na taas sa Z-coordinate, at ang anino ay projection ng ilaw mula sa itaas. Ang Human Interface Guidelines ng Apple ay hindi nag-uutos ng mahigpit na sistema ng taas, ngunit inirerekomenda ang paggamit ng mga anino upang lumikha ng biswal na hierarchy at lalim sa mga interface.
Ayon sa pananaliksik ng Nielsen Norman Group (2024), ang mga tamang pagkakalagay na anino ay nagbabawas ng oras ng paghahanap ng isang interactive na elemento ng 24%. Ang mga anino ay tumutulong din sa mga user na may kapansanan sa paningin na makilala ang mga hangganan ng elemento. Gayunpaman, ang labis na paggamit ng mga anino (3+ na antas sa isang screen) ay nagpapataas ng cognitive load at nagpapababa ng persepsyon.
Sa iOS ang mga anino ay ipinapatupad sa pamamagitan ng mga property ng CALayer: shadowColor ay nagtatakda ng kulay ng anino, shadowOffset — ang displacement sa CGSize (x, y), shadowRadius — ang radius ng paglabo, shadowOpacity — ang opacity mula 0 hanggang 1. Para sa performance, inirerekomenda din na itakda ang shadowPath — UIBezierPath na naglalarawan ng hugis ng anino, upang hindi ito kalkulahin ng Core Animation nang awtomatiko.
// UIKit: pag-configure ng anino sa pamamagitan ng CALayer
import UIKit
let cardView = UIView()
cardView.backgroundColor = .systemBackground
cardView.layer.cornerRadius = 12
// Pag-configure ng anino
cardView.layer.shadowColor = UIColor.black.cgColor
cardView.layer.shadowOpacity = 0.15
cardView.layer.shadowOffset = CGSize(width: 0, height: 4)
cardView.layer.shadowRadius = 8
"> Optimisasyon: tahasang shadowPath
cardView.layer.shadowPath = UIBezierPath(
roundedRect: cardView.bounds,
cornerRadius: 12
).cgPath
Sa SwiftUI ang mga anino ay itinatakda sa pamamagitan ng modifier na .shadow() na may mga parameter na color, radius, x, y. Awtomatikong inilalapat ng SwiftUI ang shadowPath at pinamamahalaan ang performance ng rendering. Para sa mga advanced na anino (inner shadow, maramihang anino) gamitin ang overlay() na may LinearGradient.
// SwiftUI: anino sa pamamagitan ng shadow modifier
import SwiftUI
VStack {
Text("Card na may anino")
.padding()
.background(Color.white)
.cornerRadius(16)
.shadow(
color: .black.opacity(0.15),
radius: 10,
x: 0,
y: 4
)
}
Performance ng mga anino sa iOS: kung hindi nakatakda ang shadowPath, kinakalkula ng Core Animation ang anino batay sa hugis ng layer sa bawat frame, na maaaring magdulot ng pagbagal sa panahon ng animation. Para sa mga static na elemento, palaging itakda ang shadowPath. Para sa mga animated na elemento, gamitin ang shouldRasterize = true sa CALayer upang i-cache ang anino sa isang hiwalay na layer. Sa SwiftUI, ang rasterization ay pinamamahalaan sa pamamagitan ng .drawingGroup().
Sa Android ang mga anino sa Material Design ay ipinapatupad sa pamamagitan ng elevation — ang property ng View na nagtatakda ng taas ng elemento sa Z-coordinate. Awtomatikong gumuhit ang system ng anino batay sa elevation at outlineProvider (contour ng elemento). Kung mas mataas ang elevation, mas malaki at malabo ang anino. Para sa mga View na hindi nagmamana ng Material Design (hal. AppCompat), gumagana lang ang mga anino kapag naka-enable ang hardware acceleration.
<!-- XML: elevation sa pamamagitan ng attributes -->
<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">
<!-- Nilalaman ng card -->
</androidx.cardview.widget.CardView>
Para sa custom na anino sa Android View System, ginagamit ang OutlineProvider. Ang ViewOutlineProvider ay nagbibigay-daan sa pagtatakda ng arbitraryong hugis sa pamamagitan ng outline.setRoundRect() o outline.setPath(). Kung walang OutlineProvider, ang anino ay iginuguhit batay sa rectangular na hugis ng View, na hindi isinasaalang-alang ang pag-ikot ng mga sulok.
// Kotlin: custom na OutlineProvider para sa anino
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 // radius ng sulok
)
}
}
myView.elevation = 8f // taas ng anino sa px
myView.translationZ = 4f // karagdagang taas kapag pinindot
Sa Jetpack Compose ang mga anino ay pinamamahalaan sa pamamagitan ng Modifier.shadow() at elevation sa mga component na Card at Surface. Ang Modifier.shadow() ay tumatanggap ng elevation at shape. Hindi tulad ng View System, iginuguhit ng Compose ang mga anino sa sarili nitong rendering pipeline, na nagbibigay ng mas predictable na pag-uugali sa lahat ng bersyon ng Android.
// Jetpack Compose: anino sa pamamagitan ng 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 na may custom na anino")
}
Ang tamang paggamit ng mga anino ay nagpapabuti sa persepsyon ng interface, ang maling paggamit — ay lumilikha ng visual na ingay at nagpapababa ng performance. Tinutukoy ng Material Design ang limang antas ng elevation: 0 dp (walang anino), 1–4 dp (mga button, chips), 6–12 dp (mga card, menu), 16–24 dp (mga dialog, bottom panel), 24+ dp (mga modal window, FAB).
| Antas | Elevation | Mga Elemento | Katangian ng Anino |
|---|---|---|---|
| 0 | 0 dp | Teksto, icon, background | Walang anino, patag na layer |
| 1 | 1–4 dp | Mga button, input field | Magaan na anino, maliit na displacement |
| 2 | 6–12 dp | Mga card, Snackbar | Katamtamang anino, kapansin-pansing paglabo |
| 3 | 16–24 dp | Mga dialog, menu | Malalim na anino, malaking paglabo |
| 4 | 24+ dp | Mga modal window | Maksimum na anino, lumulutang ang elemento |
Mga alituntunin ng mabuting praktika: (1) huwag gumamit ng anino para sa mga elementong hindi dapat makaakit ng pansin (background, separator), (2) ang taas ng anino ay dapat tumugma sa kahalagahan ng elemento — mas mahalaga, mas mataas, (3) kapag pinindot ang button, bawasan ang elevation nang may animation para sa tactile feedback, (4) iwasan ang mga anino sa madidilim na background — gumamit ng overlay (pagpapaliwanag/pagdidilim) sa halip na anino. Sa Material You (Android 12+) ang mga anino ay umaangkop sa tema: sa madilim na background, ang elevation ay pinapalitan ng color layer (surface tint).
Sa Flutter ang mga anino ay ipinapatupad sa pamamagitan ng BoxShadow sa loob ng BoxDecoration. Ang BoxShadow ay tumatanggap ng color, offset, blurRadius at spreadRadius. Sinusuportahan ng Flutter ang maramihang anino: ang pagpasa ng listahan ng BoxShadow ay nagbibigay-daan sa paglikha ng mga kumplikadong epekto — halimbawa, panlabas na anino + panloob na pag-iilaw. PhysicalModel — isang alternatibo na ginagaya ang pisikal na anino batay sa hugis (BeveledRectangleBorder, CircleBorder).
// Flutter: anino sa pamamagitan ng 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 na may anino'),
)
// PhysicalModel para sa physical na anino
PhysicalModel(
color: Colors.white,
elevation: 6.0,
shadowColor: Colors.black.withOpacity(0.2),
borderRadius: BorderRadius.circular(12.0),
child: Text('Physical model na may anino'),
)
Performance: Ang BoxShadow na may maramihang anino ay maaaring magdulot ng repaint sa bawat pagbabago. Para sa mga static na elemento, gamitin ang PhysicalModel — ito ay nagca-cache ng anino sa isang hiwalay na layer (RepaintBoundary). Sa Flutter 3.16+, idinagdag ang suporta para sa Material 3 elevation na may adaptive na anino na nagbabago ng kulay at paglabo depende sa tema (light/dark).
Mga Madalas Itanong
Elevation — ay ang numerical na taas ng elemento sa Z-coordinate, habang ang shadow (anino) — ay ang biswal na epekto na nilikha ng taas na ito. Sa Android, ang elevation — ay property ng View na awtomatikong bumubuo ng anino. Sa design, ang elevation at shadow ay madalas na ginagamit bilang mga mapagpapalit na termino, ngunit technically ang elevation ay ang dahilan at ang shadow ay ang resulta.
Suriin: (1) ang View ba ay may elevation na mas malaki sa 0, (2) nakatakda ba ang outlineProvider (kung ang View ay hindi mula sa Material library), (3) naka-enable ba ang hardware acceleration (android:hardwareAccelerated="true" sa manifest). Awtomatikong pinamamahalaan ng CardView ang outlineProvider. Para sa custom na View, tawagan ang view.outlineProvider = ViewOutlineProvider.BACKGROUND.
Ang CALayer ay hindi direktang sumusuporta sa inner shadow. Gumamit ng kombinasyon: CAGradientLayer na may itim na kulay at transparency sa loob ng mask (mask), o maglagay ng UIImageView na may raster inner shadow. Sa SwiftUI, ang inner shadow ay ipinapatupad sa pamamagitan ng overlay na may LinearGradient at blendMode(.multiply).
Sa Android, gamitin ang translationZ para sa animation: sa resting state elevation = 2 dp, kapag pinindot translationZ = 4 dp (kabuuang taas 6 dp). Sa iOS, i-animate ang shadowOffset at shadowRadius kasabay ng pag-transform ng button. Sa SwiftUI, gamitin ang withAnimation na may pagbabago ng elevation sa pamamagitan ng Modifier.shadow(). Sa Flutter — AnimatedContainer na may pagbabago ng BoxShadow.
Inirerekomenda ng Material Design na hindi hihigit sa tatlong antas ng elevation sa isang screen. Kung mayroong higit pang mga elemento na may anino — pagsamahin ang mga ito sa mga grupo na may parehong taas. Ang labis na bilang ng mga anino ay lumilikha ng visual na ingay at nagpapababa ng rendering performance sa mga device ng mid-range at budget segment.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din