Using "flex" property in CSS to define webpage layout

Designing a flexible layout which can scale to different screens on many devices is non-trivial. We often use float, position: absolution or other properties to achieve the desired result. However this process is uncomfortable to developers and we always dream of a better way. Today, I want to introduce to you flex, the future of layout designing in CSS.

1. What is flex?

Flex or Flexbox is a set of CSS3 properties which are used for designing the layout. The term comes from the word "flexible". It ensures that elements behave predictably when the page layout must accommodate different screen sizes and different display devices. Yep, I copied the previous sentence from w3school because it has a good explanation for flex. You can just think of it simply as a new way to define the layout of your web page.

2. Why use flex?

Good question. We have been struggling with using div, display:block, float:left, etc to design a layout which sometimes does not behave exactly what we wanted. We also have trouble making the container height to exactly 100% of the browser height. I remember the time when implementing an app similar to Trello, we use a lot of JS + CSS just to make sure the page always fits the browser size.

Using flex, we can easily define the layout. It is shorter than using block or float. It is also easier to fix the layout and it is all CSS.

3. How to use it?

You need to remember a few things when working with flex, that is container and items. The ultimate rule of a flexbox is: all of its items marked as flex should have the same width/height regardless of their contents. Still confused? Check out this example:

Assume that we have the following markup:

<div id='columns'>
   <div class='column'>This is my column</div>
   <div class='column'>This is my column</div>
   <div class='column'>This is my column</div>
</div>

In above example, let's say that I want to have 3 columns with the same width inside a div tag. How should we do that? The normal way we can do is set the width of each column class to 33.33% (with display: inline). But that is not a good solution because we might want to have 4, 5 or more columns in the future and we do not want to change the width every time we do that. In addition, using 33.33% as width is not quite correct and it does not work well if you increase the margin of the div.

By using flex, this can easily be achieved by the following CSS:

#columns{
  display: flex;
}
.column{
  flex: 1;
  border: 1px solid black;
}

(JS Fiddle: https://jsfiddle.net/e9uwk8em/)

Now, 4 divs will be displayed nicely as 4 columns on the screen without any problem. They all have the same width and they still work fine even if you add margin or change the text of the div. The important properties here are "display: flex" and "flex: 1". The first property "display: flex" tells the browser that this HTML element will be containing some items which should be spaced equally. The "flex: 1" tells the browser that this HTML element is a flexible item and it should have the width similar to other flexible items.

But what if I want a column smaller than others?

Imagine a typical website where you have a sidebar on the left side and the main content on the right side. The sidebar should be much smaller than the main content (15% for example). For that purpose, I use the following HTML:

<div id="container">
  <div id="sidebar">
     Sidebar is here
  </div>
  <div id="content">
     Content
  </div>
</div>

And the corresponding CSS properties:

html, body{
  height: 100%;
}
#container{
  display: flex;
  height: 100%;
}
#sidebar{
  flex: 1;
  background-color: #cecece;
}
#content{
  flex: 1;
  background-color: green;
}

Now, the page is divided into 2 equal columns. If you want the sidebar to be smaller, you need to remove flex property on #sidebar and set its width to some value like this:

#sidebar{
  width: 100px;
  background-color: #cecece;
}

(JSFiddle: https://jsfiddle.net/8e7zk9ty/)

The content div will automatically fill up the remaining space. Do you find it much easier than using div and float? I have just created the layout for my website in less than 1 minute. The best thing about it is you do not have to specify the height of the sidebar, which is pretty hard with traditional CSS. The sidebar will automatically set its height to 100% as long as the container height is 100%.

4. Limitation

Flex is a property of CSS3 so do not expect it to work properly on all browsers. List of supported browsers is presented here: http://www.w3schools.com/css/css3_flexbox.asp. In addition, you might experience some cross-browser issues which might be a little bit tricky to resolve. I remember the time when working with flex, I got an issue related to the scrollbar on Firefox and it took me hours to figure out what was wrong.

5. References

To me, flex is a new concept and I have not used it before in any real projects. If you also have a similar experience, I suggest you read more about how to use flex, especially the first link has a very detailed explanation for you to get started with flex. There are still tons and tons of additional information about flex which I do not mention in this blog.