Updated May 11, 2016
Intro to Styling in React Native
Originally publish on medium.com.
React does styling a bit different than you may be used to on the web. It’s CSS in JS which is a controversial topic. If you’re interested in the why I’d suggest reading through this deck. Let’s put opinions aside and just focus on how to use it.
The StyleSheet API
The StyleSheet API is pretty straight forward. It’s got two properties (that you’ll actually use) on it, create and hairlineWidth.
You use create to put together an object that you can use to apply styling to your components. If you’re familiar with CSS then the syntax is a bit different. For example: border-radius on the web is borderRadius in this api. I’ve found that basically anything that uses a “-” in it becomes camel cased.
const styles = StyleSheet.create({
listItem: {
flex: 1,
fontSize: 16,
color: 'white',
},
selectedListItem: {
color: 'green',
},
});
There is also a useful property that allows you make a thin line that’s specific to that device. It’s good for borders.
const styles = StyleSheet.create({
divider: {
flex: 1,
height: StyleSheet.hairlineWidth,
},
});
Using Flexbox
Flexbox brings some confusion and it’s definitely got a learning curve. If you want to get familiar with Flexbox itself I would suggest reading through (and bookmarking) this great reference. It will help you better understand the different properties you have available. React Native sticks to this convention very well (other than some naming differences as I said before). I like to learn by doing so let’s start building stuff.
How to Build a Navigation Bar
A navigation bar is a great example of using “flex container” properties. Most of the styling we’re going to be doing applies to our container component. Here’s what our finished product will be.
Let’s get a little boilerplate out of the way and add our various UI elements with some basic styling. This should be pretty straightforward
Navbar.js
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
navbar: {
paddingTop: 20,
height: 64,
backgroundColor: '#F4F4F4',
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#DDDDDD',
paddingHorizontal: 12,
},
leftText: {
color: '#089de3',
},
titleText: {
fontWeight: '600',
},
rightText: {
color: '#089de3',
},
});
class Navbar extends React.Component {
render() {
return (
<View style={styles.navbar}>
<Text style={styles.leftText}>Back</Text>
<Text style={styles.titleText}>Title</Text>
<Text style={styles.rightText}>Forward</Text>
</View>
);
}
}
export default Navbar;
Okay, now how do we get our elements to sit inline? That’s where flexDirection comes into play. By default it is set to column and to make things sit inline we’ll set it to row.
Progress! That’s not really what we though… how do we get the elements to spread out? That’s where we’ll use justifyContent. There are a variety of options you can use here and they’re all pretty straightforward. In this instance we want space between our elements, so we’ll use the value space-between - convenient isn’t it?
Just about there! Now we want our text to sit in the center of our navbar. The alignItems property is what we’ll use. Again, the terminology is pretty straightforward. We want our text to sit in the center… which is also the value we want to use.
Boom! There’s an example of how to build a navbar-esq layout. Flexbox makes it very easy to equally space out text, vertically center it, and display our text in a row. Obviously this isn’t going to cover all the edge cases (as you can see “Title” isn’t centered but it demonstrates my point).
I had to set four properties in order to layout our elements above. Here’s the final navbar properties.
Navbar.js
const styles = StyleSheet.create({
navbar: {
paddingTop: 20,
height: 64,
backgroundColor: '#F4F4F4',
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#DDDDDD',
paddingHorizontal: 12,
flexDirection: 'row', // step 1
justifyContent: 'space-between', // step 2
alignItems: 'center', // step 3
},
});
How to Build a News Feed
Let’s put together a seemingly more complex layout. In reality we’re tapping into less Flexbox than we were in the previous example but it’s still a good example. We’ll be building this basic news feed.
You can get the starting code in this gist. That’ll leave you with this
Yikes
First thing we’ll do is add a bit of visual difference between our text.
Feed.js
const styles = StyleSheet.create({
headerText: {
color: '#FFF',
fontWeight: '800',
fontSize: 23,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
padding: 10,
},
bodyText: {
padding: 10,
fontSize: 15,
color: '#5D5D5D',
},
});
That all looks very CSS like (with the difference of camelCasing any properties that normally use a “-”). That’ll leave us here.
Better…
What about that image background? Do you need to know some fancy trick to do it with Flexbox? Nope. Just going to using absolute positioning.
Feed.js
const styles = StyleSheet.create({
image: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute',
},
header: {
width: window.width,
height: window.width,
padding: 10,
},
});
Cool! We’ve got our UI just about there.
But I want that header text to sit at the bottom. This is where we’ll finally tap into Flexbox and we’ll use a property we’re already familiar with, justifyContent. Since we want to the sit at the end of our Flexbox we just need to add justifyContent: ‘flex-end’ to our “header” property and we’ve got what we wanted at the start!
Styling with Flexbox in React Native isn’t as intimidating or difficult as I thought it was when I first started. Find an interface you want to recreate and try to build it. Learning from experience is where it’s at!
Hope you found this helpful! At the very end of this article are a few references I highly suggest you checkout. Do you have a property you’d like to see used? Tweet me.
References
- Flexbox Docs
- Styling Guide
- Stylesheet Docs
- Intro to Flexbox — there will be syntax differences but the ideas are the same