Official website for Web Designer - defining the internet through beautiful design
FOLLOW US ON:
Author: Steve Jenkins
20th August 2013

Responsive layouts with Flexbox

Say goodbye to media queries and say hello to the ‘The Flexible Box Layout Module’ for creating powerful responsive layouts

Responsive layouts with Flexbox

Flexbox or ‘The Flexible Box Layout Module’, to give its official title, has had quite a colourful history given its short lifespan. Flexbox is a completely new way to think about layout. It has been designed from the ground up to be a superior alternative to using floats and bending CSS to our layout whims in ways the original authors never intended. It was conceived with web applications and the advanced sorts of responsive layouts that we’ve become accustomed to.

First introduced in 2009, it’s already been through three revisions – each supported to varying degrees by browsers. We’re going to be covering the latest version, released in September 2012. The W3C recommend its use and outside of Internet Explorer (only version ten supports the June 2012 syntax) it enjoys 76.52 per cent browser support. Additionally, Chrome announced that it was going to unprefix the properties, which is great news as it will now be joining Firefox and Opera. The fundamental changes Flexbox brings to CSS can be daunting at first but this tutorial will guide you through building your first responsive Flexbox site and show you just how easy it is.

DOWNLOAD TUTORIAL FILES

Box sizing

We’ll start by adding box-sizing: border-box; to all of our elements. This causes padding to be included within the calculated width of an element – so if you have two elements with 50 per cent width and 1em of padding they will sit nicely beside each other. The only browsers that have issues with this are <IE8.

001  * {
002     -webkit-box-sizing: border-box;
003     -moz-box-sizing: border-box;
004     box-sizing: border-box;    
005     margin: 0;
006     padding: 0;
007  }

Flex it

Here we come to the core of the module. To declare an element as a Flexbox element we simply add display: flex. Unfortunately this isn’t straightforward if you want to cover all possible bases – if you are supporting the buggy implementations then you’ll have to add a few more – but the following will cover all modern browsers.

001 .flex 
002 {
003     display: -ms-box;
004     display: -webkit-flex;
005     display: flex;
006 }

Navigation HTML

Our aim is to create a stripped down version of the Wikipedia homepage, exclude all content and leave nothing but the bare boxes. The difference will come in how easily we can adjust this to different widths (hint: it’s not called flex for nothing). We’ll start with the navigation on the left-hand column.

001  <nav class=”site-navigation flex”>
002     <ul>
003        <li>Home</li>
004        <li>About</li>
005        <li>Contact</li>
006    </ul>
007 </nav>

Containers and items

Flex elements have a host of properties available to them. There are two important distinctions to make: flex containers and flex items. Containers are the elements with display: flex; the immediate children are known as flex items. We’ll add some basic properties here to visually separate the navigation.

001 .site-navigation 
002 {
003     background: lightblue;
004     margin-right: 1em;
005     padding: 1em;
006 }

Flex columns

The following properties position the flex items vertically (by using column), while the default layout is to display them horizontally (known as row). Each flex item will be positioned vertically along the ‘main axis’ (explained in the diagram). The main axis is the x axis in flex-direction: row and along the y axis in flex-direction: column.

001 .site-navigation {
002    -webkit-flex-direction: column;
003    -ms-flex-direction: column;
004    flex-direction: column;
005 }

Flex property

The flex property is shorthand (like margin: 0 1em 2em 0; instead of margin-right) for flex-grow, flex-shrink, and flex-basis, ie how much you want it to grow/shrink compared to its siblings and how wide it should ideally be. If there is a flex of 2, it will shrink/grow at twice the rate.

001 .site-navigation {
002    -webkit-flex: 1 13em;
003    -ms-flex: 1 13em;
004    flex: 1 13em;
005 }

Self-alignment

Flex items have a property of their own called align-self which allows specific items to be aligned separate to its siblings. In this instance we want the navigation to sit with the natural flow (left on left-to-right languages and right on right-to-left languages) but the logo to sit centrally – while still maintaining its flexibility.

001 .site-navigation .logo {
002    -webkit-align-self: center;
003    -ms-flex-item-align: center;
004    align-self: center;
005 }
006 nav ul {
007    list-style: none;
008 }

Main markup

We’ve concentrated on the navigation layout, now let’s turn our attention to the rest of the design. The great thing about this is the navigation will stretch the entire height of the page without any JavaScript or absolute positioning. We’ll also use the HTML 5.1 element Main to signify the main content for the page.

001 <main role=”main” class=”flex”>
002    <!– nav –>
003    <section>
004        <header>
005            <h1>I am a header, I rule all below     me.</h1>
006        </header>
007        <!– next step –>
008    </section>
009 </main>

Flexible elements

We’ll place this inside the section tag – the markup is fairly typical of a content pod that has a heading, some text, and an image. We’ll repeat this twice so we have two articles side by side and a third beneath them both spanning the entire width. Certain browsers require margin: auto to ensure images sit correctly.

001 <div class=”flex”>
002    <article>
003        <h2>Header</h2>
004        <p>Lorem ipsum</p>
005        <figure>
006            <img src=”http://placekitten.        com/g/500/500” alt=”A cute kitten.”>
007            <figcaption>A cute kitten.</        figcaption>
008        </figure>
009     </article>
010     <!– repeated –>
011  </div>

