You are on page 1of 96

FlexBox

MMINTER
??
a new way of layout on CSS that
combines:
● block
What is ● inline
● table
Flexbox ● position
● float

into an easier and more elegant


way of positioning elements
let’s first setup a

hands-on
learning workshop
1. Go to codepen.io
2. Select START CODING
3. Click on CHANGE VIEW, and
select EDITOR VIEW
4. Optionally, since we will
not be using the JS
(Javascript) section, you
can click on the dropdown
arrow and select MINIMIZE
JAVASCRIPT EDITOR
5. Your screen should look like
this.
6. Let’s call this YOUR PEN
6. Open a new window or tab
7. Go to this URL:
https://codepen.io/pixelworks/pen/yLYLNbE
8. Let’s call this the
SOURCE PEN
9. Copy the HTML from the
SOURCE PEN and paste it in
the HTML section of
YOUR PEN.
10. This should be the result
in the OUTPUT area of YOUR
PEN
Explanation of the HTML:
The entire block is inside a container with the class .container
Some text
div.container has five children containers all denoted by the
<div class="container">
class .item This is so we can give a common format to all.
<div class="item item1">1</div>
<div class="item item2">2</div>
Each of the div.item containers have a second class: .item1 for
<div class="item item3">3</div>
the first, .item2 for the second, etc. This is so we can format
<div class="item item4">
each of them individually.
<div class="subitem subitem-a">A</div>
<div class="subitem subitem-b">B</div>
div.item4 has three children, each denoted by the .subitem
<div class="subitem subitem-c">C</div>
class.
</div>
<div class="item item5">5</div>
Each of the div.subitem containers have a second class:
</div>
.subitem-a, .subitem-b, and .subitem-c so we can format each
individually as well.
11. From the SOURCE PEN, copy
the CSS code and paste it in
the CSS section of YOUR PEN
12. The output should look like
this
.container
Explanation of the CSS: ● set the font-family to display in a sans-serif typeface
● add a background color so that we can see the container

}
.container{ ● set the width of the container so that is will not be larger
font-family:sans-serif; than 900px, but it can shrink when the window shrinks.
background-color:#EFEFEF; ● margin:auto centers the container on the window
max-width:900px;
margin:auto; .item
} ● set the text to display at 24px
.item{ ● set the text to be displayed as white

}
font-size:24px; ● set the background of the container to hot-pink
color:#FFFFFF; ● set a 1px margin all around the container
background-color:#F81894; ● the default setting of a container is display:block which
margin:1px; forces the container to fill up its parent container.
display:inline-block;
} Learning Opportunity: Remove display:inline-block or
replace it with display:block and see what happens.

display:inline-block tells the container to keep its natural


size.
Explanation of the CSS:
.item1 to .item5
● individually set the padding so there are different sizes of
.item1{
item containers
padding:50px 50px;
}
.item2{
padding:0px 50px;
height:200px;
}
etc...
Explanation of the CSS:
.subitem
● set the font inside the container to be displayed at 16px;
.subitem{

}
(even if we don’t set the color, this container inherits the
font-size:16px;
color of its parent, which is white.)
background-color:#3C1361;
● set the background color of the container to violet.
margin:1px;
● set a margin of 1px all around the container
display:inline-block;
● Again, we employ display:inline-block so that the
}
subitems do not grow to the entire width of its parent
.subitem-a{
(which is .item4)
padding:5px 20px;
}
.subitem-a to .subitem-c
.subitem-b{
● sets the paddings of the different subitems so that they
padding:5px 40px;
will have different widths.
}
.subitem-c{
padding:5px 10px;
}
We are all set!

If you have any questions about


the HTML or the CSS, now is the
time to ask your teacher.
the flexbox

axes
Flexbox Concepts

Flex Container

Flex Item Flex Item Flex Item Flex Item Flex Item
Flexbox Concepts

ROW

Main Axis

Cross Axis
Flexbox Concepts
Main Axis
COLUMN

Cross Axis
Flexbox Concepts

OUR OUTPUT

Main Axis

Cross Axis
properties that affect the

container
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:inline-flex;
}

First thing we noticed is that the items (pink boxes) filled up the container. We
will get to that in a bit. For now, let us concentrate on the main container.

When we use display:inline-flex, the text and the container are


treated as part of inside a block.

This is why the text is side-by-side with the flex container.


.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
}

When we use display:flex, the text is treated as a different block,


and the container is also treated as a different block.

This is why the text is on a different line of its own, and likewise,
the container has line of its own.
Some text
<div class="container">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">
<div class="subitem subitem-a">A</div>
<div class="subitem subitem-b">B</div>
<div class="subitem subitem-c">C</div>
</div>
<div class="item item5">5</div>
</div>
DELETE the text so we will not see it for the rest of the workshop.

We will also leave the display property of .container to


display:flex;
properties that affect the

main axis
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
}
flex-direction:row tells the direction of the items to be displayed
in a row;

By default, it is set to row


.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row-reverse;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:column;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;

flex-direction:column-reverse;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:flex-start;
}
justify-content determines how the items will be displayed on
the main axis
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:flex-end;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:center;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
the space in-between the items are all the same width
justify-content:space-between;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
}

the space around the items are all the same width
properties that affect the

cross axis
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
align-items:flex-start;
align-items determines how the items will be displayed on the
} main axis

Important!
By default, the align-items is set to align-items:stretch, which is
why in previous outputs, the items are stretched to fill the
container based on the largest item.

When we changed the align-item property, it reverted to its


original size.
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
align-items:flex-end;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
align-items:center;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
align-items:baseline;
align-items:baseline aligns the baseline of the text
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row;
justify-content:space-around;
align-items:stretch;
align-items:stretch expands all items so that they fill the
} cross-axis

Since this is the default, items will be stretched if you do not set a
property for align-items
properties that affect the

cross axis
with more than one line of items
We need to set up our HTML to
display items in different
rows. Change /add the following
properties.

.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;
We are setting the width and height of the main
justify-content:space-between; container so that items will be more than what the
align-items:stretch; width of the container can handle
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
}

The container is too small to fit all the items, and


so the items spill out.

In order for it to be kept inside the container, we


need to tell the flex container to WRAP the items
so they flow to a next row.
Just like align-items, the
.container{ default of align-content
font-family:sans-serif; is stretch.
background-color:#EFEFEF;
This is why the items are
max-width:350px; all stretched by default.
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
}
align-content affects the
.container{ cross-axis, so the start of
font-family:sans-serif; the axis is the top.
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
align-content:flex-start;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
align-content:flex-end;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
align-content:center;
}
Since there are only two
.container{ rows, flexbox puts a
space in between them.
font-family:sans-serif;
background-color:#EFEFEF; If there were more rows,
max-width:350px; the space in between
height:500px each row will be the
margin:auto; same.

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
align-content:space-between;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:350px;
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
The space around the
align-items:stretch; rows is the same.
flex-wrap:wrap;
align-content:space-between;
}
When align-content is
.container{ set to stretch, each row
font-family:sans-serif; will stretch to the tallest
item in the row (it
background-color:#EFEFEF; doesn’t check for all the
max-width:350px; items; just inside its
height:500px row.)
margin:auto;
This means two rows
display:flex; can have different
height.
flex-direction:row;

justify-content:space-between;
align-items:stretch;
flex-wrap:wrap;
align-content:stretch;
}
properties that affect the

items
So far we have been using properties that
affect items of the entire main-axis, and how
they are aligned in the cross-axis.

However, we might want to target particular


items. We use the item properties to do that.
We need to set up our HTML and
CSS to reset our output.

.container{
font-family:sans-serif;
background-color:#EFEFEF; m 1 m2 m 3 m4 m5
max-width:900px; .ite .ite .ite .ite .ite
height:500px
margin:auto;

display:flex;
flex-direction:row;

justify-content:space-between;
align-items:flex-start;
flex-wrap:wrap;
align-content:stretch;
}
.item1{
padding:50px 50px;
order:2;
}

order:0 order:0 order:0 order:0 order:2

order sets the sequential order of an item inside a


container.

In our example, .item1 goes to the last of the


items because by default items have an initial
order of zero.
.item1{
padding:50px 50px;
order:2;
}

.item2{
padding:0px 50px;
height:200px; order:0 order:0 order:0 order:1 order:2
order:1;
}
.item5{
padding:60px 50px;
margin-right:auto;
}

margin-right is not a flexbox property, but it can be used to indicate that


the margin on the right of an item fill up all the space it can when set to
auto.
.item5{
padding:60px 50px;
margin-right:auto;
margin-left:auto;
}

margin-left also works the same way of course.


Before flex-grow
.item5{
padding:60px 50px;
margin-left:auto;
}

.item2{
padding:0px 50px;
height:200px; After flex-grow
order:1;
flex-grow:1;
}

flex-grow allows an item to expand towards the main-axis.

The number tells how many times the item will grow in relation to others
that also have a flex-grow property.

In this example .item2 fills up all the available space inside the container
.item2{
padding:0px 50px;
height:200px;
order:1;
flex-grow:1;
}

.item5{
padding:60px 50px;
flex-grow:2;
}

In this example, .item2 is set to grow 1 times more than then other, and
.item5 is set to grow 2 times more than the others.

