CSS for Developers

Lucas Schnüriger & Mithusan Sivakumar

Flexbox layout

display Property

With this we control how an element is rendered:

  • inline: default for most elements, no size, no margin & padding
  • inline-block: like inline but with margin & padding
  • none: doesn't get rendered at all
  • and more (important ones)…

display: block

  • Displays an element as a block element
  • Element starts on a new line and takes up the 100% width
  • block is vertically oriented (stacked)
  • This is the default for some elements, has size and margin & padding.

block challenges

  • how to center element within another?
  • how to handle dynamic element sizes?
  • how to layout elements horizontally?

Flexbox layout (Flexible Box)

The flexbox layout aims to provide an efficient way to layout items in a container, even when their size is unknown.

  • Flexbox is mainly a single-direction layout concept
  • It has a main axis and a cross axis
  • We can choose whether the main axis is horizontal (default) or vertical

Flex Container

The container that is styled with display: flex or display: inline-flex.


              .flex-container {
                display: flex;
              }
            

Flex Item

Any element that is a direct child of a flex container.


                    .flex-container {
                      display: flex;
                    }
                

                    
Flex Item 1
Flex Item 2
Flex Item 3

display: flex


                    .parent {
                        display: flex;
                    }
                

                    <div class="parent">
                      <div>Item 1</div>
                      <div>Item 2</div>
                      <div>Item 3</div>
                    </div>
                
Item 1
Item 2
Item 3

main axis from left to right

Flexbox has some properties for the parent container and some for the individual items

Item 1
Item 2
Item 3
container

Parent container properties

justify-content

Controls how elements are layouted along the main axis


                    .parent {
                        display: flex;
                        justify-content: flex-end;
                    }
                

                    <div class="parent">
                      <div>Item 1</div>
                      <div>Item 2</div>
                      <div>Item 3</div>
                    </div>
                
Item 1
Item 2
Item 3

justify-content: most used values

Item 1
Item 2
Item 3
flex-start
Item 1
Item 2
Item 3
flex-end
Item 1
Item 2
Item 3
center
Item 1
Item 2
Item 3
space-between
Item 1
Item 2
Item 3
space-around

align-items

Controls how elements are layouted along the cross axis


                    .parent {
                        display: flex;
                        align-items: flex-start;
                    }
                

                    <div class="parent">
                      <div>Item 1</div>
                      <div>Item 2</div>
                      <div>Item 3</div>
                    </div>
                
Item 1
Item 2
Item 3

align-items: most used values

Item 1
Item 2
Item 3
flex-start
Item 1
Item 2
Item 3
flex-end
Item 1
Item 2
Item 3
center

What if we want to layout vertically instead of horizontally?

We can switch the main and cross axis with flex-direction!

flex-direction

Controls which axis is the main axis (horizontal/vertical)

flex-direction: row (default)
Item 1
Item 2
Item 3
flex-direction: column
Item 1
Item 2
Item 3

flex-direction

It's also possible to reverse the direction

flex-direction: row-reverse (default)
Item 1
Item 2
Item 3
flex-direction: column-reverse
Item 1
Item 2
Item 3

flex-direction

hint: flex-start and flex-end are also reversed

Item 1
Item 2
Item 3

                    .parent {
                        display: flex;
                        flex-direction: row-reverse;
                        justify-content: flex-end;
                    }
                    

Child item properties

What if we don't want to layout all items along the cross axis the same way?

Item 1
Item 2
Item 3

align-self

controls alignment along cross axis for individual element (similar to align-items)

Item 1
Item 2
Item 3

                    .parent { align-items: flex-start; }
                    .child-end { align-self: flex-end; }
                    

                    <div class="parent">
                      <div>Item 1</div>
                      <div class="child-end">Item 2</div>
                      <div>Item 3</div>
                    </div>
                

flex-basis

Sets the initial size of a flex item along the main axis - useful in combination with flex-grow (next)

no flex-basis set
no flex-basis set
Both children take exactly the space they need
flex-basis: 200px
flex-basis: 400px
no flex basis set
The first and middle child respect their size, the other one takes the necessary space

What if we want to make sure that the items use up all the available space?

Item 1
Item 2
Item 3
vs.
Item 1
Item 2
Item 3

flex-grow

  • controls if and how an item grows to use the remaining space (container size minus all item sizes)
  • space is distributed according to proportion defined by flex-grow
flex-grow: 1
flex-grow: 2
flex-grow: 1
No flex-basis set, child 2 gets double the extra space
grow: 1
grow: 2
grow: 1 | basis 350px
Third child has flex-basis set which takes precedence
flex-grow only influences the remaining space!

flex-shrink

  • controls if and how an item shrinks if all items combined are larger than the container
  • children with a higher value for flex-shrink shrink more
flex-shrink: 1
flex-shrink: 2
flex-shrink: 1
Child 2 shrinks more than the others
flex-shrink only applies if the children are larger than the container!

What if we change the order in which individual elements appear?

Item 1
Item 2
Item 3
vs.
Item 1
Item 2
Item 3

order

  • child elements can have an individual order
  • default is 0
order: 1
order: 5
order: -1
order: 3
order: 2

                    <div>
                        <div style="order: 1">order: 1</div>
                        <div style="order: 5">order: 5</div>
                        <div style="order: -1">order: -1</div>
                        <div style="order: 3">order: 3</div>
                        <div style="order: 2">order: 2</div>
                    </div>
                
Use order with care, it can be unintuitive
Exercise 1 Try to solve levels 1-13 and 16 of Flexbox froggy (or use next slide)
Solve levels 1-13 and 16
(press down to hide this)

Properties for containers with many elements

What if we have too many child items for one line?

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15

flex-wrap

Controls if and how elements are wrapped on new lines

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15
flex-wrap: no-wrap
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15
flex-wrap: wrap

gap / row-gap / column-gap

Control the gaps between rows and columns

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15

                    .parent {
                        display: flex;
                        align-items: flex-start;
                        flex-wrap: wrap;
                        row-gap: 30px;
                        column-gap: 10px;
                    }
                

align-content

Control how extra space on the cross axis is allocated

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
align-content: stretch
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
align-content: space-between
only applies if elements wrap
Exercise 2 Try to solve levels 18-23 of Flexbox froggy (or use next slide).
Solve levels 18-23
(press down to hide this)

Build person card

Laura Roberts

Member since 2015

4600 Olten


Offers

Vintage Jacket

CHF 65

Blazer Black

CHF 115

Nike Air Force

CHF 95

Close
More
Exercise 3 Build your own person tile

Go to the code sandbox and try to build the person tile after the design from figma

Link to possible solution

Build person card

Laura Roberts

Member since 2015

4600 Olten


Offers

Vintage Jacket

CHF 65

Blazer Black

CHF 115

Nike Air Force

CHF 95

Close
More

                        .personal-header {
                            display: flex;
                            align-items: center;
                            gap: 16px;
                        }
                        .product {
                            display: flex;
                            align-items: center;
                            gap: 16px;
                        }
                        .actions-container {
                            display: flex;
                            justify-content: space-between;
                            margin-top: 24px;
                        }
                    

Questions?