Styling react-native apps in browser
Intro
Styling your app cross-environment, and supporting different environments may seem hard. Behind the scene this could instead be easy, and the code-base could actually be the same.
The browser CSS rule-set is too large and it's hard to replicate on react-native due to the complex box model that CSS has. Replicating the react-native rule-set instead is pretty easy and will not blow up your minds while developing your app, since it's smaller to remember and understand, and it's also web-inspired to flexbox.
React Native for Web is a library that contains a subset of react-native components ported to the browser, along with a system that allows you to reuse your existing react-native style codebase in the browser with no style code changes.
So no style code changes?
Yep. That's true. You can write your web app using the react-native style definitions, and they will translate into CSS.
React-native style definitions like these are supported.
var {StyleSheet} = require('react-native');
<View style={{height: 100, width: 20}} />
// you can define your own style object
let styles = {
main: {
width: 10
},
large: {
width: 100
}
};
// or define a StyleSheet
let sheetStyles = StyleSheet.create({
main: {
width: 10
},
large: {
width: 100
}
});
// nullish definitions will be ignored by the style
// you can merge also objects and stylesheets
<View style={[styles.main, sheetStyle.large, null, undefined]} />
Double-direction style props
React-native provides style shorthand like paddingVertical
or marginHorizontal
. You can use them and don't mind about them since they are automatically converted into a couple of their meaning. marginVertical
will be decoupled into two style props marginTop
and marginBottom
.
Colliding style props
Like react-native behaves, styles are merged left-to-right. If you do this directly using radium this will bring you to warning about array of colliding props like margin
and marginBottom
. React-native-for-web avoids this problems by decoupling four-direction style props into their meanings, like it does with the double-direction ones.
Vendor prefixes
Old browsers may support flexbox and other properties via vendor-prefixes. React-native-for-web leaverege the power of the Radium package, using it to append vendor prefixes to your inline styles. Default styles provided via LESS are already prefixed using the autoprefixer-core package.
So you don't have to think about the vendor prefixes, they are internally supported.
Default styles and inline ones
React-native-for-web comes together with a pre-compiled LESS stylesheet. This sheet contains all the default styles to make a browser environment suitable for react-native-like style definitions.
These styles are precompiled intentionally; we don't want to inline them in order to keep the developer console DOM tree human-readable. If they were converted to inline styles and mixed together with the developer provided style, it would be difficult to understand which ones are provided by the library, and which by the user.