Transparent React Native iFrames/WebViews

When creating an iFrame in React Native, it’ll be transparent by default if you compile for the web, but it might not be for iOS or Android. For these platforms, you need to add extra styling properties.

The setup

In the below sample code, I’ve created an example React function component that accepts a uri as a prop and then creates a WebView. The WebView will become an iFrame during build, and the View will become the relevant container type for the platform you’re building for (e.g. A div on Web).

When compiled for Web, since we haven’t applied any styling to say otherwise, both the container view (div) and the iFrame will have transparent backgrounds and will therefore show whatever is behind them.

export default function MyComponent(props: {uri: string}) {
    // ...

    return (
        <View>
            <WebView
                source = {{ uri: uri }}
            />
        </View>
    )
}

Note
If transparency doesn’t even work when building for the web, be sure to check two things:

  • The styles loading within the iFrame… make sure the background isn’t being set there.
  • The styles in any Views or containers that this component sits within.

The problem

The problem, however, is that even though this code will produce transparency in a browser, it won’t produce transparency on iOS or Android when built directly for them.

Note
When I build my React Native apps, I often deploy them to Vercel as PWAs while I’m working. However, it’s easy to forget that PWAs you’ve saved on your phone’s home screen aren’t natively compiled apps. They’re browser-rendered, so you won’t notice the issue in these.

The solution

If you’ve noticed this issue, the answer is to add some extra styling to your WebView component like below.

Any parent Views will be transparent by default, but if you still encounter issues, check it’s not coming from them. Check for any places where you may have accidentally set a background colour (Either in this component or wherever it’s used).

export default function MyComponent(props: {uri: string}) {
    // ...

    return (
        <View>
            <WebView
                source = {{ uri: uri }}
                javaScriptEnabled = {true}
                style = {styles.webView}
            />
        </View>
    )
}

const styles = StyleSheet.create({
    webView: {
        backgroundColor: 'transparent',
    },
});

That’s it!

Thanks…

I also dissect and speculate on design and development.
Digging into subtle details and implications, and exploring broad perspectives and potential paradigm shifts.
Check out my conceptual articles on Substack or find my latest below.


You can also find me on Threads, Bluesky, Mastodon, or X for more diverse posts about ongoing projects.

My latest articles

Designing immersive experiences

In traditional cinema, TV, or even the more modern phone screen, there’s limited screen real-estate. But removing that limitation creates a design problem…

The future is not prompt engineered

Let’s not pretend the importance of prompt engineering is ubiquitous. The most prevalent power of generative AI is in the way it adapts to us, not the other way around…

The typography of dates, times, & filenames

A deep dive into carefully considered date formatting, line length and general typography attributes of filenames…

Author:

Date:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.