In React Native, applying box shadows is not easy. Because the developers build for both the Android and iOS platforms, it will be tedious to apply consistent box shadows with the different platform-specific deployment processes.
In this tutorial, we learn the implementation of box shadows in the React Native app on the Android and iOS platforms.
To create shadow boxes on the iOS devices, we have to use four different React Native shadow props.
- The first type is shadowColor, which determines the color of the box’s shadow. Please note that it is the shadow accessory that works on Android devices.
- The second property is shadowOffset, which has accepted the objects that contain the length, width, and height of the numeric value:
- {width: number;height: number
Because it is developed by X and Y offsets relative to the element on the box-shadow where it is applied, the width property will determine the X offset at the shadow. In contrast, the height prop will determine the Y offset.
Both the width and height support accept the positive and negative values.
Let’s use the props to apply a box shadow at a card component with the below code:
- // when the return statement is
- <View style={[styles.card, styles.shadowProp]}>
- <View>
- <Text style={styles.heading}>
- React Native Box Shadow (Shadow Props)
- </Text>
- </View>
- <Text>
- Using the elevation style prop to apply box-shadow for iOS devices
- </Text>
- </View>
Now, import the StyleSheet to apply styles on the card component:
- // import StyleSheet from react-native
- const styles = StyleSheet.create({
- heading: {
- fontSize: 18,
- fontWeight: ‘600’,
- marginBottom: 13,
- },
- card: {
- backgroundColor: ‘white’,
- borderRadius: 8,
- paddingVertical: 45,
- paddingHorizontal: 25,
- width: ‘100%’,
- marginVertical: 10,
- },
- shadowProp: {
- shadowOffset: {width: -2, height: 4},
- shadowColor: ‘#171717’,
- shadowOpacity: 0.2,
- shadowRadius: 3,
- },
- });
The app reads the card by the box-shadow in the code added below.

Adding the styles.elevation prop for Android
Using Android elevation API, we have to use the elevation widget to add the box shadows to the Android.
Just apply a box shadow to the card component. Note: The styles.elevation property works with the applied <View> component:
- // wherever your return statement is
- <View style={[styles.card, styles.elevation]}>
- <View>
- <Text style={styles.heading}>
- React Native Box Shadow (Elevation)
- </Text>
- </View>
- <Text>
- By using the elevation style props to apply box-shadow for Android devices
- </Text>
- </View>
After that, we import the Style Sheet for styling the card here:
- // import StyleSheet from react-native
- const styles = StyleSheet.create({
- heading: {
- fontSize: 18,
- fontWeight: ‘600’,
- marginBottom: 13,
- },
- card: {
- backgroundColor: ‘white’,
- borderRadius: 8,
- paddingVertical: 45,
- paddingHorizontal: 25,
- width: ‘100%’,
- marginVertical: 10,
- },
- elevation: {
- shadowColor: ‘#52006A’,
- elevation: 20,
- },
- });
By setting the elevation 20 in Shadow Color, we apply the box-shadow at the Android card options.

Note: There is no control at the box’s opacity, radius, and shadow offset; we have to control the color of the shadow.
React Native Cross-Platform Box Shadow
It covers the style props of shadow props for implementing the box-shadow in iOS and Android devices in place of separate processes.
Now, let’s create the function that calls the render box-shadow for the card component based on the user’s device by React Native Platform API.
We start by configuring the cards:
- <View style={[styles.card, styles.boxShadow]}>
- <View>
- <Text style={styles.heading}>
- React Native cross-platform box shadow
- </Text>
- </View>
- <Text>Using the Platform API to conditionally render box shadow</Text>
- </View>
Let’s generate a generateBoxShadowStyle() which will apply the box shadow based on the user’s operating system in the styles object:
- const generateBoxShadowStyle = (
- xOffset,
- yOffset,
- shadowColorIos,
- shadowOpacity,
- shadowRadius,
- elevation,
- shadowColorAndroid,
- ) => {
- if (Platform.OS === ‘ios’) {
- styles.boxShadow = {
- shadowColor: shadowColorIos,
- shadowOpacity,
- shadowRadius,
- shadowOffset: {width: xOffset, height: yOffset},
- };
- } else if (Platform.OS === ‘android’) {
- styles.boxShadow = { elevation,
- shadowColor: shadowColorAndroid,
- };
- } };
With the help of code, we implemented the app checks the user’s device platform and applied the appropriate box-shadow props.
Let’s invoke the generateBoxShadowStyle() and pass the value of shadow and props as arguments:
- generateBoxShadowStyle(-2, 4, ‘#171717’, 0.2, 3, 4, ‘#171717’);
It renders the below platforms:

Cross-platform box-shadow limitations
There are many use cases when we control the box-shadow’s offset, opacity, and blur radius.
It may include:
- Adding a custom box-shadow design that is compatible with Android and iOS platforms
- Apply box-shadow to <flat list> or <squeezable> component with custom style in the block.
With the help of the current implementation, design flexibility is not possible here. However, we could overcome the limitations with the react-native-drop-shadow.
Applying the box-shadow with react-native-drop-shadow
The react-native-drop-shadow is a view component that takes the nested component and creates a bitmap representation, blurring or colorizing the style’s shadow value, like shadow props in the iOS inputting.
Install the react-native-drop-shadow package by the commands given below:
- yarn add react-native-drop-shadow
- #or
- npm i react-native-drop-shadow
Sync, the Android Gradle Toolkit, builds to restart the development server if the installation is done.
Then after, you have to import the package:
- import DropShadow from “react-native-drop-shadow”;
You can generate a custom button using the<pressable> component and wrap it to the drop shadow component where we import it.
Note the consistency in both the iOS platform and Android platforms.

The drop shadow component is the parent component of the <pressable> component, which is styled to look exact as a button. if we want to apply drop shadow to our button:
- // wherever your return statement is
- // Don’t forget to import the Pressable component
- <DropShadow style={styles.shadowProp}>
- <Pressable
- style={styles.button}
- onPress={() => console.log(‘pressed’)}>
- <Text style={(styles.text, styles.buttonText)}>See more</Text>
- </Pressable>
- </DropShadow>
Add a drop shadow to the drop shadow component to make the <pressable> component look exactly like a button key from the style sheet which is given below:
- const styles =StyleSheet.create({
- shadowProp:{
- shadowOffset:{width:0, height:3},
- shadowColor:’#171717′,
- shadowOpacity:0.4,
- shadowRadius:2,
- },
- button:{
- backgroundColor:’#4830D3′,
- justifyContent:’center’,
- alignItems:’center’,
- height:42,
- borderRadius:4,
- marginTop:30,
- },
- buttonText:{
- color:’#fff’,
- },
- text:{
- fontSize:16,
- fontWeight:’bold’,
- lineHeight:21,
- letterSpacing:0.25,
- },
- });
Using React-Native-shadow-2
The react-native-shadow-2 package is an updated version of the react-native-shadow, which declare the functionality, typing, and support and is written from scratch to minimize the performance-impacting dependencies.
Unlike the drop shadow implementation with react-native-drop-shadow, it creates a bitmap representation of the child components; react-native-shadow-2 is used for persistent implementation on Android and with the plugin react-Native-SVG shadow of the iOS platform.
Install both the packages at the root of the project directory to get the installation done:
- npm i react-native-SVG react-native-shadow-2
- or
- yarn add react-native-SVG react-native-shadow-2
To ensure runs on iOS, CD ios directory and run pod install to sync the packages that we installed:
- // import the package right at the top
- import {Shadow} from ‘react-native-shadow-2’;
- // wherever your return statement is
- <Shadow
- distance={5}
- startColor={‘#00000010’}
- containerViewStyle={{marginVertical: 20}}
- radius={8}>
- <View style={[styles.card, {marginVertical: 0}]}>
- <View>
- <Text style={styles.heading}>
- React Native cross-platform box shadow
- </Text>
- </View>
- <Text style={styles.boxShadow}>
- Using the Platform API to conditionally render box shadow
- </Text>
- <DropShadow style={styles.shadowProp}>
- <Pressable
- style={styles.button}
- onPress={() => console.log(‘pressed’)}>
- <Text style={(styles.text, styles.buttonText)}>See more</Text>
- </Pressable>
- </DropShadow>
- </View>
- </Shadow>
The code generates the below given output:

Shadow props
By using the shadow props recommended in the react-native doc.
- shadowColor: It sets drop shadow color.
- shadowOffset: It sets drop shadow offset.
- shadowOpacity: It sets the drop shadow opacity (that is multiplied by the color alpha component).
- Shadow Radius: It sets the drop shadow in a blur radius.

There is a problem with using React Native’s shadow props if we use styled-components: The shadow is a set on top of the element, and there is no way to move it.
It is a problem that has not any solution, so you have to use the below code:
Box shadow
By using the CSS box-shadow property:
- Insert: If not specified (default), the shadow is mentioned as a drop shadow (such as hovering over the box contents).
- Offset-x, offset-y: It specifies the vertical and horizontal distances.
- Blur Radius – How larger the value, the blur is more significant and makes the shadow lighter and a proficient radius.
- Diffusion Radius: Positive values expand and enlarge the shadow, and negative values shrink the shadow.
- Color: The color box used is browser dependent if it is not specified.
How to apply shadows on the Android platform
On Android, we can use the height style prop from react-native to add the shadow.
Upgrade: It sets up the upgrade of the scene by using Android’s built-in upgrade API. It adds a drop shadow to affect the z-order of the overlapping scenes.

There are no other properties to customize the look of the shadow.
Android’s shadow on the circle button is very soft, but it’s hard to appreciate, but if we turn the button so vast, then the exact value of height property looks excellent.

Other multi-platform alternatives
The react-native-shadow enables the management of Android shadow like iOS, but its performance is terrible because of some user opinion. Shadow does not work with React Native in Android. The view takes the children, creates a bitmap representation, blurs it, and colors it like shadow values in iOS.
Installation
- yarn add react-native-drop-shadow
Limitations
Android’s bitmap limit is 2048×2048, but it depends on the API version.
If shadows and animations are rendered continue, it uses bitmap rendering to simulate heavy shadows in performance.
Usage
- import DropShadow from “react-native-drop-shadow”;
- export default function usage() {
- return (
- <DropShadow
- style={{
- shadowColor: “#000”,
- shadowOffset: {
- width: 0,
- height: 0,
- },
- shadowOpacity: 1,
- shadowRadius: 5,
- }}
- >
- …
- </DropShadow>
- );
- }
Usage with FlatList
- export default function withFlatList() {
- return (
- <FlatList
- data={[“”]}
- keyExtractor={(item, index) => “List-” + index}
- CellRendererComponent={DropShadow} // <==== add line
- renderItem={({ item, index }) => (
- <DropShadow
- style={{
- shadowColor: “#000”,
- shadowOffset: {
- width: 0,
- height: 0,
- },
- shadowOpacity: 1,
- shadowRadius: 5,
- }}
- >
- …
- </DropShadow>
- )}
- />
- );
- }
Usage with Animated Views
We use animated.createAnimatedComponent to create any animatable version of the drop shadow to make the work instead of animated view.
For example:
- const AnimatedDropShadow = Animated.createAnimatedComponent(DropShadow);
- export default function withAnimatedViews() {
- return (
- <AnimatedDropShadow
- style={{
- shadowColor: “#000”,
- shadowOffset: {
- width: 0,
- height: 0,
- },
- shadowOpacity: 1,
- shadowRadius: 5,
- }}
- >
- …
- </AnimatedDropShadow>
- );
- }
We use AnimatedDropShadow despite the Animated view.
Conclusion
It will not be used in Android apps. It’s the big problem with shadow props in React Native.
We implement persistent box shadows in React Native apps for Android or iOS platforms by using the react-native-drop-shadow and the react-native-shadow-2.
Leave a Reply