Essential CSS Tutorial – Flexbox

Designing and managing web layouts by positioning individual elements proves to be cumbersome specially for modern web-based products which cater to various sizes of viewports. Enters Flexbox, a CSS layout model, which simplifies designing layouts for webpage / webapp. It’s a layout mechanism through which elements are arranged in rows or columns seamlessly.

So without further ado, let’s create a new HTML file named ‘flex.html’ in ‘csstut’ folder which we created in first part of this tutorial series and insert the following code into it:

<!DOCTYPE html>
<html>
<head>
<title>Flex</title>
<link rel="stylesheet" href="styles3.css">
</head>
<body>
  <div class="box">
    <div class="item-1">
      <h1>Heading 1</h1>
      <p>This is paragraph 1 under the Heading 1</p>
    </div>
    <div class="item-2">
      <h1>Heading 2</h1>
      <p>This is paragraph 2 under the Heading 2</p>
    </div>
    <div class="item-3">
      <h1>Heading 3</h1>
      <p>This is paragraph 3 under the Heading 3</p>
    </div>
  </div>
</body>
</html>

Save and load ‘flex.html’ in the browser – observe the default block look of all the items (children <div>). Now, create ‘styles3.css’ in ‘csstut’ folder and insert the following styles in it:

body{
	margin: 20px;
}

.box{
	display: flex;
}

.box div{
	border: 2px solid black;
	margin: 10px;
	padding: 10px;
}

Save ‘styles3.css’ and reload ‘flex.html’ in the browser – due to ‘display: flex;’ style the parent <div> (applying ‘.box’ style) has turned into a Flexbox container and all the container’s items (children <div>) act accordingly i.e. being shown in a row which is default flow direction for flex container. We can customize flow direction by using ‘flex-direction’ style. So let’s insert a media query to make container’s flow direction as ‘column’ for smaller screens:

@media screen and (max-width: 800px) {
    .box {
	flex-direction: column;		
    }
}

Save ‘styles3.css’ and load ‘flex.html’ in the browser – reduce the size of browser window and observe how children <div> are arranged in column for screen sizes less than or equal to 800px.

Let’s make container’s items (children <div>) more interesting. We can define the space occupied by each item within the container by using ‘flex’ style and we can even define the order in which each item is displayed using ‘order’ style which is helpful when dealing with different screen sizes. Let’s put ‘flex’ and ‘order’ on each item within container by inserting following code in ‘styles3.css’:

.item-1{
	flex: 2;
	order: 2;
}

.item-2{
	flex: 4;
	order: 1;
}

.item-3{
	flex: 1;
	order: 3;
}

Save ‘styles3.css’ and reload ‘flex.html’. Here we’ve defined ‘flex’ as 2, 4 and 1 respectively for each item which signifies how much relative width each item will have. Put it in other words, item-2 has the largest width (i.e. 4), item-1 has half of the width of item-2, and item-3 has half of width of item-1. We have also defined ‘order’ style for each item which signifies the actual order in which items will be displayed; therefore, item-2 is displayed first, then item-1 and lastly item-3.

For aligning the children items within the container we use ‘align-items’ style which works according to the flow of direction (flex-direction) of container – if the flex-direction is ‘row’, the children items will align vertically (along y-axis); if the flex-direction is ‘column’, the children items will align horizontally (along x-axis). To understand this, let’s enhance container’s styles by adding ‘align-items’ style as follows:

.box{
	display: flex;
	align-items: flex-end;
}

@media screen and (max-width: 800px) {
    .box {
	flex-direction: column;		
	align-items: flex-start;
    }
}

Save ‘styles3.css’ and reload ‘flex.html’ in the browser. Observe that when the items are in row (as in screen larger than 800px) all of them are vertically aligned at the ‘end’ (i.e. baseline of row). Reduce the browser window size and observe the effect more vividly. Further reduce the size less than 800px, and the items will align horizontally in column at the ‘start’ (i.e. left side of the column). We can define ‘align-items’ as ‘center’ in order to align items in the middle. You can try changing the value as ‘center’ in the ‘align-items’ style and observe the change.

