React Native for Web relies on JavaScript to define styles for your application. This allows you to avoid issues arising from the 7 deadly sins of CSS:
- Global namespace
- Dependency hell
- No dead code elimination
- No code minification
- No sharing of constants
- Non-deterministic resolution
- Lack of isolation
Styles should be defined outside of the component:
class Example extends React.Component {}
const styles = StyleSheet.create({
heading: {
color: 'gray',
fontSize: '2rem'
},
text: {
color: 'gray',
fontSize: '1.25rem'
}
})
Using StyleSheet.create
is optional but provides the best performance
(style
is resolved to CSS stylesheets). Avoid creating unregistered style
objects.
The attribute names and values are a subset of CSS. See the style
documentation of individual components.
All the React Native components accept a style
attribute.
<Text style={styles.text} />
<View style={styles.view} />
A common pattern is to conditionally add style based on a condition:
// either
<View style={[
styles.base,
this.state.active && styles.active
]} />
In order to let a call site customize the style of your component children, you
can pass styles around. Use View.propTypes.style
and Text.propTypes.style
in
order to make sure only valid styles are being passed.
class List extends React.Component {
static propTypes = {
style: View.propTypes.style,
elementStyle: View.propTypes.style,
}
render() {
return (
<View style={this.props.style}>
{elements.map((element) =>
<View style={[ styles.element, this.props.elementStyle ]} />
)}
</View>
);
}
}
In another file:
<List style={styles.list} elementStyle={styles.listElement} />
You also have much greater control over how styles are composed when compared to using class names. For example, you may choose to accept a limited subset of style props in the component's API, and control when they are applied:
class List extends React.Component {
static propTypes = {
children: React.PropTypes.any,
// limit which styles are accepted
style: React.PropTypes.shape({
borderColor: View.propTypes.borderColor,
borderWidth: View.propTypes.borderWidth
})
}
render() {
return (
<View
children={children}
style={[
this.props.style,
// override border-color when scrolling
isScrolling && { borderColor: 'transparent' }
]}
/>
)
}
}
StyleSheet.create
is a way of defining the styles your application requires;
it does not concern itself with where or when those styles are applied to
elements.
There are various React libraries wrapping JavaScript Media Query API's, e.g., react-media-queries, media-query-fascade, or react-responsive. This has the benefit of co-locating breakpoint-specific DOM and style changes.
Pseudo-classes like :hover
and :focus
can be implemented with events (e.g.
onFocus
). Pseudo-elements are not supported; elements should be used instead.
You do not need to include a CSS reset or normalize.css.
React Native for Web includes a very small CSS reset taken from normalize.css.
It removes unwanted User Agent styles from (pseudo-)elements beyond the reach
of React (e.g., html
, body
) or inline styles (e.g., ::-moz-focus-inner
).