How to Create Complex Layouts in Ionic 1.x

8 min read

Originally published May 18, 2015

Check out my advanced Ionic tutorials at

Before [switching to Ionic][1], I used [Sencha Touch][2] which has a completely different layout system. Layouts in Sencha Touch are built almost completely with Javascript, and I've previously written about [how to create complex layouts in Sencha Touch][3].

[Ionics][4] layout system looks like something you would expect from a typical grid based CSS framework like [Bootstrap][5] or [Foundation][6] – but it's not quite as complex. Unlike Sencha Touch, you will use HTML and CSS to build layouts in Ionic which might look something like this:

<div class="row">
  <div class="col-20"></div>

  <div class="col-25"></div>

  <div class="col-20 col-offset-10"></div>

Each new row is added vertically and each column divides the row horizontally. Columns come with a range of available percentage based widths in the form of **col-_ and you can also simply just specify col to space them evenly. The **col-offset-** classes allow you to offset where the column is placed, for example:

col-20 col-offset-10```

Would create a column **20% wide** and it would give it a **margin to the left of 10%**. Here's a list of available classes for columns, each of these can also be used as offsets:

Class Width
col-10 10%
col-20 20%
col-25 25%
col-33 33.3333%
col-34 33.3333%
col-50 50%
col-66 66.6666%
col-67 66.6666%
col-75 75%
col-80 80%
col-90 90%
The post I linked above about [creating a complex layout in Sencha Touch][3] is a good example to follow – it walks through creating a reasonably common and useful interface that falls outside of the usual **sliding menu** or **tabbed menu** approach that is available by default in Ionic. So we will recreate that same layout again in Ionic, this is what we're aiming for: [
Complex Layout Example
][7] This layout has a header area to place branding, and 6 icons beneath it that will serve as navigation to various parts of the application. In this example we will just be creating the layout itself, not the navigation as well. ### 1. Create a new Ionic project Create a new blank Ionic project by running the following command:
ionic start IconHomeScreen blank```

and also **enable SASS** in the project by first changing your directory into the project you just created:

cd IconHomeScreen```

and running:

ionic setup sass```

### 2. Understand how Ionic's layout system works

To really understand Ionics layout system (which is a grid system), you need to understand the [CSS Flexible Box Layout][8] or "**Flexbox**". Flexbox is a reasonably new W3C specification that creates a way to align and distribute elements within a container **even when the size of the container is unknown**. A flex container will **expand** and **shrink** items as necessary to best fill the available space and it can be used both horizontally and vertically. It is not yet widely used as it is not supported by all browsers, but since Ionic isn't intended to run in all browsers it's free to make use of this fancy new spec!

I recommend taking a look at [this article][8] for a more in depth explanation of the concepts of the flexbox layout, but I will talk through the basics as we go.

A **flex container** has a **direction** which is either row (left to right), row-reverse (right to left), column (top to bottom) or column-reverse (bottom to top). For example, in the layout we are aiming to create we are creating a series of rows stacked vertically, so we would define our **flex container** as follows:

.home-container {
  display: -webkit-flex;
  -webkit-flex-direction: column;

So each row we add to the container will go under the last. This is the default behaviour of rows added in Ionic anyway, but we will discuss why we're creating this container class in just a little bit.

A **flex item** goes inside of a **flex container** and will follow the "rules" of its parent. In our case the flex items are our rows and cols that live inside of our container. We can specify the **flex** of individual items which is a ratio of how much space they should occupy compared to everything else. The following is an image from the [Sencha Touch layout tutorial][3] which demonstrates the concept of "flex":

Complex Layout Example
][9] Ignore the rest because some of it is irrelevant to this tutorial, but focus on the "flex" attributes in the diagram above. If you add the flex of the header area and the three icon areas you get **9**. The header area has a flex of **3** so it takes up 3/9ths (or 1/3rd) of the total available space and each of the icon rows will take up 2/9ths of the total space. Alter the flex values and you alter the distribution of the space that gets taken up by each item. ### 3. Add the layouts HTML To create the layout pictured above, we need to add some rows and columns to our HTML. * Open up your **index.html** file and make the following changes: ```javascript
``` If you run **ionic serve** now, the result will look like this: [
Ionic Layout 1
][10] Close, but not really what we want. Everything is all squished up the top, but we want it to expand to fit all the available space vertically too. To achieve this we're going to have to add a container around our content and apply some CSS styling to it. We also want to change the flex values of the header and icon containers too so we will add some CSS classes to identify them. * Open up your **index.html** file and make the following changes: ```javascript
``` ### 4. Add the CSS styles Now we need to add the CSS styles to make our flexbox layout behave the way we want it to. First, we will define the behaviour of our container. * Open up **scss/** and add the following classes: ```javascript .home-container { display: -webkit-flex; -webkit-flex-direction: column; height: 100%; } .home-container > .row { -webkit-flex: 1; } ``` Now our **flex items** that are added to this container will **flow from top to bottom**, and since we've given the container a height of 100% it will fill the whole screen (causing the items within the container to expand to fit as well). We've also defined a default flex of '1' for all rows inside of the **home-container**. If everything has a flex of '1' then everything will be **evenly spaced**. If everything has a flex of '2' everything will be evenly spaced as well, it is only when a **different flex** is supplied that it is noticeable. Now we're going to do exactly that. * Add the following classes to your **** file: ```javascript .header { -webkit-flex: 1.5 !important; -webkit-align-items: center; background-color: #1abc9c; } .icon-row { -webkit-align-items: center; } ``` Now we've given the header area a flex of 1.5, this means it will be slightly larger (50% larger) than an individual icon row which will only have a flex of 1. Play around with some different flex values on both classes to see the effect. We are also aligning the contents of the header and icon rows to the center and changing the background colour of the header. The end result looks like this: [
Ionic Layout 2
][11] Which looks pretty much exactly like our diagram. The Flexbox layout is a tricky thing to get your head around, but even this reasonably simple example demonstrates how powerful it can be. If you want to learn more about Flexbox, again, I encourage you to [read this article][8] and I would also encourage you to poke around through the Ionic documentation to see what other [CSS goodies Ionic provides][12]. [1]: [2]: [3]: [4]: [5]: [6]: [7]: [8]: [9]: [10]: [11]: [12]: