Flexbox

Written by Craig Godden-Payne

On February 26, 2018

Reading this will take about 14 minutes.


More posts like this

I found myself doing some front end work, after months of backend and migration work. I felt a bit rusty when it came to layouts, and although using a prebuilt grid system is all good, i wanted to go back over layouts in general, and some more modern parts such as flexbox and grid.

Layouts are important if you more than just one big column of content. Its important to support a variety of devices and sizes nowadays, so just having one column isnt great, because you end up with really long content on wide screens, and on small screens, you tend to have to scroll sideways a lot, which isnt very user friendly.

I must admit that most of the time, I rely on a grid system to lay out my content, but sometimes you need something that is a bit more strict, there are issues with grid systems, such as spacing between columns when content reaches a certain size, which makes it not the best solution. I must say I probably should have learnt flexbox well before now, (I’m sure I’ve used it before, following an example online, but I must admit I never really learnt it properly!)

Layouts in css are controlled by the display property. Most elements have a default of block or inline (also referred to as inline element and block element). But some have none (such as script or link blocks). When positioning content the main you can use are Block, Inline, Table (for two-dimensional table data) and Positioned, for explicit position of an element.

Flexbox makes it easier to design flexible responsive layout structure without having to use floats or positioning.

Flexblox is now widely supported, and is compatible with the following

A flexbox layout consists of a parent element, with one or more child elements.

When setting the display type to flex, and no other settings, it works similar to inline-block.

You get access to the following properties when working with flexbox, and here is a bit of a description of what each does:

flex-direction which direction the container wants to stack the items.
flex-wrap if, and how, the container wants its children to wrap
flex-flow shorthand property for setting both the flex-direction and flex-wrap properties
justify-content aligns the items
align-items aligns the items vertically (the opposite axis of the justify-content property)
align-content aligns the item rows

When you have child elements within a flexbox layout, they become flexible items, and you can assign flex properties to them.

order sorts the items in the specified order
flex-grow specifies how much a flex item will grow relative to the rest of the flex items
flex-shrink specifies how much a flex item will shrink relative to the rest of the flex items
flex-basis specifies the width of a flex item
flex shorthand property for the flex-grow, flex-shrink, and flex-basis properties
align-self overrides the default alignment set by the container’s align-items property

This, in my opinion is such much easier than fighting (sometimes it feels like that) with various combinations of a grid system, divs using various inline / inline-block and fudging designs to make them look similar, but never 100% right.

Here are a few example of using flexbox

1
2
3
<style>
.flex-container1 {
  display: flex;
  background-color: yellow;
}

.flex-container1 > div {
  background-color: white;
  margin: 10px;
  padding: 10px;
}
</style>

<div class="flex-container1">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
</div>

1
2
3
<style>
.flex-container {
  display: flex;
  align-items: stretch;
  background-color: yellow;
}

.flex-container > div {
  background-color: white;
  width: 5rem;
  margin: 10px;
  padding: 10px;
  text-align: center;
}
</style>
<div class="flex-container">
  <div style="flex-grow: 1">1</div>
  <div style="flex-grow: 8">2</div>
  <div style="flex-grow: 1">3</div>
</div>

Here is an example of building something like an article, with author content without having to rely on a grid system.

I have emphasized the borders, so you can see where the content divs lay

Title of article

Some Content

And some of it is on a second line.

<style>
.flex-row2 {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  width: 50%;
}
.flex-row2 img {
  width:6rem;
  height:6rem;
}

.flex-container2 {
  display: flex;
  justify-content: center;
  flex-direction: column;
}
.flex-container2 > div {
  background-color: white;
  margin: 0;
}
</style>
<div class="flex-row2">
  <div>
    <img src="/assets/avatar.jpg">
  </div>
  <div class="flex-container2">
    <div>
      <h3>Title of article</h3>
    </div>
    <div>
      <p>Some Content</p>
      <p>And some of it is on a second line.</p>
    </div>
  </div>

You can also create really nice looking image grids, which isn’t the easiest thing to do without flexgrid


<style>
* {
    box-sizing: border-box;
}

.row {
    display: flex;
    flex-wrap: wrap;
    padding: 0 4px;
}

.column {
    flex: 25%;
    max-width: 25%;
}
.column img {
    vertical-align: middle;
    width:100%;
}

@media (max-width: 800px) {
    .column {
        flex: 50%;
        max-width: 50%;
    }
}
@media (max-width: 600px) {
    .column {
        flex: 100%;
        max-width: 100%;
    }
}
</style>
<div class="row"> 
  <div class="column">
    <img src="http://via.placeholder.com/100x80"/>
    <img src="http://via.placeholder.com/100x30"/>
    <img src="http://via.placeholder.com/100x110"/>
  </div>
  <div class="column">
    <img src="http://via.placeholder.com/100x50"/>
    <img src="http://via.placeholder.com/100x20"/>
    <img src="http://via.placeholder.com/100x50"/>
    <img src="http://via.placeholder.com/100x90"/>
  </div>
  <div class="column">
      <img src="http://via.placeholder.com/100x50"/>
      <img src="http://via.placeholder.com/100x50"/>
      <img src="http://via.placeholder.com/100x50"/>
      <img src="http://via.placeholder.com/100x60"/>
  </div>
  <div class="column">
    <img src="http://via.placeholder.com/100x50"/>
    <img src="http://via.placeholder.com/100x60"/>
    <img src="http://via.placeholder.com/100x110"/>
  </div>
</div>

*One thing to look out for…

The default behaviour of flexbox is to squash elements on a single line. This usually means if you have an image it will appear distorted. If you are expecting elements to wrap, like they would using other display types, make sure the flex-wrap is set to wrap


element {
  flex-wrap: wrap;
}

Written on February 26, 2018.

Please share and spread the word!

More posts like this