How to Design Bottom Tab Bar Layout in React Native
I'm back and I am filming in my normal studio so that's why you see me now.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Now with our tab bar our bottom tab bar ready and showing up in our container layout, now it's time for us to implement this. So it actually is starting to look more like an actual tab bar. So let's get started with that.

I'm gonna open up the bottomTabStyles here and we're gonna make a few changes. I'm actually gonna get rid of everything here just so it's a little bit easier for you to see and we're gonna build this from scratch. So whenever you're building a component and you're adding styles and that component needs to stay on the screen at all times, you can't treat it like a normal component. You have to add something which is called position: absolute.

That is going to allow us to make sure that this bottom tab bar does not move when say the user is scrolling up and down on the screen and it's not hidden behind something else. So we're gonna start by doing that. So we're gonna add in a position and whenever you're writing this type of CSS, you may have already noticed this a little bit but whenever you're writing this, and you have to use any words.

So words like absolute, this has to be wrapped up in a string. This is once again, different than writing regular CSS or Sass and the reason is because this technically isn't CSS or Sass or any library like that. This is JavaScript code, this is a JavaScript function and a JavaScript object.

What React Native is doing behind the scenes is it's taking this object, it's taking this StyleSheet and saying okay, we have a new StyleSheet function called here and it has an object inside and it has all these key-value pairs and then it does the job of turning that into a set of styles that the application itself can use, it's really neat how it happens behind the scenes. If you're wondering on why we can't just write normal CSS, that's the reason why.

Now that we have position: absolute, let's add a comma at the end and let's say that we want this to be at the bottom so I'm gonna say this is gonna be bottom: zero and that gets written as an integer. And I'm gonna be hitting save as we're doing this and you'll see, right up here, you're starting to see something's changing. It obviously is not working yet but it's starting to change.

large

Now, you may also be curious on why we have all of this code up here at the top or we have that content at the top when we said bottom: zero, that should mean it's gonna be on the bottom. With the way it works, and this is the way normal CSS works as well, is that bottom: zero means that this content's gonna be placed absolutely at the bottom of its parent component, which in this case is the screen.

So in order to get this working properly, we need to actually update the screen styles. So to start that off, I'm just gonna do a placeholder here but it's good because it's also gonna give you some knowledge on how you can add styles in line.

You can add styles directly into a component and many times, you'll find yourself when, say that you're working with a small component, a small view tag or a text tag or something like that and you don't actually want to have a resharable type of component, a resharable style, you just need a one-off style, this is how you can implement that.

Inside of the top View tag here, I can say style equals and then we're gonna use two curly brackets. So the reason why you need to use two curly brackets, 'cause this can look a little bit confusing if you haven't done this a lot, the outside curly bracket represents and tells JavaScript that we are gonna be placing in some JavaScript code inside of it.

Say that I didn't put another object here and I just put something like someFunction. And I called that, and it did some autocomplete and that's why that came up, but that would be called because it's JavaScript. Anything inside of here, if you put two plus two, you'd get four, that's just gonna run JavaScript.

So that first set of outside brackets, that's simply telling the system that we wanna use and process JavaScript. If we wanna put something else inside of it, so if we want to do an object, which that's whats necessary here, then we are going to put another set of curly brackets so now we have an object.

So inside of here, I'm going to put what we need for the screen to take up 100%. So for that, I'm just gonna say height colon and then as a string, I'm gonna say 100% and I'll hit Save.

Container.tsx

export default (props: IContainerProps) => {
  return (
    <View style={{ height: "100%" }}>
      {props.children}
      <BottomTabBar navigate={props.navigate} />
    </View>
  );
};

Any time you type out a percent in your CSS or for the CSS Style Sheet rules, then you need to type it out as a string like we did there and as you can see in the simulator, that moved all of our elements down to the bottom. So far, so good.

large

We now have a screen that's taking up 100% of the height and then we have a bottom tab bar here that now is positioned at the bottom, so let's keep going. We have our bottom, we also are gonna need to add what's called a zIndex, so I'm gonna type it out and then we'll walk through what this equals.

So I'm gonna do a zIndex of 1,000. What this does is because, if you can imagine what this is eventually gonna look like, we're gonna have all these posts and users are gonna be scrolling up and we want the bottom tab bar to be on the very top of what users are seeing.

We don't want posts to get in the way and we don't want any other components we call to sit on top of that bottom tab bar. So by saying zIndex 1,000 that means we're placing it at the top. Later on in the course, we're also gonna walk through a few other ways to do that so just stay tuned for that.

Now let's knock out a few other things. This is gonna get you back more into the just the way that you're used to writing CSS and how you build your own styles. So I'm gonna say that I want this to be flexDirection and we want this to be row.

Now, your first question right here, if you went through my flexbox course, first question should be how in the world am I calling flexDirection here and not calling displayFlex? So I'll hit Save here and you'll see, this is actually working. It's not fully styled yet obviously, but now, each one of these items are sitting right next to each other.

large

The reason for that is very cool if you're a fan of flexbox. Inside of React Native, it comes, all these style sheets, come with flexbox baked in by default so you don't have to do anything. Every one of these types of style objects is always gonna have displayFlex automatically.

