how to flexbox like a real gamer

hi kids today we are going to learn to flexbox and ascend to the coveted status of amateur web developer

firstly, we need to make a flex container to do flexbox things with. thankfully, that's easy.

use css to give an element the property and value of display: flex;.
preferably, you would do this to a <div>, but lots of other things work too.


example:
.flex-container {
display: flex;
width: 70vw;

margin: auto;
padding: 2em;
background-color: #BBBBFF;
}

here is a div with this fancy new container class.


you may notice there's nothing different, and that's because we haven't put anything in it yet.
in fact, even if we do put something in it, nothing seems to be special about it.

boo! this is boring!

believe it or not, it is working behind the scenes. first, let's make a special class to demonstrate the power of flex.
most developers create a generic flex item class, which they can then build upon later.

.flex-item {
background-color: #CCCCCC;
max-height: 1em;
margin: 1em;
padding: 1em;
font-size: 1.5em;
}

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

flex item 1
flex item 2
flex item 3


okay, that makes them look nicer, but you can do this with regular divs and tables. what's so special here?
try resizing your browser window to see how the flex items interact.

the flex items grow and shrink to fit the container. neat, but there's a couple problems with this. for instance, if you shrink the container too much, the items will spill outside! that doesn't look too good. they're also aligned to the left of the box, which might not be very desirable.

fortunately, this is where the main draw of flex comes into play. flexboxes makes it easy to design website layouts, without having to resort to floating, positioning, or other techniques that don't scale super well across devices. flexboxes excel in liquid, responsive design, which is an essential consideration for modern web development.




FLEX CONTAINER PROPERTIES

let's adjust our css to rectify the problems mentioned earlier.
first up is flex-wrap, which defines how to handle flex items exiting the container.
by default, flex-wrap is set to nowrap. let's change that.


.flex-container {
display: flex;
width: 70vw;
min-height: 40vh;
margin: auto;
padding: 2em;
background-color: #BBBBFF;

flex-wrap: wrap;
}

flex item 1
flex item 2
flex item 3

more about flex-wrap
flex-wrap also supports the value wrap-reverse, which puts the wrapped items above the others as opposed to below.
note the items moving to the bottom of the container, which can be rectified with align-items as described below.

flex-wrap: wrap-reverse;

flex item 1
flex item 2
flex item 3


now, when the container is too small to fit the whole row, the container will grow and the items will wrap around to fit. good stuff.
let's try tackling that item alignment using justify-content. by default, this is set to flex-start. let's change it to center and see what happens.


.flex-container {
display: flex;
width: 70vw;
min-height: 40vh;
margin: auto;
padding: 2em;
background-color: #BBBBFF;
flex-wrap: wrap;

justify-content: center;
}


flex item 1
flex item 2
flex item 3

more about justify-content
justify-content additionally supports the values flex-end, space-around, and space-between.

justify-content: flex-end;

this value orients the items towards the end of the container.
flex item 1
flex item 2
flex item 3

justify-content: space-around;

this value acts like center, but places space between the items in addition to before and after.
notice that any wrapped items are centered.
flex item 1
flex item 2
flex item 3

justify-content: space-between;

this is similar to space-around, but only puts space between the elements, not before or after.
notice that wrapped items are not centered.
flex item 1
flex item 2
flex item 3


nice and centered. beautiful. but only horizontally. what if we want them to be centered vertically as well, because we're insane?
have no fear! we also have align-items at our disposal. by default, this is set to stretch, which stretches out the items to fit the container, like so:

(you may have noticed that the earlier demonstrations don't act like this. i've secretly been hiding an align-items: flex-start; property from you this whole time, which prevents the content from stretching, like you see here.)

flex item 1
flex item 2
flex item 3

this doesn't look great, which is why we have an align-items: flex-start; property on the above demonstrations.
however, we can also set it to flex-start, flex-end, or for our purposes, center.


.flex-container {
display: flex;
width: 70vw;
min-height: 40vh;
margin: auto;
padding: 2em;
background-color: #BBBBFF;
flex-wrap: wrap;
justify-content: center;

align-items: center;
}


flex item 1
flex item 2
flex item 3

more about align-items
here's a demonstration of the flex-end value.

align-items: flex-end;

flex item 1
flex item 2
flex item 3


align-items also supports the value baseline, which aligns the elements based on the text baseline.
see how the bottom of the text in the items are all lined up.

align-items: baseline;

flex item 1
flex item 2
flex item 3

behold! easy vertical alignment, while still being responsive and liquid in nature! bask in its glory! this is how you center a div.




FLEX ITEM PROPERTIES

let's play around a little with the items themselves, as opposed to their container.

the order property allows you to change the order that the flex items appear in.
by default, this is just the order that they are listed inside the HTML file, but this property outprioritizes that.


<div class="flex-container">
<div class="flex-item">flex item 1</div>
<div class="flex-item" style="order: 3;">flex item 2</div>
<div class="flex-item">flex item 3</div>
</div>

flex item 1
flex item 2
flex item 3

(note: not every element in the container needs this property in order to work!)

here's a more useful one: flex-grow. this specifies how much an individual item will grow lengthwise to fit the container.

(default value is 0)
<div class="flex-container">
<div class="flex-item">flex item 1</div>
<div class="flex-item">flex item 2</div>
<div class="flex-item" style="flex-grow: 1;">flex item 3</div>
</div>

flex item 1
flex item 2
flex item 3


this works great for making certain elements stand out, or to just look nicer. likewise, there is a flex-shrink property which has the opposite effect.

remember align-items? here's align-self, which applies to an individual item as opposed to every item in the container.
this value overrides the align-items value of the container. otherwise, it functions exactly like align-items.
<div class="flex-container">
<div class="flex-item">flex item 1</div>
<div class="flex-item">flex item 2</div>
<div class="flex-item" style="align-self: stretch;">flex item 3</div>
</div>

flex item 1
flex item 2
flex item 3

more about align-self
here's a demonstration of the other values align-self offers.
flex-start
center
flex-end


now your layouts can be even more confusing and inconsistent! hooray!



CONCLUSION

flexboxes are a very powerful tool. they are used to quickly and easily create liquid, responsive design layouts. they provide ease of use, simplicity, and extra flexibility when designing a web page. using them correctly, they will never conflict with your existing css, and require such minimal setup to use that even a caveman could do it. i've hardly scraped the surface of what you can do with flexbox. you can also use it with media queries, @keyframes, and more. it's amazing what they can do. with practically universal support, obscene extensibility, and amazing ease of integration, you're pretty much shooting yourself in the foot for not using them. try them out sooner or later.





WICKED SICK EXTRA CREDIT


the example on kuzmaclass.org uses a special container id to produce the effect. this takes a different approach, instead using an entirely new flex item class, which i think would end up being a bit more flexible, since it's not tied to the original class. also i'm not sure the original example uses transitions. but who cares, funny box go weee

.flex-item-extra {
background-color: #CCCCCC;
margin: 0.25em;
padding: 1em;
font-size: 1.5em;
flex-grow: 1;
border: 0.2em solid black;
transition: flex-grow 0.3s, background-color 0.3s, color 0.3s;
}

.flex-item-extra:hover {
flex-grow: 5;
background-color: #333333;
color: #FFFFFF;
}

wow!!!
they move!!!
that's cool!!!