Making Layouts Easy With CSS Flexbox: Flex-Item Properties
Tags: css, webdev, design, flexbox
Published: 2021-05-24 08:28:58

# What is Flexbox CSS?
> ***It is a responsive design layout that distributes elements within their parent container, even if the size of items is unknown or dynamic (hence the term "flex")***.


* In the [previous post](https://dev.to/bharati21/css-flexbox-making-layout-design-easy-part-1-24l5), I covered all the properties that are applied to the parent flex container item.

* To reiterate, ***these are the properties applied to flex container (parent)***:
  1. display
  2. flex-direction
  3. flex-wrap
  4. flex-flow
  5. justify-content
  6. align-items
  7. align-content
     * For detailed explanation, go through [this post](https://dev.to/bharati21/css-flexbox-making-layout-design-easy-part-1-24l5).  


In this post, we will go through the properties that are applied to flex items (children of flex parent container).


> You can check out the entire demo here: https://demo-flexbox.netlify.app/

> You can check out the entire code here: https://github.com/bharati-21/Flexbox-CSS


<hr />

# BASICS
* Before explaining the properties applied to flex items, there are a few concepts that determine how much space a flex item occupies in it's container.
* ***POSITIVE AND NEGATIVE FREE SPACE***
  * **Positive Free Space**: The extra space available when the flex container has more than required space to display flex items within the container. 
     * This space can be distributed among the items so as to occupy the entire container.
  * **Negative Free space**: Opposite of *positive free space*, this is when the space required by flex items combined is more than the flex container can accommodate. 
     * This space can be removed from flex-items so as to occupy the exact size of the container.

* When the `flex-direction: row`, the size of flex items is determined by their width. 
* When the `flex-direction: column`, the size of flex items is determined by their height.


## PROPERTIES APPLIED TO FLEX ITEMS (CHILDREN)
* Following are the properties applied to flex items:
  1. order
  2. flex-basis
  3. flex-grow
  4. flex-shrink
  5. flex
  6. align-self

* Let's use the following code to demonstrate how each of these properties work:
    ```html
     <div class="flex-container">
        <div class="flex-item" id="item-1">1</div>
        <div class="flex-item" id="item-2">2</div>
        <div class="flex-item" id="item-3">3</div>
        <div class="flex-item" id="item-4">4</div>
        <div class="flex-item" id="item-5">5</div>
     </div>
    ```


<hr/>

1. ***order***
   - By default, all the flex items are displayed in the order of HTML source code.
   - The order of flex-items appearing within the container can be modified using the ***order*** property.
   - The default order for every flex items is: **0**.
   - ***This property takes a number that specifies the order, and items are placed accordingly from the items having lowest order values first***. 
   - Order can be a **negative value**, which becomes useful when one item needs to be placed before other items.
   - If more than one item is assigned the same order value, then within that group, items are placed according to HTML source order.
       ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfrut4vub2o2mh582ohd.png)
       <pre>
       ```css
       .flex-item {
           order: 0; // default
       }
       #item1 {
           order: 4;  
       }
       
       ```
       </pre>
     * In the above image, the first container shows the original order of elements as per HTML source code.
     * This order is altered using the ***order*** property in the second container and a code snippet is shown above.
       * Each of the flex items are displayed from lowest to highest values of ***order***. (3 < 2 < 4 < 5 < 1)
       * Notice how 2 and 4 have the same ***order*** and are displayed according to HTML source order.




2. ***flex-basis***
   - This property specifies the initial size of the flex item before positive space in the container is distributed among the items.
   - The default value of this property is **auto**, meaning the browser looks at the height/ width of the flex item or the max-content size (in supporting browsers) to distribute space.
   - It also takes value **content**, which specifies that the flex-item should occupy space within the container based on it's content. 
      - _This is a newer implementation and has less browser support_. 
   - The property also accepts an absolute value for its length. For e.g. 1rem, 200px, 15% etc.
   - ***flex-basis*** can also be set to **0**: This is same as specifying `width: 0;`. Hence the flex item will be collapsed to its smallest possible size based on the content.
     ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ae5jqdswja8gbjda381u.png)
       <pre>
       ```css
       .flex-item {
           flex-basis: auto; // default is auto
       }
       #item3 {
           flex-basis: 200px;
       }
       ```
       </pre>
       * In the above image, container 1 shows the default case when `flex-basis: auto;`.
         * The flex items are auto-sized and in supporting browsers, the flex items are set to initial size based on their content.
       * The second container has flex items set to varying ***flex-basis*** values using absolute values.
       * A code snippet for the example is shown above.



3. ***flex-grow***
   * This property dictates the factor by which a flex item _grows_ relative to other items in the container when the positive space is filled.
   * The default value for ***flex-grow*** is **0**. The extra space remains unoccupied.
   * If the same ***flex-grow*** value is set for all the items, the positive space in the container is _equally distributed_.
   * It takes a ***positive value*** which defines the relative growth factor.
   * The positive value is a ratio and could be any number: 2, 200, 50 or 1.5.
       ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gf0e775g2nej4xnspovj.png)
       <pre>
       ```css
          #container2 > .flex-item {
              flex-grow: 1;
          }
          #container3 > #item1 {
              flex-grow: 3; 
          }
       ```
       </pre>
   * In the image above, the first container depicts the default case where, `flex-grow: 0;`.
   * In the second container, all the flex items are set the same `flex-grow: 1;` value. 
     * Hence the positive space is distributed to all the items and they _grow_ equally 
   * In the third container, each of the flex-items are set with different ***flex-grow*** value, and hence their growth varies.
   * ***NOTE:*** flex-grow deals with the situation where the container has more space than required to fit the flex items. 
       * Hence, it **adds** space to the flex items to fit to the container.
    