There's one other default it's always gonna have that you have to keep in mind. It's the exact opposite of the way the web works. So on the web, any time you call displayFlex, the natural flexDirection is row. It's where you have each one of the elements sitting right next to each other.

Inside of React Native, they always bring in flexbox but they set the default to always be column and that kind of makes sense because usually when you're building out your layouts and your components in React Native, you're usually wanting them stacking on top of each other. But here, we're going to want them to be row because we want them here on the side.

So that is what you can do. You no longer have to type displayFlex and I want to do a justifyContent role here and for this we're gonna go space-around. Let's hit Save and see what that gives us and so far, nothing here has changed and I'm gonna show you why in a second, it has to deal with the width of what we have.

Let's go alignItems because I want these actually centered. Say alignItems: center. So far, no change. Kind of weird but you're gonna see why in a second. And it's something very good to keep in mind because when I was teaching myself React Native, this part was very confusing in the beginning and it speaks to simply the default nature of how React Native styles work. It is very different than how say a div works inside of HTML and so that's important to keep in mind.

So now, let's decare a width, this is gonna fix one of our issues. So I'm gonna say the width is 100% and now you can see each one of those elements is working perfectly. Now they're spread out where we want them to be. Now let's add a height, let's go height of 80. I'm gonna hit save and now you can see this is all working.

One of the most important parts of this entire video I want you to remember, a View tag, a View component in React Native does not come with a height at all. So if you do not declare the height, the way it's gonna work is whatever content is filling up that tag is going to be the default height and if you do not have content or you have something where you're trying to set the style and the layouts inside of the CSS.

So say you're trying to create like a blue button or something like that, if you don't have content in the button, the View tag is not even gonna show up. That can lead to some very confusing things when you're building this and so it's important to keep in mind. You always have to define the height of your View tag and you're gonna see later on how we can create some dynamic heights.

We can say okay, based on the size of an image, we're gonna change the height and we're gonna do things like that. Just a few more things here and then we'll wrap this video up.

Next one, I'm gonna do backgroundColor and for this, we are going to dig into our color pallette. You notice, we're not using these colors anymore which is fine. If you reference it again, we have one that's called dark and so that's what I wanna use for this backgroundColor. So I can simply call dark, hit Save and there we go, that's all working.

bottomTabStyles.tsx

import { StyleSheet } from "react-native";
import { dark } from "../colors";

export default SytleSheet.create({
  container: {
    position: "absolute",
    bottom: 0,
    zIndex: 1000,
    flexDirection: "row",
    justifyContent: "space-around",
    alignItems: "center",
    width: "100%",
    height: 80,
    backgroundColor: dark,
  }
});

Now, you can't see the text here and I'll show you how we can fix that here in a second. I'm not worried about that because we're gonna be replacing this text with icons anyway. So I'm gonna say dark and if you notice, it's a little bit hard to see but if you really notice and let's fix one thing really quick just so it's easier for you to see on the screen.

So I don't need to go in the colors, let's just go in the bottom tab bar and let's add Text here and a style so I'm gonna say style equals color: white. Hit Save and now you'll see that Feed is working.

BottomTabBar.tsx

export default (props: IBottomTabBarProps) => {
  return (
    <View style={bottomTabStyles.container}>
      <TouchableOpacity onPress={() => props.navigate("Feed")}>
        <Text style={{ color: "white" }}>Feed</Text>
      </TouchableOpacity>

large

I'm not gonna change the other ones 'cause you'll see what we're gonna do in one of the next videos but you can see that.

Now, this also goes to speak to how the colors work between View tags, View components, and Text components. If I wanna change the color of the text, I can't directly do it here in a style that is only called by one of those View components and we can test it out in case you don't believe me. So I can say color here in this container, change it to white, hit Save and you can see, none of these other changed.

large

That is also something that might be helpful for you later on. I know it was for me because when I was originally building out my first few React Native apps, I was confused because I was used to the way CSS worked. If I changed the color of a div and there were no other child styles that were overriding that color, then that color would stand. So if this were a div and we were writing this for the web, by me placing color inside this container, all of those elements would have been white but that's not the way it works here.

You actually have to go and address each one of the components directly. We don't follow the same type of cascading style sheet rules here. Here we have to be very explicit on how it works. So I'm going to remove that. And the last change I wanna make, you can see this feed here, I think it's located, each one of these is located a little bit low so I'm just gonna add a padding.

So I'm gonna say paddingBottom and let's say 15. Hit Save and that brought it up a little bit more.

bottomTabStyles.ts

import { StyleSheet } from "react-native";
import { dark } from "../colors";

export default StyleSheet.create({
  continer: {
    postition: "absolute",
    bottom: 0,
    zIndex: 1000,
    flexDirection: "row";
    justifyContent: "space-around",
    alignItems: "center",
    width: "100%",
    height: 80,
    backgroundColor: dark,
    paddingBottom: 15
  }
});

So great job if you went through that, you now have a bottom tab bar layout.

Resources