Even if .item2 and .item5 started the same size, .item5 grows larger than
.item2
Before flex-basis
.item2{
padding:0px 50px;
height:200px;
order:1;
flex-grow:1;
}

.item5{ After flex-basis


padding:60px 50px;
flex-grow:0;
flex-basis:150px;
}

flex-basis sets the initial width of the item.

In this case, .item5 starts with a width of 150px;

Note that we had to set flex-grow to zero so we can see the initial state,
or else .item5 would have filled up all the space.
At 900px wide
.item2{
padding:0px 50px;
height:200px;
order:1;
}

.item5{
At 770px wide
padding:60px 50px;
flex-grow:0;
flex-basis:150px;
}

By default, items shrink as much as they can, which is good for


responsive design.

In this example:
.item4 was stretched because it had content that forced it to stretch.
When it shrunk, its content collapsed.
.item5 was stretched to 150px because that is what was set by the
flex-basis.

When the main container shrunk, these items shrunk to their smallest
limit. The other items are already in their smallest limit from the start.
Before flex-shrink
.item2{
padding:0px 50px;
height:200px;
order:1;
flex-grow:1;
}
After flex-shrink
.item5{
padding:60px 50px;
flex-grow:0;
flex-shrink:0;
flex-basis:150px;

} flex-shrink sets an item to shrink when the container shrinks. The


number indicates how many times more it shrinks compared to other
elements.

In our example, notice that .item5 does not shrink. It retains its flex-basis
size of 150px.

Notice that .item4 had to compensate by shrinking more. More items


wrapped inside of it.
.item2{
padding:0px 50px;
height:200px;
order:1;
flex-grow:1;
}

.item5{
padding:60px 50px; There is a shorthand for the three flex item properties:
flex-grow:0;
flex-shrink:0;
flex-basis:150px;
} flex: flex-grow flex-shrink flex-basis;

flex:0 0 150px;
}
.item3{
padding:30px 50px;
align-self:flex-end;
}

align-self will align the item across the CROSS-AXIS.

By Default, it is set to flex-start.


.item3{
padding:30px 50px;
align-self:flex-start;
}
.item3{
padding:30px 50px;
align-self:center;
}
.item3{
padding:30px 50px;
align-self:stretch;
}
nested flexbox
r
“Nesting” is when one t aine
n
item that lives inside a .co
container becomes a
container itself of the
same type.

In our topic, items of a


m4
flex container, can they .ite
themselves become a a b -c
In our example,
m- m- em .item4 is an item of
flex container. b ite b ite bit .container
.su .su .s u

A B C So that we can align


the elements inside
of it, we can also
turn it into a flexbox.

So there will be a
flexbox inside a
flexbox.
.item4{
padding:40px 10px;
display:flex;
}
.item5{
padding:60px 50px;
flex:0 0 150px;
} When we set .item4 to display as a flex, it seems that nothing
happens.

Actually the elements inside it become flex items.

The only reason we don’t see a change is that the flex-direction of


.item4 is set to row by default.
.item4{
padding: 10px 10px;
height:200px;
display:flex;
flex-direction:column;
}

We reduced the top padding .item4 just so we can see the changes
better. We also set its height to 200px for the same reason.

The main axis of .item4 flexbox is now set as a column.

Question? Why are all the items now the same size?
Answer: Because by default, the align-items is set to stretch.
guided
examples
what will the layout look like?
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
}
?
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:flex-end;
} ?
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:flex-end;
} ?

.subitem-a{
padding:5px 20px;
order:5;
}
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:flex-end;
} ?

.subitem-a{
padding:5px 20px;
order:5;
margin-top:auto;
}
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:flex-end;
} ?

.subitem-a{
padding:5px 20px;
order:5;
margin-top:auto;
flex:1 1 20px;
}
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:flex-end;
} ?

.subitem-a{
padding:5px 20px;
order:5;
margin-top:auto;
flex:1 1 20px;
align-self:stretch;
}
.item4{
padding:10px 10px;
height:200px;
display:flex;
flex-direction:column;
justify-content:center;
align-items:stretch;
} ?

.subitem-a{
padding:5px 20px;
order:5;
margin-top:auto;
flex:1 1 20px;
align:self:stretch;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row; ?
justify-content:center;
align-items:flex-start;
}
.container{
font-family:sans-serif;
background-color:#EFEFEF;
max-width:900px;
margin:auto;

display:flex;
flex-direction:row; ?
justify-content:center;
align-items:stretch;
}
.container{
font-family:sans-serif; Image 1
background-color:#EFEFEF;
max-width:900px;
margin:auto;
Image 2
display:flex;
flex-direction:row;
justify-content:center;
align-items:stretch;
}
Image 3

