Flexbox
Flexbox(flexible box) is one-dimensional layout module that allows you to build layouts, align and distribute space among flex items inside flex container, regardless of their sizes. And Flexbox is meant to be used to build small-scale layouts and used to distribute space among components, and for large-scale-layouts Grid should be used. And the combination of Grid and Flexbox has become very powerful as with Grid you can build any complex layout while with Flexbox you can create simple layouts and use for to aligning items inside components.
And Flexbox solves the problem of building layouts with ease where before Flexbox came to the game, we have to build layouts with tables, floats, positioning all of which was not intended to build layouts and were quite painful to build layouts as we had to do hacks like clear fix and so on.
Flexbox can be used for
- Creating menus, navbars
- Equal columns
- Aligning input and button in the same row
- And more
Flexbox Core
So before learning about all the properties that are on flexbox, we should learn the core functionality of how flexbox works so that all flexbox properties that we use make sense and we can make better decisions when using flexbox. So have a look at the image below and I'm explaining each one of them in detail after that.
main-axis is like arrow and arrow by default points to right but we can change the direction of the arrow to left, bottom, top with flex-direction values
main-start & main-end - is where flex items are placed from main-start to main-end and direction of how flex items are placed changes based on flex-direction value. By default flex items are placed from left to right horizontally when flex-direction: row; in that case main-axis arrow points to the right. And flex items are placed from right to left horizontally when flex-direction: row-reverse; and main-axis arrow points to left in that case. And flex items are placed from top to bottom vertically when flex-direction: column; in that case main-axis arrow points to the bottom. And flex items are placed from bottom to top vertically when flex-direction: column-reverse; and in that case main-axis arrow points to top
main-size - is width/height of flex items based on the direction of main-axis
cross-axis can also consider as an arrow and by default, it points to the bottom but it changes to point to the right when flex-direction: column or column-reverse
cross-start & cross-end is how flex items are placed inside container. By default cross-axis arrow points to the bottom and in that mode, flex items are positioned from cross-start to cross-end vertically which is top to bottom but the direction of the cross-axis changes when flex-direction: column. And in that case flex items are placed horizontally from left to right
cross-size - is width/height of flex items based on the direction of cross-axis
flex-container is when the HTML element whose display property is set to flex thus become the container for flex items. NOTE: flex items can also be a flex container
flex-item is a flexible item when its direct parent's display property is set to flex
Flex Container Properties
There are types of properties that are available only on flex container ones that can be applied only on flex item itself. In this section, we are learning all major flex container properties.
Justify Content
So justify-content moves all flex items in the main-axis and the picture below you can how justify-content moves flex items on the main axis. And it has the following values
- flex-start - moves all flex items to the main-start of the flex container, and regardless of which side the main-axis arrow points to, flex items are always placed at the main-start of the container before other values in justify-content is used
- flex-end - moves all flex items to the main-end of flex container. And based on where the main-axis arrow points to, flex items could be placed on the right side, left side, topside, and bottom side of the flex container
- center - moves all flex items to the center of the main-axis
- space-between - creates equal space in between flex items but not any space in main-start and main-end of flex items
- space-around - creates equal space between flexbox items and half of that space in main-start and main-end of flex items
- space-evenly - creates equal space both in between flex items and in main-start and main-end of flex items
Align Items
So align-items moves flex items in cross-axis. As I've told you if flex-direction: row or row-reverse flex items are placed vertically top to bottom in the container but if flex-direction: column or column-reverse then flex items are positioned horizontally from left to right. And it few values that by using them we can align flex items in cross-axis. Please look at the picture below to have the visual mental image of how align-items work.
- stretch - is the default value in which flex items occupy available space in the cross axis
- flex-start - moves all flex items to cross-start of cross axis
- flex-end - moves all flex items to cross-end of cross axis
- center - moves flex items to the center of the cross axis
- baseline - moves the bottom of all flex items' content into the same line. This is especially useful when one of the flex items is larger than other flex items. So to put them in the same line we use this value.
Centering with Justify Content and Align Content
So instead of using all other hacks like transforming elements, positioning elements to center it inside the container. we can just use a combination of few flexbox declarations to center the element. It's that easy, look at the example below
.container {
display: flex;
justify-content: center;
align-items: center;
}
Flex Wrap
So basically setting flex-wrap other than no-wrap in flex container makes each flex item move to the next line as soon as its set width gets smaller. So have look at the picture below to make sense of it. And there are few values that I'm explaining in detail below
- no-wrap - is the default value and in that mode, even if flex items shrink they do not move to the new line.
- wrap - makes flex items starting from last to the first move to a new line as soon as their width starts to get smaller than the specified width. In wrap flex items that move to a new line earlier will be on the bottom of the flex items which move to a new line later
- wrap-reverse - makes flex items starting from last to the first move to the top of them when their width gets smaller. In wrap-reverse flex items that move to a new line earlier will be on the top of the flex items which move later to the new line
Flex Direction
So flex-direction changes the direction of the main axis (default one main-axis arrow points to the right). See the picture below to form a mental image of how this property works.
- row - is default and in that mode main-axis arrow points to right
- row-reverse - changes direction of main-axis to make it points to left
- column - makes main-axis arrow points to bottom
- column-reverse - sets main-axis arrow points to top
NOTE: So setting flex-direction: column or column-reverse when flex item's width is set width flex-basis, result in value declared in flex-basis applying to the height of the flex item when above-mentioned values applied to flex-direction. NOTE: this only applies for flex-basis not for other measurement units.
Flex Flow
So flex-flow is the way to define flex-direction and flex-wrap in a single declaration which is a cool way in my opinion. And they are defined like this.
.container {
display: flex;
flex-flow: row wrap;
}
Align Content
align-content has the same values as justify-content. But it only works when "flex-wrap wrap or wrap-reverse" is applied to the flex container and also when there is more than one line of flex items and is used to move flex items in the cross axis. Have a look at the picture below to get an idea of how it works. I'
- stretch - is the default value in which all flex items occupy available space in cross-axis
- flex-start - moves bunch of flex items to the cross-start of flex container
- flex-end - moves all flex items to the cross-end of flex container
- center - moves all flex items to the center of cross-axis
- space-between - creates equal space in between flex items but not any space in cross-start and cross-end of flex items
- space-around - creates equal space between flexbox items and half of that space in cross-start and cross-end of flex items
- space-evenly - creates equal space both in between flex items and in cross-start and cross-end of flex items
NOTE: ::fistline and ::firstletter don't work on flex containers
Flex Item Properties
Align Self
align-self overrides the declared value of align-items if it's set on the parent element or even if it's not applied, it moves individual flex item it's used on in cross-axis of the container. And all those values on align-items also apply the same to align-self. And have a look at the image below to have a visual mental image for this property
Flex Grow
flex-grow only accepts positive integers and it tells the available portion of container space(width) is distributed among sibling flex items. The higher the flex-grow value on a flex item, the more available space it occupies and the faster it'll grow relative to its sibling flex items. And for example, if one flex item has a flex-grow of 2 and other items have flex-grow 1, then it'll grow twice more than its sibling flex items.
Flex Shrink
flex-shrink also only accepts positive integers and works like flex-grow but instead of growing, it'll make flex item shrink. The higher value in flex-shrink has in flex item, the faster it'll shrink(gets smaller) relative to its sibling flex items.
Flex Basis
flex-basis defines starting width of flex items. This means is that before the viewport gets smaller, the width of the flex item will be what is defined in flex-basis but shrinks when the viewport gets smaller.
Flex
flex is cool property that is shorthand for defining flex-grow | flex-shrink | flex-base in single declaration. And by default values in flex is set to flex: 1 0 auto. Using flex-shrink | flex-base is an optional but you have to have flex-grow in it.
It's suggested to use this shorthand property instead of setting those 3 properties individually. As flex can intelligently set other properties.
Order
order accepts only integers and it changes the order of flex items in which flex items that have smaller value on their order property will be before all other flex items that have bigger value on their order property and flex items with the biggest value on order property that is used on them will be after all flex item that has smaller value for order property on them. And default order value in all flex items are 0 in which are placed in the source order in the container
NOTE: float, clear and vertical-align don't work on flex items.
Browser Support
You can check browser support for flexbox and its properties on this website. And If certain browsers don't support certain flexbox properties then include vendor prefixes of those browsers. Below a few of the major browser vendor prefixes.
- iOS: -webkit-
- Safari: -webkit-
- Firefox: -moz-
- Chrome: -webkit-
- Opera: -o-
- Internet Explorer & Microsoft Edge: -ms-
.container {
-webkit-display: flex;
-moz-display: flex;
-ms-display: flex;
-o-display: flex;
display: flex;
}
Projects to Built
So You've learned a lot about the core of the Flexbox and now it's time to practice what you've learned to cement it in your brain. So I recommend building a few projects below. I recommend you to do push yourself to do those projects on your own without looking at their source code
- Built Youtube navbar
- Built projects in link
- Built one or two projects in here or more if you want to
Websites For Exercising
- Flexbox froggy
- Freecodecamp flexbox section
Resources to dive deeper
Summary
- So you've learned the fundamentals of Flexbox
- You can now implement Flexbox on your projects to build flexible layouts
- PRACTISE PRACTISE PRACTISE to internalize what you've learned
- Next article is going to be about Grid