In this lecture, I want to dive a bit deeper into flexbox, especially regarding how you use it in React
Native apps.
If you know all about that already, you can of course skip this lecture.
So for this, I prepared a simple dummy application
and of course you find that attached, it's a normal React Native app built with expo and in the app.js
file here, what I have in the end is just a view with three views in there where each view then has a
text with text one, two, three,
this simply creates some boxes with different colors - red, blue and green and now we'll use flexbox
to move these boxes around so that you can get a feeling for how flexbox works because it's so important.
Now
first things first, by default every view in React Native,
even if you assign no special styles uses flexbox and that's different to the web for example, there
if you have a div which would be your equivalent to a view kind of, it doesn't use flexbox by default.
In React Native, it does, every view by default organizes its children with the help of this flexbox
thing, flexbox simply is a term, is simply a concept from CSS that is all about organizing child
elements in a one-dimensional space,
so here for example in a column. That's also another default,
not only does every view by default use flexbox, it also by default organizes children in a column,
so from top to bottom. That's also a difference to the web
and I don't want to emphasize these differences too much because of course you don't need to be a web
developer to build React Native apps but I think a lot of people do know web development,
do know CSS flexbox and therefore it makes sense to also talk about the differences. So in the
web when you use flexbox,
not only is it not turned on by default,
in addition if you do turn it on, the default is to organize all child elements in a row and here, the default
is to organize them in a column.
You can change that default though, so in this case on the view which holds my boxes, by adding flex direction
here and setting this to row for example, now you will see that these three boxes are organized in a row
from left to right. Now besides row and column,
you also have row reverse and column reverse
and this simply also does what the name implies.
Now we still have a row but the first element, the red box actually is on the right and not on left anymore,
so that's also something you can do,
let me go back to row though. So that's the the first thing you can do.
Another important thing about flexbox is how child elements are sized, here
I gave every child element a width and a height of 100.
Now if we would remove that width and height thing on every child element, then you will see that now we
have a very small row here because every box now is only as wide as its child requires it
to be and only as tall as its child requires it to be,
so every box here which holds a number is only as wide and tall as the number it's containing.
Now you can change that with the surrounding flexbox container too. Let's give that a width of let's say
300 pixels or of 80% of the parent width,
so in this case since it's the root element, of the device width and let's give it a height of let's say
300.
If we do that and now really important, I'm doing this on the view which holds all these boxes, I'm not
doing it on the boxes themselves.
So if we assign this width and height on the surrounding box, you see something interesting,
the height is assumed for all the elements,
now all the views in the flexbox take the height of the parent, the width has no impact here.
That's also a default behaviour you've got here, obviously since we haven't changed anything.
The default behaviour here indeed is that the child elements in a flexbox,
so in this outer view here, are organized such that they align themselves along the cross axis by stretching.
Okay, that were a lot of terms, what does this mean? Now when working with flexbox,
we have two important axis. The main axis depends on your flex direction, for a row which we have here,
flex direction row, the main axis is from left to right. For row reverse, it would be right to left, for
column, it would be top to bottom and for column reverse, it would be bottom to top,
so that's the main axis
and then you also have a cross axis and that's simply the opposite of the main axis.
So for a row where the main axis is from left to right, the cross axis would be from top to bottom. If
the main axis is from right to left which would be the case for row reverse, then the cross axis would
be from bottom to top.
Okay, so that's the main axis and cross axis concept.
Now you can organize your child elements, so in this view where we have the three boxes as child elements,
you can organize these child elements along this axis. You use justify content to organize elements
along the main axis and you have align items to organize elements around the cross axis.
Now you see the values you got for justify content here
if you add these quotes or if you place your cursor in there and you hit control space. You see you
can center elements, you can position them at the end or at the start of that container or you can add
some space in between,
for example if we use space between here and we use align item center, then things will change.
Now you will see there taking the width of the surrounding container,
every box itself still is pretty small but they're split or they're distributed across the width of
the parent container and they're no longer taking the height because along the cross axis, we're aligning
them with align items and there, I set this to center.
The default here is stretch and if I set it back to stretch, then unsurprisingly they do stretch for
the entire height.
Now if you want to make sure that they take the available width, you can't set stretch here on justify
content which is your main axis positioning vehicle, so you can't set stretch here.
So what can you do regarding that then?
Well, that is something you now configure on every child item itself.
You can tell a child item how much space it should take off the space it's potentially getting. Stretch
here is kind of a special case, there you set this up on the parent item,
normally you set this up on the child item.
So for example if I set this to center now so that the parent doesn't tell the child how much space
it should take, then we can fully control the space a child takes by going to the child style and there,
you can add flex, the flex property. The flex property is applied to items that are inside of a flexbox,
so that are inside of a view
in this case here and that can be a view itself but that could also be another component like a text
for example.
So now here, you can add flex and you can set this to a value of one for example,
so flex needs to be a number. If you set this to one, what you will see is that
now the red container where I did set flex to 1 takes all the available width it can get just so much
that it leaves enough space for the blue and the green container so that they can squeeze their content
into the surrounding flexbox.
Now we can't see the boundaries of the surrounding container but the boundaries would essentially be where
the red item starts and the green item and so on the horizontal axis here.
So now flex one makes sure that the red item gets as big as it can get,
so it takes as much space as it can get. By default, views only take as much space as their child elements
require,
so as this one character required but with flex one, you change this and they now take as much space along
the main axis,
so along the width here, as they can get. For the cross axis,
again that's a special case, you have to do this on the parent. For the main axis
and since we have row here, the main axis is a horizontal axis from left to right,
you do this with the flex property on a child.
Now of course you can add flex to other child elements as well, like that second to the blue container
with the two in there,
you can add flex one there as well.
So now I have flex one on the red container and flex one on the blue container and
what now happens is that both of them take the available free space and amongst these two boxes, the
space is distributed evenly and that's what this number here indicates.
This number is a relative number,
all items in the same flexbox, with the flex property distribute the available space by considering
the number you assign here and these numbers are relative to each other.
So if I give the blue container flex two here, then this means that of the available space you have
in that surrounding container, after deducting the space every element needs to squeeze its content in
there,
the blue container will take twice as much space as this one because here we have flex one,
here we have flex two,
if we had flex three here, then this would take three-fifths of the available free space because we have
three plus two,
so we have 5 available segments so to say and here the red container would take 3 segments, blue container
would take 2 segments.
If we have 1 and 2, then we have three available segments and the blue container takes two of them,
red takes one, so you always add up these flex numbers and then distribute or that's automatically done
of course but then the available space is distributed accordingly.
So now here, we'll see that the blue container is twice as big as the red one or it takes twice as much
free space as the red one.
So this is how you can work with flex,
you can organize how items are positioned with flex direction, with justify content and with align
items and you can also make your items grow and shrink with the help of flex.
So now that's a brief introduction to flexbox in React Native,
as I said inspired by Flexbox for CSS, so if you knew that, all of what I explained here is probably
not new to you.
We'll work with flexbox throughout this course,
so there things will also become clearer and we'll work a lot with it and you'll see how you can create
beautiful user interfaces with flexbox, flexbox in the end is the tool in React Native to structure
your content on a page, to organize your content and you will typically work with a lot of views which
you also nest into each other so that you can position elements the way you want because of course
and that's also important,
you don't just have to have one view in your app which uses flexbox,
you could have another view in there which also uses flexbox and actually as I mentioned, every
view by default uses flexbox and you can then nest these views into each other so that you position
everything the way you want and you'll also see this in this module already
and actually, I'm already doing it here. In my views here which are in the surrounding view, so my boxes
here, there I also use justify content and align items to center my numbers in these boxes, so that
1, 2 and 3 are centered there horizontally and vertically and that works because we have flexbox turned
on by default and we can't turn it off by the way and therefore, I just use these two properties here
to align my content of this view along the main and the cross axis and here since I set no special flex
direction for this view, the main axis is top to bottom because the default flex direction is column
and the cross axis is left to right.
That's just a side note.