CSS - tutorial - 12 - flexbox

Revision:


Content

CSS flexbox layout module CSS flex container CSS flex items CSS flex responsive CSS flexbox properties CSS flexbox gaps CSS flex-basis inline-flex


CSS flexbox layout module

top

CSS flexbox layout module: before the Flexbox layout module, there were four layout modes:

1/ block, for sections in a webpage,
2/ inline, for text,
3/ table, for two-dimensional table data,
4/ positioned, for explicit position of an element

The flexible box layout module makes it easier to design flexible responsive layout structure without using "float" or "positioning". Flexbox is used to arrange elements in one direction either in x(row) or y(column). Without using of "floats" we can arrange a number of elements in container.

Flexbox elements: to start using the Flexbox model, you need to first define a flex container.

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                </div>
                <style>
                    .flex-container { display: flex; background-color: DodgerBlue; height:10vw; width: 30vw;}
                    .flex-container > div{ background-color: #f1f1f1; margin: 10px; padding: 20px; font-size: 30px;}
                </style>
            

A flexible layout must have a "parent element" with the "display property"set to flex or inline-flex.

Direct "child element(s)"" of the flexible container automatically becomes flexible items.


CSS flex container

top

The parent element (flex container) becomes flexible by setting the "display property" to flex or inline-flex. The flex container properties are: flex-direction, flex-wrap, flex-flow, justify-content, align-items, align-content.

The "flex-direction" property defines in which direction the container wants to stack the flex items. It is used to arrange all the elements inside the container in one direction (either row or column).

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container1">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                </div>
                <style>
                    .flex-container1 { display: flex; background-color: DodgerBlue; flex-direction: column; width: 30vw; height: 20vw;}
                    .flex-container1 > div{ background-color: #f1f1f1; width: 100px; margin: 10px; padding: 20px; font-size: 30px;}
                </style>
            

The "column" value stacks the flex items vertically (from top to bottom):

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container2">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                </div>
                <style>
                    .flex-container2 { display: flex; background-color: DodgerBlue; flex-direction: column-reverse; width: 30vw; height: 20vw;}
                    .flex-container2 > div{ background-color: #f1f1f1; width: 100px; margin: 10px; padding: 20px; font-size: 30px;}
                </style> 
            

The "column-reverse" value stacks the flex items vertically (but from bottom to top):

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container3">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                </div>
                <style>
                    .flex-container3 { display: flex; background-color: DodgerBlue; flex-direction: row-reverse; width: 30vw; height: 5vw;}
                    .flex-container3 > div{ background-color: #f1f1f1; width: 100px; margin: 10px; padding: 20px; font-size: 30px;}
                </style>
            

The "flex-direction: row-reverse;" stacks the flex items horizontally (but from right to left).

The "flex-wrap" property specifies whether the flex items should wrap or not. Flex wrap will allow to arrange automatically all elements inside the container on available space by setting {flex-wrap: wrap;}.

The examples below have 15 flex items, to better demonstrate the flex-wrap property.

examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                <div style="margin-left: 2vw;" class="flex-container4">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                    <div>4</div>
                    <div>5</div>
                    <div>6</div>  
                    <div>7</div>
                    <div>8</div>
                    <div>9</div>  
                    <div>10</div>
                    <div>11</div>
                    <div>12</div>  
                    <div>13</div>  
                    <div>14</div>  
                    <div>15</div>  
                </div>
                <style>
                    .flex-container4 {  display: flex; flex-wrap: wrap; background-color: DodgerBlue; width: 30vw; height: 30vw;}
                    .flex-container4 > div { background-color: #f1f1f1; width: 100px; margin: 10px; text-align: center; line-height: 75px;} 
                </style>
            

Try to resize the browser window

The "nowrap" value specifies that the flex items will not wrap (this is default), while the "wrap-reverse" value specifies that the flexible items will wrap if necessary, in reverse order.

The "flex-flow" property is a shorthand property for setting both the "flex-direction" and "flex-wrap" properties.

examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                <div style="margin-left: 2vw;" class="flex-container5">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                    <div>4</div>
                    <div>5</div>
                    <div>6</div>  
                    <div>7</div>
                    <div>8</div>
                    <div>9</div>  
                    <div>10</div>
                    <div>11</div>
                    <div>12</div>  
                    <div>13</div>  
                    <div>14</div>  
                    <div>15</div>  
            </div>
            <style>
                .flex-container5 { display: flex; flex-flow: row wrap;  background-color: DodgerBlue; width: 30vw; height: 30vw;}
                .flex-container5 > div { background-color: #f1f1f1; width: 100px; margin: 10px; text-align: center; font-size: 30px; font-size: 30px;}
            </style>
            

Try to resize the browser window

The "justify-content" property is used to align the flex items vertically or in x direction.

The "center" value aligns the flex items at the center of the container.
The "flex-start" value aligns the flex items at the beginning of the container (this is default).
The "flex-end" value aligns the flex items at the end of the container.
The "space-around" value displays the flex items with space before, between, and after the lines.
The "space-between" value displays the flex items with space between the lines:

The "align-items" property is used to align the flex items horizontally or in y direction.

The "center" value aligns the flex items in the middle of the container.
The "flex-start" value aligns the flex items at the top of the container.
The flex-end" value aligns the flex items at the bottom of the container.
The "stretch" value stretches the flex items to fill the container (this is default).
The "baseline" value aligns the flex items such as their baselines aligns.

examples

1

2

3

4
                <div style="margin-left: 2vw;" class="flex-container6">
                    <div><h1>1</h1></div>
                    <div><h6>2</h6></div>
                    <div><h3>3</h3></div>  
                    <div><small>4</small></div>  
                </div>
                <style>
                    .flex-container6 { display: flex; height: 200px; align-items: baseline; background-color: DodgerBlue; width: 30vw; }
                    .flex-container6 > div { background-color: #f1f1f1; width: 100px; margin: 10px; text-align: center; line-height: 75px;  font-size: 30px;}
                </style>
            

Note: the example uses different font-size to demonstrate that the items gets aligned by the text baseline.

The "align-content" property is used to align the flex lines. It is used to align items horizontally or in y direction (for more elements).

The "space-between" value displays the flex lines with equal space between them.
The "space-around" value displays the flex lines with space before, between, and after them.
The "stretch" value stretches the flex lines to take up the remaining space (this is default).
The "center" value displays the flex lines in the middle of the container.
The "flex-start" value displays the flex lines at the start of the container.
The "flex-end" value displays the flex lines at the end of the container.

examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                <div style="margin-left: 2vw;" class="flex-container7">
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>  
                    <div>4</div>
                    <div>5</div>
                    <div>6</div>  
                    <div>7</div>
                    <div>8</div>
                    <div>9</div>  
                    <div>10</div>
                    <div>11</div>
                    <div>12</div>  
                    <div>13</div>  
                    <div>14</div>  
                    <div>15</div>  
                </div>
                <style>
                .flex-container7 { display: flex; height: 20vw; flex-wrap: wrap; align-content: space-between; background-color: DodgerBlue;}
                .flex-container7 > div { background-color: #f1f1f1; width: 4vw; height: 3vw; margin: 1vw; text-align: center; line-height: 2vw; font-size: 2vw;}
                </style>
            

Perfect centering: set both the "justify-content" and "align-items" properties to center, and the flex item will be perfectly centered.

examples
                <div style="margin-left: 2vw;" class="flex-container8">
                    <div></div>
                </div>
                <style>
                .flex-container8 { display: flex; justify-content: center; align-items: center; height: 20vw; background-color: DodgerBlue;}
                .flex-container8 > div { background-color: #f1f1f1; color: white; width: 10vw; height: 10vw;}
                </style>
            

CSS flex items

top

The direct child elements (items) of a flex container automatically become flexible (flex) items. The flex item properties are: order, flex-grow, flex-shrink, flex-basis, flex, align-self.

The"order" property specifies the order of the flex items. The first flex item in the code does not have to appear as the first item in the layout. The "order" value must be a number, default value is 0. The "order" property can change the order of the flex items:

examples
1
2
3
4
                <div style="margin-left: 2vw;" class="flex-container9">
                    <div style="order: 3">1</div>
                    <div style="order: 2">2</div>
                    <div style="order: 4">3</div> 
                    <div style="order: 1">4</div>
                </div>
                <style>
                    .flex-container9 { display: flex; align-items: stretch; background-color: #f1f1f1; width: 30vw; height: 10vw;}
                    .flex-container9>div { background-color: DodgerBlue; color: white; width: 100px;  margin: 10px; text-align: center;  
                        line-height: 75px; font-size: 30px;}
                </style>
            

The"flex-grow" property specifies how much a flex item will grow relative to the rest of the flex items. The value must be a number, default value is 0. On default, the item takes the width or flex-basis value. With value 1 or greater than 1, it tries to fill the parent element(if space is available).

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container10">
                    <div style="flex-grow: 1">1</div>
                    <div style="flex-grow: 1">2</div>
                    <div style="flex-grow: 8">3</div>
                </div>
                <style>
                    .flex-container10 { display: flex; align-items: stretch; background-color: #f1f1f1; width: 30vw; height: 10vw;}
                    .flex-container10 > div{background-color: DodgerBlue; color: white; margin:10px; text-align: center; line-height:75px; 
                        font-size: 30px;}
                </style>
            

The property makes the third flex item grow eight times faster than the other flex items.

The "flex-shrink" property specifies how much a flex item will shrink relative to the rest of the flex items. The value must be a number, default value is 1. When the parent element's total width is lesser than the width of the children elements, it starts to shrink the element(s). If value equals 0, it doesn't shrink the element(s).

examples
1
2
3
                <div style="margin-left: 2vw;" class="flex-container10A">
                    <div style="flex-shrink: 1">1</div>
                    <div style="flex-shrink: 0">2</div>
                    <div style="flex-shrink: 2">3</div>
                </div>
                <style>
                    .flex-container10A { display: flex; align-items: stretch; background-color: #f1f1f1; width: 30vw; height: 10vw;}
                    .flex-container10A > div{ background-color: DodgerBlue; color: white; margin: 10px; text-align: center; 
                        line-height: 75px; 
                        font-size: 30px;}
                </style>
            

The"flex-basis" property specifies the initial length of a flex item. It sets the initial size of the child element. In the example here below: set the initial length of the third flex item to 200 pixels.

examples
1
2
3
4
                <div style="margin-left: 2vw;" class="flex-container11">
                    <div>1</div>
                    <div>2</div>
                    <div style="flex-basis:200px">3</div>
                    <div>4</div>
                </div>
                <style>
                    .flex-container11 { display: flex; align-items: stretch; background-color: #f1f1f1; width: 30vw; height: 10vw;}
                    .flex-container11 > div { background-color: DodgerBlue; color: white; width: 100px; margin: 10px; text-align: center; 
                        line-height: 75px; 
                        font-size: 30px;}
        
                </style>
            

The "flex" property is a shorthand property for the flex-grow, flex-shrink, and flex-basis properties.

The "align-self" property specifies the alignment for the selected item inside the flexible container. The align-self property overrides the align-items property of the container.

examples
2
3
4
code:
                <div style="margin-left: 2vw;" class="flex-container12">        
                    <div>2</div>
                    <div style="align-self: center">3</div>
                    <div>4</div>
                </div>
                <style>
                    .flex-container12 {  display: flex; height: 200px; background-color: #f1f1f1; width: 30vw; height: 20vw;}
                    .flex-container12 > div { background-color: DodgerBlue; color: white; width: 100px; margin: 10px; text-align: center; 
                        line-height: 75px;
                        font-size: 30px;}
                </style>
            

The "align-self: center;" aligns the selected flex item in the middle of the container.


CSS flex responsive

top

Responsive flexbox: a way to create different layouts for different devises is to change the percentage of the "flex" property of the flex items.

Note that we also have to include "flex-wrap: wrap;" on the flex container for this example to work.

examples
1
2
code:
                <div style="margin-left: 2vw;" class="flex-container13">        
                    <div class="flex-item-left">1</div>
                    <div class="flex-item-right">2</div>
                </div>
                <style>
                    .flex-container13 {display: flex; flex-direction: row; font-size: 2vw; text-align: center; width: 30vw; height: 10vw;}
                    .flex-item-left{background-color: #f1f1f1; padding: 1vw; flex: 50%; }
                    .flex-item-right{background-color:dodgerblue; padding: 1vw; flex:50%;}
                    /* responsive layout - one column-layout instead of two-column layout*/
                    @media (max-width: 800px){
                        .flex-container13{ flex-direction: column}
                    }
                </style>
            

Note that we also have to include "flex-wrap: wrap;" on the flex container for this example to work.

examples
1
2
                <div style="margin-left: 2vw;" class="flex-container14">        
                    <div class="item-left">1</div>
                    <div class="item-right">2</div>
                </div>
                <style>
                    .flex-container14 {display: flex; flex-wrap: nowrap; font-size: 2vw; text-align: center; width: 30vw; height: 10vw;}
                    .item-left{background-color: #f1f1f1; padding: 1vw; flex: 50%;}
                    .item-right{background-color:dodgerblue; padding: 1vw; flex: 50%;}
                    /* responsive layout - one column-layout instead of two-column layout*/
                    @media (max-width: 800px){
                        .flex-container14{flex-wrap: wrap;}
                        .item-left, .item-right{flex: 100%;}
                    }
                </style>
            

CSS flexbox properties

top

The following table lists the CSS properties used with flexbox:

display - specifies the type of box used for an HTML
flex-direction - specifies the direction of the flexible items inside a flex container
justify-content - horizontally aligns the flex items when the items do not use all available space on the main-axis
align-items - vertically aligns the flex items when the items do not use all available space on the cross-axis
flex-wrap - specifies whether the flex items should wrap or not, if there is not enough room for them on one flex line
align-content - modifies the behavior of the flex-wrap property. It is similar to align-items, but instead of aligning flex items, it aligns flex lines
flex-flow - a shorthand property for flex-direction and flex-wrap
order - specifies the order of a flexible item relative to the rest of the flex items inside the same container
align-self - used on flex items. Overrides the container's align-items property
flex - a shorthand property for the flex-grow, flex-shrink, and the flex-basis properties.


CSS flexbox gaps

top

Browser support for this CSS feature is improving. You can now start using "gap", "row-gap", and "column-gap" to create space in layouts created with grid, flexbox, and multi-column layouts.

examples
            .boxes {
                display: flex;
                gap: 12px;
            }    
        

CSS flex-basis

top

The flex-basis CSS property sets the initial main size of a flex item. It sets the size of the content box unless otherwise set with box-sizing.

In case both "flex-basis" (other than auto) and "width" (or "height" in case of flex-direction: column) are set for an element, flex-basis has priority.

If the element is not a flexible item, the flex-basis property has no effect.

syntax: flex-basis: content | <width>

syntax examples

        /* Specify <'width'> */
        flex-basis: 10em;
        flex-basis: 3px;
        flex-basis: 50%;
        flex-basis: auto;

        /* Intrinsic sizing keywords */
        flex-basis: max-content;
        flex-basis: min-content;
        flex-basis: fit-content;

        /* Automatically size based on the flex item's content */
        flex-basis: content;

        /* Global values */
        flex-basis: inherit;
        flex-basis: initial;
        flex-basis: revert;
        flex-basis: revert-layer;
        flex-basis: unset;
    

values

'width': any of the following units:

length : sets an absolute value;
percentage : sets a percentage of the width or height of a containing block's content area;
auto : uses the value of the width in horizontal writing mode, and the value of the height in vertical writing mode; when the corresponding value is also auto, the content value is used instead;
max-content : sets the intrinsic preferred width;
min-content : sets the intrinsic minimum width;
fit-content : sets the maximum possible size of a containing block's content area, bounded by the min-content and max-content values, and calculated based on the content of the current element.

content: indicates automatic sizing, based on the flex item's content.

examples
  • 1: flex-basis test
  • 2: flex-basis test
  • 3: flex-basis test
  • 4: flex-basis test
  • 5: flex-basis test
  • 6: flex-basis test
code;
                    <div>
                        <ul class="container-x">
                            <li class="flex flex1">1: flex-basis test</li>
                            <li class="flex flex2">2: flex-basis test</li>
                            <li class="flex flex3">3: flex-basis test</li>
                            <li class="flex flex4">4: flex-basis test</li>
                            <li class="flex flex5">5: flex-basis test</li>
                        </ul>
                        
                        <ul class="container-x">
                            <li class="flex flex6">6: flex-basis test</li>
                        </ul>
                    </div>
                    <style>
                        .container-x {font-family: arial, sans-serif; margin: 0; padding: 0; list-style-type: none; display: flex;flex-wrap: wrap;}
                        .flex {background: #6ab6d8; padding: 1vw; margin-bottom: 5vw; border: 0.2vw solid #2e86bb; color: white; font-size: 0.8vw;
                            text-align: center; position: relative;}
                        .flex::after {position: absolute; z-index: 1; left: 0; top: 100%; margin-top: 1vw; width: 100%; color: #333; font-size: 0.8vw;}
                        .flex1 {flex-basis: auto;}
                        .flex1::after {content: "auto";}
                        .flex2 {flex-basis: max-content;}
                        .flex2::after {content: "max-content";}
                        .flex3 {flex-basis: min-content;}
                        .flex3::after {content: "min-content";}
                        .flex4 {flex-basis: fit-content;}
                        .flex4::after {content: "fit-content";}
                        .flex5 {flex-basis: content;}
                        .flex5::after {content: "content";}
                    </style>
                

inline-flex

top

inline-flex tells browsers to display the selected HTML element as an inline-level flexible box model. In other words, setting an element's "display property's" value to inline-flex turns the box model into an inline-level flexbox.

{display: inline-flex} does not make "flex items" display inline. It makes the "flex container" display inline. That is the only difference between "{display: inline-flex}" and "{display: flex}"".

example
            section {
                display: inline-flex;
                background-color: orange;
                margin: 10px;
                padding: 7px;
            }
        

The snippet above used the inline-flex value to convert the HTML document's <section> elements from regular <section> nodes to inline-level flexible box models.

Converting an HTML node to a flexible box model makes the element's direct children become flexible items. The '{display: inline-flex}" directive only affects a box model and its direct children. It does not affect grandchildren nodes.