How to Create a UI with Box Shadow in React Native: iOS and Android Implementation
React Native implements box shadow through platform-specific style props—shadowColor, shadowOffset, shadowOpacity, and shadowRadius for iOS, and elevation for Android—mapped to native view attributes via the renderer's attribute payload system.
Creating visual depth with box shadow in React Native requires understanding how the framework translates JavaScript style objects into native platform shadows. Unlike web CSS, the facebook/react repository implements separate shadow APIs for iOS and Android, processed through the renderer's attribute flattening pipeline in packages/react-native-renderer/src/ReactNativeAttributePayload.js.
Platform-Specific Shadow APIs
React Native does not support the standard CSS box-shadow property. Instead, the framework exposes distinct shadow interfaces for each mobile platform, handled internally by the ReactNativeAttributePayload module.
iOS Shadow Properties
On iOS, React Native maps JavaScript style props to Core Animation shadow parameters:
shadowColor: The color of the shadow (defaults to#000)shadowOffset: Object withwidthandheightvalues in pointsshadowOpacity: Alpha value between 0 and 1 controlling transparencyshadowRadius: Blur radius measured in points
These properties are defined in the Flow type declarations at flow-typed/environments/html.js (lines 562-565), which specify the expected JavaScript shape for shadow styling according to the facebook/react source.
Android Elevation
Android utilizes a single elevation numeric value that determines Z-order and automatically generates soft-edge shadows through the Material Design elevation system. This property appears in the standard style names list at packages/react-dom-bindings/src/shared/possibleStandardNames.js (line 228). Unlike iOS, Android's shadow color and offset derive automatically from the elevation value and cannot be customized through React Native style props.
Implementation Architecture
The shadow styling pipeline flows through three stages in the facebook/react codebase:
- Style Declaration: Developers define shadow properties in component stylesheets
- Attribute Flattening: The renderer processes styles through
ReactNativeAttributePayload, converting JavaScript objects into native view attributes (setShadowColor,setShadowOffset, etc. on iOS;setElevationon Android) - Native Rendering: Platform-specific APIs draw shadows using Core Animation (iOS) or Material Design elevation (Android)
The entry point ReactNativeRenderer.js in packages/react-native-renderer/src/ creates native views using this attribute payload system.
Code Examples
iOS Shadow Implementation
The following implementation targets iOS specifically using the four shadow properties defined in the Flow types:
import {View, Text, StyleSheet} from 'react-native';
export default function Card() {
return (
<View style={styles.container}>
<Text style={styles.title}>React Native Card</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#fff',
padding: 20,
borderRadius: 8,
// iOS shadow properties
shadowColor: '#000',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 4,
// Android fallback
elevation: 5,
},
title: {
fontSize: 18,
fontWeight: '600',
},
});
Android-Only Elevation
For Material Design elevation without iOS shadows:
import {View, StyleSheet} from 'react-native';
export default function ElevatedBox() {
return <View style={styles.box} />;
}
const styles = StyleSheet.create({
box: {
width: 120,
height: 120,
backgroundColor: '#4caf50',
elevation: 10,
},
});
Cross-Platform Shadow Solution
Combine both approaches for consistent appearance across platforms:
import {View, Text, StyleSheet} from 'react-native';
export default function CrossPlatformCard() {
return (
<View style={styles.card}>
<Text style={styles.text}>Cross-platform Shadow</Text>
</View>
);
}
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
margin: 16,
padding: 16,
borderRadius: 12,
// iOS shadow
shadowColor: '#000',
shadowOffset: {width: 0, height: 3},
shadowOpacity: 0.3,
shadowRadius: 6,
// Android elevation
elevation: 8,
},
text: {
fontSize: 16,
},
});
Summary
- React Native uses
shadowColor,shadowOffset,shadowOpacity, andshadowRadiusfor iOS shadows, defined inflow-typed/environments/html.js - Android requires only the
elevationproperty, recognized inpackages/react-dom-bindings/src/shared/possibleStandardNames.js - The
ReactNativeAttributePayload.jsmodule inpackages/react-native-renderer/src/processes these styles into native view attributes - iOS shadows provide granular control while Android elevation uses automatic Material Design shadows
- Define both iOS shadow props and Android elevation in the same style object for cross-platform compatibility
Frequently Asked Questions
Why doesn't React Native support CSS box-shadow?
React Native compiles JavaScript styles into native platform views rather than browser DOM elements. According to the facebook/react source code, iOS uses Core Animation shadow parameters and Android uses Material Design elevation, neither of which map directly to CSS box-shadow syntax. The renderer's ReactNativeAttributePayload module specifically handles platform-specific attribute mapping instead of CSS polyfills.
How do I make shadows look identical on both iOS and Android?
You cannot achieve identical shadows because Android's elevation property generates shadows automatically based on Material Design guidelines without customizable color or blur radius. For visual consistency, use both iOS shadow properties and Android elevation in your style sheet, adjusting values until they appear visually similar, or use third-party libraries that draw shadows using SVG or Canvas APIs.
Where are shadow properties defined in the React source code?
The Flow type definitions for iOS shadow properties appear in flow-typed/environments/html.js at lines 562-565, specifying the expected JavaScript object shapes. The elevation property for Android is listed among standard style names in packages/react-dom-bindings/src/shared/possibleStandardNames.js at line 228. The runtime implementation resides in packages/react-native-renderer/src/ReactNativeAttributePayload.js.
Does Android support shadowOpacity and shadowColor?
No, Android does not support shadowOpacity, shadowColor, shadowOffset, or shadowRadius in React Native. The platform exclusively uses the elevation numeric value, which triggers automatic shadow rendering based on the view's Z-order and the device's Material Design theme. To customize Android shadows beyond elevation, you must use native module bridges or third-party components.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s https://instagit.com/install.md