4. ***flex-shrink***
   * This property indicates the relative factor by which a flex item _shrinks_ when negative space is distributed among items in a container.
   * The default value for this property is **1**, which specifies the browser to shrink the item by a factor of its ***flex-basis***.
   * This property takes a ***positive value***, and flex items are shrunk accordingly by and do not overflow the container.
   * When all the flex items are provided the same flex-shrink ratio, they shrink and the negative space is evenly distributed among them.
   * When ***flex-shrink*** is set to **0**, none of the items shrink and overflow if the size of the container is smaller than all the items.
   * Similar to ***flex-grow***, ***flex-shrink*** takes a value which is a relative factor and could be any positive number: 2, 200, 50 or 1.5.
      ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oes466cr9dcqm910yakt.png)
      <pre>
       ```css
       #container2 > .flex-item {
           flex-shrink: 0;   // default is 1
       }
       #container3 > #item5 {
           flex-shrink: 2.5; 
       }
       ```
       </pre>
   * In the image above, the first container depicts the default case where, `flex-shrink: 1;`.
   * In the second container, all the flex items are set to `flex-shrink: 0;`, and the items overflow the container. 
   * In the third container, each of the flex-items are set with different ***flex-shrink*** values, and hence the factor by which they shrink varies.
     * A code snippet for the example in the image is shown above.
   * ***NOTE:*** flex-shrink deals with situations where the initial flex-basis value of all flex-items is greater than the available space in the flex-container. 
       * Hence, it **takes away** the space from flex items to fit the container. 
     
 
5. ***flex***
   * This is a shorthand property that combines ***flex-grow***, ***flex-shrink***, and ***flex-basis***.
   * The flex-shrink and flex-basis values are _optional_ in this property.
   * This property can take values in the following manner:
     * ***flex-initial***: `flex: 0 1 auto | 0 auto; //default`
          * This makes the flex item partially flexible. 
          * ***flex-basis*** is set to auto and items are auto-sized if there is no main-size (width/ height) specified.
          * Item shrinks by a factor of 1 if the container cannot accommodate the flex items, but the item does not grow if there is positive space to be filled
     * ***flex-auto***: `flex: auto | 1 1 auto;`
          * This sets the ***flex-basis*** based on initial height/ width properties, but the item is flexible and grows or shrinks when necessary.
          * This property can take positive values other than 1.
     * ***flex-none***: `flex: none| 0 0 auto;`
          * This sets the ***flex-basis*** based on initial height/ width properties, but the item is inflexible and **does not** grow or shrink.
          * Hence items overflow if the container size is not enough to fit the items.
   * ***flex*** can also take values accepted by the individual properties.
       ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6om0zuxzhoiirudnx6b.png)
       <pre>
       ```css
       #container1 > .flex-item {
            flex: 0 1 auto;  // default is flex-initial
       }
       #container2 > .flex-item {
            flex: 1 1 auto;   
       }
       #container3 > .flex-item {
            flex: 0 0 auto;   
       }
       ```
       </pre>
       * The above code snippet shows the cases ***flex-initial***, ***flex-auto*** and ***flex-none*** explained above and shown in the image (first three containers in the image).
      <pre>
       ```css
       #container4 > .flex-item {
            flex: <flex-grow>;
            flex: <flex-basis>;
            flex: <flex-grow> <flex-basis>;
            flex: <flex-grow> <flex-shrink>;
            flex: <flex-grow> <flex-shrink> <flex-basis>;
       }
       ```
       </pre> 
       * ***flex*** can also take combination of ***flex-grow***, ***flex-shrink*** and ***flex-basis*** values as shown in the code snippet above and last container in the image.
      


6. ***align-self***
   * This property controls the alignment of a flex item along the cross-axis.
   * It overrides the ***align-items*** value for a specific flex item
   * ***align-self*** accepts all the values assigned to align-items plus value of **auto** which is the default.
   * The following are the values accepted by the property"
      * ***auto***: (default) inherits the ***align-items*** value of the parent property.
      * ***stretch***: stretches the cross-size of the flex item to fit the entire cross axis of the container 
      * ***flex-start***: flex item is placed at the start of cross axis (cross-start)
      * ***flex-end***: flex item is placed at the end of cross axis (cross-end)
      * ***center***: flex item is placed in the center of cross axis
      * ***baseline***: flex item is aligned such that the baselines of items displayed as `align-self: baseline;` are aligned. 
   * [Check out this post to understand align-items, cross-axis, cross-size and baselines](https://dev.to/bharati21/css-flexbox-making-layout-design-easy-part-1-24l5)
      ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u78dco246j8l4jgxs0rc.png)
      <pre>
      ```css
      #item1 {
          align-self: auto; // default
      }
      #item2 {
          align-self: flex-start;
      }
      #item3 {
          align-self: flex-end;
      }
      #item4 {
          align-self: center;
      }
      #item5, #item6 {
          align-self: baseline;
      }
      ```
      </pre>
     * The above code snippet aligns the flex items within the container as shown in the image above.
       * Since **stretch** is the ***align-items*** value for the parent property, the first flex item set to **auto**, inherits this value and stretches across the column.
       * Notice how baselines for flex items 5 and 6 are aligned. 


<hr/>

Thank you for reading the part 2 of the blog on CSS Flexbox series. 

> You can check out the entire demo here: https://demo-flexbox.netlify.app/

> You can check out the entire code here: https://github.com/bharati-21/Flexbox-CSS
***In the next blog, I will focus on common use cases and scenarios where CSS Flexbox is used.***

Do leave a thumbs up, save and pin this blog if it helped you in understanding the properties applied to flex items. 
Hopefully you might now be able to use these concepts in creating better layouts.

Cheers!