Question 1: In Image 2, why did .item2 not stretch all the way like the others?
Question 2: How would fix it so it still looks like the Image 1 but will stretch all
the way like the other items line in Image3 when align-items is set
to stretch?
Answer1: Because .item2 is set to a fix height of 200px.
Answer2: Set .item2 to min-height:200px so it can grow bigger
but not smaller than 200px;
hands-on
exercises
FlexBox CheatSheet

CONTAINER -this creates a flexbox container & flex items inside


it
To make a container a flexbox
display:flex|inline-flex;

MAIN AXIS
-these apply to all items inside the container
To set the direction of the
main-axis. Apply this to the flex-direction:row|row-reverse|column|column-reverse|
flexbox container initial|inherit;

To set the spacing of the


items justify-content:flex-start |flex-end|center|space-betwee
n|space-around|initial|inherit;

*pink values are the default values


FlexBox CheatSheet

CROSS-AXIS -these apply to all items inside the container


To set how items will align to align-items:stretch|center|flex-start|flex-end|baseline
the cross-axis if there is only |initial|inherit;
one row of items

To make the flow to a new flex-wrap:nowrap|wrap|wrap-reverse;


row if it cannot fit the
container

To set how items will align to align-content:flex-start |flex-end|center|space-between|


the cross-axis if there are space-around|stretch;
more than one row of items

*pink values are the default values


FlexBox CheatSheet

FLEX ITEMS (MAIN-AXIS) -these apply to individual items


To determine the sequence of order:(integer);
items along the main-axis Note that the default is zero even if you don’t set it

Make an item grow along the flex-grow:0|1(integer);


main-axis

Make an item shrink along the flex-shrink:1|0|(integer);


main axis

Set the width of an item flex-basis:(width);

Shorthand of flex flex:flex-grow flex-shrink flex-basis|auto|initial|


inherit;
FLEX ITEMS (CROSS-AXIS)
Set alignment along the align-self:auto|stretch|center|flex-start|flex-end|
cross-axis baseline|initial|inherit;
*pink values are the default values
FlexBox CheatSheet

Some helpful websites https://yoksel.github.io/flex-cheatsheet/

http://flexbox.malven.co/

https://css-tricks.com/snippets/css/a-guide-to-flexbox/
let’s first setup the

hands-on
initial codes
1. If you don’t want to lose
your code, create a free
account on codepen.io, save
YOUR PEN, and click on the
logo and CREATE > PEN

Let us set up your code for


this hands-on exercises

2. Go to this URL
https://codepen.io/pixelworks/pen/mdedrPv

3. Copy the HTML code to YOUR


PEN

4. Copy the CSS code to YOUR This should be the output on your codepen
PEN

5. Work on the 10 challenges


SETUP

Your first task is to add the


flex styles on the proper
containers so that the output
should look like this…

Hint: look for the main


container of the pink boxes;
then look for the main
container of the violet boxes.

Those are the two places where


you put the flex styles meant
for containers.

When you are done, you may


proceed to challenges in the
next pages.
Challenge 1:

Make the output look like this.

HINT:
● You need to use the ORDER
property
● Remember that items have an
order of zero by default.
Challenge 2:

Make the output look like this.

HINT:
● You are trying to fix the
items across the MAIN AXIS.
What property can fix all
items along the main axis.
Challenge 3:

Make the output look like this.

HINT:
● You are trying to fix the
items across the CROSS AXIS.
● What property, on one
container can do this for all
items?
Challenge 4:

Make the output look like this.

HINT:
● Notice that all the numerals
are in one straight line. It
is also in line with the
first letter (A).
● What one property applied to
one container can do all
this?
Challenge 5:

Make the output look like this.

HINT:
● We want item 4 to stretch to
fill up whatever space it can
fill.
● Look carefully, the numeral 4
is in the center of the
rectangle, not on the left!
What additional property can
you use to fix this. (It
isn’t a flex property.)
Challenge 6:

Make the output look like this.

HINT:
● We want item 4 to retain its
width but its margin on the
right to stretch to fill up
whatever space it can fill.
● You will not use a flex
property.
Challenge 7:

Make the output look like this.


Challenge 8:

Make the output look like this.

HINT:
● You may have to change
several properties of
different items or
containers.
Challenge 9:

Change the width of .container


so it is 320px wide.

Then,make the output look like


this.

HINT:
● You have to add a property to
the main container so that
the items will automatically
go to the next row if it
can’t fit in the container.
Challenge 10:

Change the width of .container


so it is 320px wide, and the
height so it is 500px high.

Then,make the output look like


this.

HINT:
● Now that you have more
than one row, you need to
use a flex property on the
container so that it will
push the first row to the
top, and the last row to
the bottom.

You might also like