Flexbox
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
<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>
<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
![](/assets/avatar.jpg)
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.