import { View } from 'react-native';
const App = () => (
<View style={{ flex: 1 }}>
style={{
position: 'absolute',
zIndex: 1,
top: 0,
left: 0,
right: 0,
height: 60,
backgroundColor: 'blue',
style={{
backgroundColor: 'red',
flex: 1,
</View>
export default App;
Assuming zIndex
works fine for both IOS and Android, the Blue box should display on top of the Red one. However, on Android the Blue box actually displays behind the Red one (see below).
Android
Interestingly, if I add some random styles to the container <View>
, like backgroundColor: '#fff'
, then the Blue box actually starts showing on Android somehow.
const App = () => (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
</View>
So after noticing all of these inconsistent behaviours above, I just want to confirm if zIndex
actually works for React Native Android. And if zIndex
are NOT expected to work for Android all the time, should it be mentioned is the React Native docs?
There are some workarounds for this issue, like using elevation
or just re-order the code to make sure Blue box is after the Red box in the document tree. But I think it would still be good to know if zIndex
on Android is actually an issue.
Version
0.70.6
Output of npx react-native info
System:
OS: macOS 12.6
CPU: (10) arm64 Apple M1 Pro
Memory: 356.00 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
Yarn: 1.22.17 - ~/.nvm/versions/node/v16.14.0/bin/yarn
npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
Watchman: 2022.03.07.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.2 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
Android SDK:
API Levels: 30, 31, 32
Build Tools: 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0
System Images: android-30 | Intel x86 Atom_64, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play ARM 64 v8a, android-32 | Google APIs ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2021.1 AI-211.7628.21.2111.8193401
Xcode: 14.1/14B47b - /usr/bin/xcodebuild
Languages:
Java: 11.0.15 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.6 => 0.70.6
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Steps to reproduce
See above in Description
Snack, code example, screenshot, or link to a repository
React Native CLI
https://github.com/mk-nickyang/react-native-android-zindex-issue
Expo Snack
https://snack.expo.dev/@lucissa/android-zindex-playground?platform=android
@pierroo Haven't got an answer from React Native officially. But I just kinda accept this is an issue and will always put the element with higher stack level after the one with lower stack level in the document tree. Like
const App = () => (
<View style={{ flex: 1 }}>
// View A
<View style={{ backgroundColor: 'red', flex: 1 }} />
// View B
// Make sure View B is placed after View A
<View style={{ position: 'absolute', zIndex: 1 }} />
</View>
In my case placing the component higher or lower in a component tree, adjusting zIndex or elevation doesn't help with the issue. The component is still rendered in the background.
And the problem only occurs when there's a conditionally rendered loader present in a component hierarchy. If it has been rendered at least once, zIndex issue will occur (happens randomly).
Loader itself is an Animated.View with LottieView as its single child.
@Orange9000 Do you happen to use LayoutAnimation from react-native-reanimated
? If so, it might also be because react-native-reanimated
v2 LayoutAnimation doesn't work very well, they did fix it in v3 tho.
I do, but not in the component which has zIndex issues.
I solved my problem above by setting opacity of a loader to 0 when there's no fetching, instead of conditionally rendering it. Dirty solution, but does the job.
Yeah, that's how I found this zIndex issue too in the first place. After triggering reanimated LayoutAnimation, some conditional render component zIndex just goes wrong (similar to software-mansion/react-native-reanimated#3368) and I had to remove the reanimated v2 LayoutAnimation usage to fix it.
I'm still not sure what's causing the issue, looks like it's from reanimated, but RN Android zIndex is also sus, that's why I posted this issue.
Btw, the reanimated team did rewrite the entire LayoutAnimation in v3 recently and looks like the reanimated side issue did get fixed.
@pierroo Haven't got an answer from React Native officially. But I just kinda accept this is an issue and will always put the element with higher stack level after the one with lower stack level in the document tree. Like
const App = () => (
<View style={{ flex: 1 }}>
// View A
<View style={{ backgroundColor: 'red', flex: 1 }} />
// View B
// Make sure View B is placed after View A
<View style={{ position: 'absolute', zIndex: 1 }} />
</View>
You saved my day! Thank you! <3
I'm having the same problem in a conditional render component, with react native 0.72.7, it seems to be an old issue in react native. The only way to get around it was to follow @sergioisidoro tip and sett the elevation to a negative number (-2) in the parent view of my conditional render view.
I can't post the component here, but I did something like this:
const App = () => (
<View style={{ flex: 1 }}>
<View style={{ backgroundColor: 'red', flex: 1 , zindex:1, elevation:-2}} />
{conditionalRendering &&
<View style={{ position: 'absolute', zIndex: 3 }} />
</View>