Let’s move onto another Flexbox’s concept i.e. ‘flex-wrap’ – by adding ‘flex-wrap’ style for flex container, we can make it automatically manage the flow of children items within the container. To understand ‘flex-wrap’ let’s add a new flex container along with its children items by inserting following code into ‘flex.html’:

  <div class="box2">
    <div>
      <h1>Heading 4</h1>
      <p>This is paragraph 4 under the Heading 4</p>
    </div>
    <div>
      <h1>Heading 5</h1>
      <p>This is paragraph 5 under the Heading 5</p>
      </div>
    <div>
      <h1>Heading 6</h1>
      <p>This is paragraph 6 under the Heading 6</p>
    </div>
  </div>

Now add following code into ‘styles3.css’:

.box2{
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}

.box2 div{
	border: 2px solid black;
	padding: 10px;
	margin: 5px;
}

Save both ‘flex.html’ and ‘styles3.css’ and then reload ‘flex.html’ in the browser – We have another container with three children items. Here, we have used couple of new styles; first one is ‘flex-wrap: wrap;’ which automatically manages the flow of items and wraps around items which can’t be rendered within the viewport’s width. Let’s grab the browser window and start to decrease its size; notice that once the items don’t have enough space to squeeze them in one line, they will wrap around and one or more of the items will be pushed to next line automatically.

We have also used ‘justify-content’ style which manages how the items are distributed in the available space of the container. In simple worlds, it manages the space between and around the items. Here, we’ve defined ‘justify-content: center;’ so the items will be centered within the available space of container. You can try different values e.g. ‘start’, ‘end’, ‘space-between’, ‘space-around’ etc, and see how items get distributed within the container.

We’re done with the basics of Flexbox but here is food for thought – what if we want to place a child item right in the middle of container horizontally as well as vertically. Here is the quick solution using the styles we have just learnt:

.box3{
	display: flex;
	align-items: center;
	justify-content: center;
}

Clean and simple 😉 We have inserted third <div> in following final files to demonstrate the above trick.

The final ‘flex.html’ and ‘styles3.css’ are as follows:

<!DOCTYPE html>
<html>
<head>
<title>Flex</title>
<link rel="stylesheet" href="styles3.css">
</head>
<body>
  <div class="box">
    <div class="item-1">
      <h1>Heading 1</h1>
      <p>This is paragraph 1 under the Heading 1</p>
    </div>
    <div class="item-2">
      <h1>Heading 2</h1>
      <p>This is paragraph 2 under the Heading 2</p>
    </div>
    <div class="item-3">
      <h1>Heading 3</h1>
      <p>This is paragraph 3 under the Heading 3</p>
    </div>
  </div>
  <div class="box2">
    <div>
      <h1>Heading 4</h1>
      <p>This is paragraph 4 under the Heading 4</p>
    </div>
    <div>
      <h1>Heading 5</h1>
      <p>This is paragraph 5 under the Heading 5</p>
      </div>
    <div>
      <h1>Heading 6</h1>
      <p>This is paragraph 6 under the Heading 6</p>
    </div>
  </div>
  <div class="box3">
    <div>
      <h1>Heading 7</h1>
      <p>This is paragraph 7 under the Heading 7</p>
    </div>
  </div>
</body>
</html>
body{
	margin: 20px;
}

.box{
	display: flex;
	align-items: flex-end;
}

.box div{
	border: 2px solid black;
	margin: 10px;
	padding: 10px;
}

@media screen and (max-width: 800px) {
    .box {
	flex-direction: column;		
	align-items: flex-start;
    }
}
.item-1{
	flex: 2;
	order: 2;
}

.item-2{
	flex: 4;
	order: 1;
}

.item-3{
	flex: 1;
	order: 3;
}

.box2{
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}

.box2 div{
	border: 2px solid black;
	padding: 10px;
	margin: 5px;
}

.box3{
	display: flex;
	align-items: center;
	justify-content: center;
	width:500px; 
	height: 300px; 
	border: 2px dashed black;
}

.box3 div{
	border: 2px solid black;
	padding: 10px;
}

Leave a Comment