React Native Shadow Generator: iOS + Android [2026]

React Native Shadow Generator featured graphic showing iOS shadow props (color, offset, opacity, radius) next to Android elevation value
TL;DR: React Native handles shadows with two completely different APIs depending on platform. iOS uses four properties: shadowColor, shadowOffset, shadowOpacity, shadowRadius. Android uses one — elevation — which renders a Material-Design-style shadow whose appearance you can’t fully control. Our free React Native shadow generator shows both side by side, lets you tune iOS to match an Android elevation visually, and outputs a copy-paste StyleSheet block including the cross-platform Platform.OS guard.

Shadows on a React Native card sound like one feature; they’re actually two implementations with no overlap. iOS reads the four shadow* props that map closely to Apple’s CALayer shadow API. Android ignores all four and reads elevation only — a 0–24 numeric value that the Material framework converts into a system-rendered shadow. Set both: iOS uses its props, Android uses elevation. Set only iOS-style props: Android is shadowless. Set only elevation: iOS is shadowless. Pretty much every “why does my shadow not show up?” Stack Overflow question is one of these three.

Our React Native shadow generator renders both platforms side-by-side with a live preview that approximates each platform’s rendering. You set the iOS values, see the Android equivalent under our preset mapping, and copy a single StyleSheet block that works on both. This guide covers the prop semantics, the iOS-vs-Android visual mismatches, and the gotchas with backgroundColor, borderRadius, and overflow.

iOS shadow props vs Android elevation

Property Platform Type Default
shadowColor iOS only colour 'black'
shadowOffset iOS only { width, height } { width: 0, height: 0 }
shadowOpacity iOS only number 0–1 0 (invisible)
shadowRadius iOS only number (px) 3
elevation Android only number (0–24) 0

Mapping iOS values to Android elevation

Material Design’s elevation system is a fixed scale: 1 = subtle, 2 = card, 4 = button, 6 = dropdown, 8 = floating action button, 16 = navigation drawer, 24 = highest layer. There’s no Android API to fully customise the shadow — you pick a number and Android renders the matching Material shadow. Approximate iOS-to-Android mapping:

  • iOS subtle (offset 0/2, opacity 0.1, radius 3) ≈ elevation: 2
  • iOS soft card (offset 0/4, opacity 0.15, radius 6) ≈ elevation: 4
  • iOS prominent (offset 0/6, opacity 0.2, radius 10) ≈ elevation: 8
  • iOS dramatic (offset 0/12, opacity 0.3, radius 16) ≈ elevation: 16

Pixel-perfect parity isn’t possible — the platforms render shadows with different algorithms. Aim for visual equivalence at the design-system level: a “card” looks like a card on both platforms.

How to generate a React Native shadow

  1. Open the React Native shadow generator
  2. Adjust the four iOS sliders: shadowColor, shadowOffset, shadowOpacity, shadowRadius
  3. The Android elevation slider tracks automatically (or override manually)
  4. Watch the side-by-side preview — iOS on the left, Android approximation on the right
  5. Click Copy StyleSheet for a complete cross-platform block

Cross-platform StyleSheet pattern

The standard React Native shadow shim looks like this:

import { StyleSheet, Platform } from "react-native";

const styles = StyleSheet.create({
  card: {
    backgroundColor: "white",
    borderRadius: 12,
    padding: 16,
    ...Platform.select({
      ios: {
        shadowColor: "#000",
        shadowOffset: { width: 0, height: 4 },
        shadowOpacity: 0.15,
        shadowRadius: 8,
      },
      android: {
        elevation: 4,
      },
    }),
  },
});

Note backgroundColor is required on Android for elevation to render — without it, Android won’t draw the shadow even though the prop is set. iOS doesn’t have this requirement.

Common gotchas

  • Android elevation requires backgroundColor. A transparent or undefined background makes Android skip the shadow entirely. Always set a background colour for elevation to render.
  • iOS shadow doesn’t follow rounded corners by default. Set shadowPath via the older shadowOffset shape, or use the react-native-svg-shadow library if you need precision. Most cases are fine without.
  • Don’t use both elevation and iOS props on Android. elevation alone produces the Material shadow; adding iOS props doesn’t help and may break expected layouts in some RN versions.
  • shadowOpacity defaults to 0. If you set everything else but skip shadowOpacity, your iOS card has no shadow. The most common “shadow doesn’t show” cause on iOS.
  • overflow: hidden clips shadows on iOS. A card with overflow: 'hidden' (e.g., to clip an image to rounded corners) hides its own shadow. Wrap the clipped element in a parent that has the shadow, then put the clipped child inside.
  • Color names differ. iOS accepts CSS colour names; Android accepts standard names too but some hex strings render differently. Stick to hex ('#000') for cross-platform consistency.
  • RN 0.71+ supports new architecture. The new (Fabric/TurboModules) renderer respects shadow props more consistently across both platforms. Older versions (RN <0.65) may need third-party libraries like react-native-shadow-2 for visual parity.

When NOT to use this tool

For complex shadows (multiple stacked shadows, inner shadows, coloured shadows beyond simple offsets), use a third-party library: react-native-shadow-2 renders SVG-based shadows that look identical on both platforms. For text shadows, use the dedicated textShadowColor, textShadowOffset, textShadowRadius props (different from view shadows). For Web React Native (RN Web), neither shadow API works — use CSS box-shadow via style.shadowOffset = ... with platform check or a CSS-in-JS library.

Frequently asked questions

Why doesn’t my shadow show on Android?

Three usual causes: (1) you set iOS props but no elevation — Android ignores iOS props; (2) you set elevation but the parent has no backgroundColor — Android needs an opaque background to render the shadow; (3) overflow: 'hidden' on the parent clips the shadow. Add elevation, set backgroundColor, remove overflow: hidden.

Why doesn’t my shadow show on iOS?

Almost always shadowOpacity is 0 (the default). Set it to 0.1–0.3. Other causes: shadowColor is transparent, parent has overflow: 'hidden', or the view has no backgroundColor (transparent views can’t cast shadows on iOS either, though it’s less strict than Android).

Can I have a coloured shadow?

iOS yes — set shadowColor: '#FF0000'. Android no — elevation always renders the system Material shadow which is roughly black with system-controlled opacity. For coloured shadows on Android, use react-native-shadow-2 or render a manual SVG shadow.

Does this work on Expo and bare React Native?

Yes. Both shadow APIs are part of core React Native; they work identically in Expo and bare projects. No native modules required.

What’s the difference between elevation and zIndex?

elevation controls visual shadow depth on Android. zIndex controls render order (which view appears in front). They’re independent — a high-elevation card with low zIndex still appears behind other views. Set both together when you want an elevated card to also be on top.

Is my data uploaded?

No. The generator runs in your browser. The shadow values, preview, and exported StyleSheet stay on your device.

Related tools and guides