Dark Mode
Image

Box shadow in React Native

n 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 theimplementationof box shadows in the React Native app on the Android and iOS platforms.

To create shadow boxes onthe 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.
  • he second property is shadowOffset, which has accepted the objects that contain thelength,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 readsthe card bythe box-shadow in the code added below.

Box shadow in React Native

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 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, weimport 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 applythe box-shadow at the Android card options.

Box shadow in React Native

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

Itcovers the style props ofshadow props for implementingthe box-shadowiniOS and Android devices in place of separate processes.

Now, let's create thefunction that callsthe 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:

Box shadow in React Native

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 or component with custom style in the block.

With the help of the current implementation, design flexibility is not possible here. However, wecould 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 componentthat 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 commandsgiven below:

yarn add react-native-drop-shadow  
#or  
npm i react-native-drop-shadow  

Sync, the Android Gradle Toolkit, buildsto restart the development serverif 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 component and wrap it to the drop shadow component where we import it.

Note: the consistency in both the iOS platform and Android platforms.

Box shadow in React Native

The drop shadow component is the parent component of the 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 dropshadow component to make the 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 anupdated version of the react-native-shadow, whichdeclarethe functionality, typing, and support and is written from scratch to minimizethe performance-impactingdependencies.

Unlike the drop shadow implementation with react-native-drop-shadow, it creates a bitmap representation of the child components; react-native-shadow-2 is usedfor 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:

Box shadow in React Native

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 ismultiplied by the color alpha component).
  • Shadow Radius: It sets the drop shadow in a blur radius.

Box shadow in React Native

There is a problem with using React Native's shadow props if weuse styled-components: The shadow is a set on top of the element, and there isnoway 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 ofthe overlapping scenes.

Box shadow in React Native

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 looksexcellent.

Box shadow in React Native

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 2048x2048, 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>  
  );  
}  

Weuse AnimatedDropShadow despite the Animated. view.

Conclusion

It will notbe 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.

Comment / Reply From