Article flexing

Next we want our articles to sit side-by-side but not have a defined width, so they sit nicely in the parent element. To do this without resorting to floats we use the shorthand flex property again; this is the equivalent of saying that both items should grow and shrink at the same rate as each other.

001    section article {
002    -webkit-flex: 1;
003    flex: 1;
004    padding: 1em 1em 0 0;
005    }

Responsive images

There’s just one last technique before we get into building its responsive layout.  By setting a maximum width of 100 per cent on all images used, we  are ensuring that they will never spill over their container. This doesn’t really beat serving the right size images in the first place, but with fluid layouts that change on orientation and resize this isn’t always possible and can be difficult.

001 img {
002     max-width: 100%;
003 }

Media query

Just in case you’re not familiar with media query syntax, we’re telling the browser that only devices with screens with a maximum width of 50ems (this equates to 800 pixels given a base font size of 16px on the body element) should apply the following rules:

001 @media only screen and (max-width: 50em) { /*     800/16 */
002     /* next step */
003 }

Adjusting articles

Next we’ll use the nth-child selector to select the first article and tell it to flex, or grow, at twice the rate of its sibling. Using this simple property we can expand items that may be of more importance at different widths. In this case, the first article will take precedence.

001 section article:nth-child(1) {
002     -webkit-flex: 2;
003     -ms-flex: 2;
004     flex: 2;
005 }

Small screen widths

Our next breakpoint will be at 40em (which equates to 640 pixels with our base font size) and deliver our single column layout. Although 640 pixels is a common breakpoint it’s important to add breakpoints when it feels right for the content to change, not just because certain devices adhere to it.

001 @media only screen and (max-width: 40em) { 002 /*     640/16 */
003     body {
004        padding: 0 1em;
005     }
006     /* next steps */
007 }

Changing direction

In one fell swoop we can convert our entire layout to a single column that is optimised for smaller widths. By changing the flex-direction we change the main axis (the one that flex items are aligned across) from horizontal to vertical which causes it  to behave as though all our elements with the class of flex have display: block on them.

001 .flex 
002    {
003     -webkit-flex-direction: column;
004     -ms-flex-direction: column;
005     flex-direction: column;
006 }

Change flex basis

Remember that the flex property is shorthand for flex-grow, flex-shrink, and flex-basis? Now the navigation is stretching downwards with a height of 13em but we want it to simply be the height of it’s contents (auto). There’s no IE10 equivalent to flex-basis so it’ll look slightly larger unless you manually set a height.

001 .site-navigation {
002     margin-right: 0;
003     -webkit-flex-basis: auto;
004     flex-basis: auto;
005 }

A new order

We’re going to move the navigation list before the logo. One of the most exciting things about Flexbox is that it can move where items are on the page without having to use JavaScript to move elements around. This is easily done by changing the order property – but it must be a positive integer, so no 1.1 or -13 values.

001 .site-navigation ul {
002     -webkit-order: 1;
003     -ms-flex-order: 1;
004     order: 1;
005 }

Moving the logo

All items have an order of 0 unless specified so we’ll change the order property on our logo to move it beneath the navigation. Note that IE10 uses the older syntax so has a slightly different property name. That’s all there is to it! You should now see the logo dip beneath the navigation on small-screen widths.

001 .site-navigation .logo 
002 {
003     -webkit-order: 2;
004     -ms-flex-order: 2;
005     order: 2;
006 }

Adding boxes

We’ve made some big blocky elements flex and bend to our layout but we haven’t looked at the items within them much. They’re capable of flexing just as much as their container and there’s some very easy ways to accomplish complex layouts. First we’ll create some coloured boxes to play with.

001 .small-box {
002     width: 6.25em; height: 6.25em;
003     border: 0.0625em solid;
004     background: #E74C3C;
005 }
006
007 <div class=”justify”>
008     <div class=”small-box”></div>
009 </div>

Justifying placement

We want our boxes to sit neatly alongside each other with an even amount of spacing between them, no matter what the widths. We could do something complicated with margins and percentages, or we could just use the justify-content property with a value of space-between – another useful value is space-around.

001 .justify {
002     display: -webkit-flex;
003     display: -ms-box;
004     display: flex;
005     -webkit-justify-content: space-between;
006     -ms-flex-pack: justify;
007     justify-content: space-between;
008 }

Inline flexing

We’re basically done with our responsive layout but there’s another important display value to cover: inline-flex. Like other inline elements, this will collapse its width to that of its items. Applying it to our justify class causes the boxes to sit next to each other as justify-content doesn’t have extra space to distribute them.

001 .justify {
002     display: -webkit-inline-flex;
003     display: -ms-inline-box;
004     display: inline-flex;
005 }

Bi-directional

Flexbox is a powerful tool that can be used to develop complex layouts using relatively little CSS. Browser support isn’t brilliant but it is getting there. One final bonus, it all switches direction so if your users read right-to-left then your layout can easily accommodate it thanks to it’s direction agnosticism.

001 body {
002    direction: rtl;
003 }

  • Tell a Friend
  • Follow our Twitter to find out about all the latest web development, news, reviews, previews, interviews, features and a whole more.
    • http://www.joomkb.com/ Keybrowsse

      Now a days most of the people need responsive website. Because it has more flexible. So your post giving great information. thanks for sharing useful article.