Here are five, higher-level thoughts which have helped me wrap my head around flexbox. (Note: I'll refer to flex containers as parents, and flex items as children.)
1. The parent is the commander of positioning the children
This is a shift in thought process. The "old" way of doing layout used floats, positing, and display properties on the children to position them within the parent.
2. The parent has a horizontal and vertical axis
justify-* properties distribute children along the horizontal axis, and
align-* properties distribute children on the vertical axis.
However, you can switch things up with the flex-direction property.
For example, you can flip the axes by using
flex-direction: column. Now, any
justify-* properties you use will distribute children along the vertical axis.
So whenever you are using
justify-* properties or
align-* properties, make sure you know which flex-direction is being used.
3. A child can be a parent, can be a child, can be a parent...
Any flex item can be a parent of other flex items. Infinity flexbox nesting!
4. Ordering is up to the children
They can stand in line wherever they want and defy the HTML source order. Such rebels!
5. "Flex" is not just a display value, it's also a property
This is the hardest part of flexbox to grasp (for me at least). The flex property is shorthand for
flex-basis. (Just like margin is shorthand for
flex property, you can have some children take up more space than others, depending on the space available. Also, you can have some items stop flexing, while their siblings continue to flex.
This comes in handy for items like fixed-width sidebars next to flexible content, or fixed-height, sticky headers and footers.
I have found if I keep these five thoughts in mind while using flexbox, I can come up with solutions more efficiently rather than throwing a bunch of properties and values around haphazardly until something works.