Flexbox

Here's a good quick overview: https://www.youtube.com/watch?v=fYq5PXgSsbE

Here are some page layout designs using flexbox: https://www.quackit.com/css/flexbox/examples/flexbox_website_layout_examples.cfm

Create a page called flexbox.html and add this starter code to it:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Flexbox</title>
	<style type="text/css">
		/*We'll add styles here*/
	</style>
</head>
<body>
	<!--We'll add HTML elements here-->
</body>
</html>

Put this ruleset inside the STYLE element:

.container div {border: 1px solid black; margin: 1px; padding: 10px;}

Add this code to the BODY:

<p>Default behavior of DIVS (block-level elements)</p>
<div class="container">
	<div>DIV 1</div>
	<div>DIV 2</div>
	<div>DIV 3</div>
</div>

To see how the DIV elements look, load the page in the browser. By default, block-level elements in HTML take up the full width of their parent element and so they stack vertically.

We can take control of this layout behavior by setting the display property to flex on an element. Then, it's child elements can be controlled by many various flexbox properties.

Add this code inside the BODY element:

<p>Example 1 (Setting the container to display: flex)</p>
<div class="container ex1">
	<div>DIV 1</div>
	<div>DIV 2</div>
	<div>DIV 3</div>
</div>

Add this to the STYLE element and then look at the page in the browser:

.ex1{ display: flex; }

Notice that by setting the display property of the parent to flex, the children line up horizontally instead of vertically: Also notice that the children are no longer 100% width.

Flex Container (Parent) and Flex Items (Children)

When setting the dislay property to 'flex' for an element, it's important to be aware that the that it becomes what's known as a 'flex container' and that the children of the element are referred to as 'flex items'.

We can apply other properties to the parent to further control the layout of the children. You'll definitely want to experiment with the justify-content property, and the align-items property.

To demonstrate, add this code to the BODY:

<p>Example 2 - (justify-content for the container is set to 'center'):</p>
<div class="container ex2">
	<div>DIV 1</div>
	<div>DIV 2</div>
	<div>DIV 3</div>
</div>

And add this code to the STYLE element, and then reload the page:

.ex2{
	display: flex;
	justify-content: center; /* OPTIONS: center flex-start flex-end space-between space-around, space-evenly*/
	align-items: center; /* OPTIONS: stretch center start end (and more...)*/
}

The justify-content property controls the childrens alignment on the MAIN axis of the flexbox. These are the options for setting the justify-content property:

  1. center: Centers the divs on the MAIN axis
  2. space-between: Puts even spacing BETWEEN the children
  3. space-around: Puts even spacing AROUND the children
  4. space-evenly: distributes the unused space evenly between the children.
  5. flex-start: Puts the children at the left side (or top when flex-direction is column)
  6. flex-end: Puts the children at the right side (or bottom when flex-direction column)

Make sure to try each one of the options for justify-content in the rule set for .ex2

The align-items property controls the childrens alignment on the CROSS axis of the flexbox. Here are the options for setting the align-items property:

  1. strech: The children will take up as much space as possible on the cross axis;
  2. center: centers the children (vertically for flex-direction:rows and horizontally for flex-direction:columns);

You might be wondering what the MAIN and CROSS axis are, and about 'flex-direction'. It turns out that they are very closely intertwined. We'll get to that in just a moment, but first I should point out what happens if a flex container contains only text (not child elements). In this case the browser will treat the text as if it were a flex item. This allows you to easily control the alignment of text within a flex container.

Add this HTML code to the BODY element:

<p>Example 3 - (Aligning text within a flex container):</p>
<div class="container ex3">
	<div>DIV 1</div>
	<div>DIV 2</div>
	<div>DIV 3</div>
</div>

And add this to the STYLE element:

.ex3 {
	/*nothing to do here*/
}

.ex3 div{
	display: flex;
	height: 100px;
	justify-content: center; 
	align-items: end;
}

In this case DIV 1, DIV 2, and DIV 3 are set to be flex containers, and the text content inside them can be positioned with justify-content and align-items.

Flex Direction

The flex-direction property that you saw earlier (which is set on the parent) defaults to row. This means that the children will line up in a row horizontally. And that the MAIN axis is horizontal and the CROSS axis is vertical.

But if you change the flex-direction property to column, you'll notice that the children will line up vertically. In this case the MAIN axis would be vertical and the CROSS axis would be horizontal.

Add this code to the BODY:

<div class="container ex4">
	<div>DIV 1</div>
	<div>DIV 2</div>
	<div>DIV 3</div>
</div>

And add this to the STYLE element:

.ex4 {
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
}

By setting the flex-direction to column, the children (flex items) will stack vertically instead of horizontally. This also means that the MAIN AXIS is now vertical, and the CROSS AXIX is horizontal. Experiment with the justify-content setting and the align-items setting in this example to observe how the axis changes when you set the flex-direction to column.

Flex Grow

You can control the amount of space that a flex item occupies by setting it's flex-grow property. Add this to the BODY element:

<div class="container ex5">
	<div>DIV 1</div>
	<div class="bigger">DIV 2</div>
	<div>DIV 3</div>
</div>

Note that DIV 2 has a class of 'bigger' assigned to it. We'll get to that in just a minute.

But first, add this to the STYLE element:

.ex5 {
	height: 200px;
	display: flex;
	justify-content: center;
	align-items: center;
}

.ex5 div{
	flex-grow: 1;
}

Reload, and notice the effect of the flex-grow property that is set on the children. By setting it to 1, the children will automatically set their width equally across %100 of their parent.

The flex-grow property defaults to 0, which means that the element will only be as wide as the content that's inside of it. But as you have seen, setting it to 1 is a handy way of equally distributing the width of the children.

Now add this to the STYLE element and reload the page:

.ex5 div.bigger{
	flex-grow: 2;
}

You can use the flex-grow property to control page layout. For example, if you have a page with a 3-column layout, you could make the middle one twice as wide as the sides by setting it's flex-grow property to 2.