Practical application of flexbox. Things to remember. Main axis direction: flex-direction
About how easy it is to work with Flexbox using the example of the layout of a news site template.
Believe me, there is no need for detailed analysis all aspects of working with Flexbox if you want to start using it now. In this tutorial, the author is going to introduce you to some of the properties of Flexbox and create a “news layout” like the one you might have seen on The Guardian website.
The reason why the author uses Flexbox is the large number of possibilities it provides:
- ease of creating adaptive columns;
- creating columns same height;
- the ability to press the contents to the bottom of the container.
Let's go!
1. Start by creating two columns
Creating columns using CSS has always been challenging. For a long time, floats and/or tables were (and are) widely used to perform this task, but each of these methods had (and has) its drawbacks.In turn, Flexbox simplifies this process, having a number of advantages such as:
Writing cleaner code: all we have to do is create a container with a rule display: flex;
- flexibility: we can resize, stretch and align columns by changing a couple of lines of CSS;
- semantic markup;
- in addition, using Flexbox there is no need to cancel the wrapping to avoid unpredictable layout behavior.
Let's get started by creating two columns, one of which will take up 2/3 of the width of our container, and one of which will take up 1/3 of it.
There are two elements here:
Container columns;
- two child elements column, one of which has an additional class main-column, which we will use later to make the column wider.
Columns ( display: flex; ) .column ( flex: 1; ) .main-column ( flex: 2; )
Because the main-column has a flex value equal to 2
, then this column will take up twice as much space as the second one.
Let's add a little visual design and, in the end, we get:
Click to see in action
2. Make each column a flexbox container
Each of the two columns will contain several vertically arranged articles, so from these two elements we, in turn, must also make flexbox containers.So, we need the articles:
Positioned vertically inside the container column;
- took up all available space.
Rule flex-direction: column specified for the container, along with the rule flex: 1 specified for the child element allows the article to fill everything free place vertically, while the height of the first two columns will remain unchanged.
Click to see in action
3. Making a container from an article
Now, to expand our capabilities even further, let's represent each article as a flexbox container. Each such container will contain:Title;
- paragraph;
- information panel with the author’s name and number of comments;
- some kind of adaptive picture.
Here we use Flexbox to push the information bar to the bottom of the element. Here, look at the result we expect to get.
And here is the code itself:
.article ( display: flex; flex-direction: column; flex-basis: auto; /* Sets the initial size of the element depending on its content */ ) .article-body ( display: flex; flex: 1; flex-direction: column; ) .article-content ( flex: 1; /* The content fills the remaining space, thereby pushing the infobar to the bottom */ )
Elements inside an article are arranged vertically due to the use of a rule flex-direction: column.
We also applied the property flex: 1 to element article-content, thereby stretching it to all available space and pressing article-info to the bottom. The height of the columns in this case does not matter.
Click to see in action
4. Add several nested columns
In fact, we need the left column to include several more columns. Therefore, we need to replace the second element responsible for the article with a container columns, which we used earlier.
Since we want the first nested column to be wider, we'll add the class to the element nested-column, and in CSS we indicate:
Nested-column ( flex: 2; )
Now this column will be twice as wide as the second one.
Click to see in action
5. Making the first article with a horizontal layout
Our first article is actually big. In order to effectively use the space on the monitor screen, let's change its orientation to horizontal.First-article ( flex-direction: row; ) .first-article .article-body ( flex: 1; ) .first-article .article-image ( height: 300px; order: 2; padding-top: 0; width: 400px)
Property order plays a big role in this case because it allows you to change the order of HTML elements without changing the HTML markup. In fact, article-image in the code it comes before the element article-body, but behaves as if he is standing after him.
Click to see in action
6. Making an adaptive layout
Now everything looks the way we wanted, albeit a little squished. Let's fix this by adding flexibility to our layout.One of the great things about Flexbox is that you can simply delete a rule display:flex in the container in order to completely disable it (Flexbox), while the rest of its properties (such as align-items or flex) will remain working.
As a result, we can activate the adaptive layout by using Flexbox only when necessary.
So we're going to delete display:flex from selectors .columns And .column, instead "packing" them into a media query:
@media screen and (min-width: 800px) ( .columns, .column ( display: flex; ) )
That's all! On screens with a low resolution, all articles will be located on top of each other, and on screens with a resolution of over 800 pixels - in two columns.
7. Adding finishing touches
To make the layout look more attractive on big screens, let's add some CSS tweaks:@media screen and (min-width: 1000px) ( .first-article ( flex-direction: row; ) . first-article . article-body ( flex: 1; ) . first-article . article-image ( height: 300px ; order: 2; padding-top: 0; width: 400px; .main-column (flex: 3; .nested-column (flex: 2; )
The content of the first article is aligned horizontally: the text is on the left side, and the image is on the right. Also, the main column is now wider (75%). The same goes for the nested column (66%).
And here is the final result!
Click to see in action
Conclusion
Now you can see for yourself that you can use Flexbox in your projects without even delving into all its intricacies, and the created layout is a clear example of this. At least, the author really hopes so.CSS flexbox (Flexible Box Layout Module)- flexible container layout module - is a way of arranging elements, based on the idea of an axis.
Flexbox consists of flexible container And flexible items. Flexible elements can be arranged in a row or column, and the remaining free space is distributed between them in various ways.
The flexbox module allows you to solve the following tasks:
- Arrange elements in one of four directions: left to right, right to left, top to bottom, or bottom to top.
- Override the display order of elements.
- Automatically size elements so that they fit into the available space.
- Solve the problem with horizontal and vertical centering.
- Move items inside a container without overflowing it.
- Create columns of the same height.
- Create pressed to the bottom of the page.
Flexbox solves specific problems - creating one-dimensional layouts, for example, a navigation bar, since flex elements can only be placed along one of the axes.
What is flexbox
Browser support
IE: 11.0, 10.0 -ms-
Firefox: 28.0, 18.0 -moz-
Chrome: 29.0, 21.0 -webkit-
Safari: 6.1 -webkit-
Opera: 12.1 -webkit-
iOS Safari: 7.0 -webkit-
Opera Mini: 8
Android Browser: 4.4, 4.1 -webkit-
Chrome for Android: 44
1. Basic concepts
![](https://i1.wp.com/html5book.ru/wp-content/uploads/2015/06/box-model.png)
A specific set of terms is used to describe a Flexbox module. The flex-flow value and recording mode determine the correspondence of these terms to the physical directions: top / right / bottom / left, axes: vertical / horizontal, and dimensions: width / height.
Main axis— the axis along which flex elements are laid out. It extends into the main dimension.
Main start and main end— lines that define the start and end sides of the flex container, relative to which flex elements are laid out (starting from main start towards main end).
Main size) - the width or height of the flex container or flex items, depending on which of them is in the main dimension, determines the main size of the flex container or flex item.
Cross axis- axis perpendicular to the main axis. It extends in the transverse dimension.
Cross start and cross end— lines that define the starting and ending sides of the transverse axis, relative to which flex elements are laid out.
Cross size— the width or height of a flex container or flex items, whichever is in the cross dimension, is their cross dimension.
![](https://i0.wp.com/html5book.ru/wp-content/uploads/2019/02/flexbox-mode.jpg)
2. Flex container
A Flex container sets a new flexible formatting context for its content. A flex container is not a block container, so for child elements CSS properties such as float , clear , vertical-align do not work. Also, the flex container is not affected by the column-* properties that create columns in the text and the pseudo-elements::first-line and::first-letter .
The flexbox layout model is associated with a certain value CSS display properties of a parent HTML element containing child blocks. To control elements using this model, you need to set the display property as follows:
Flex-container ( /*generates a block-level flex container*/ display: -webkit-flex; display: flex; ) .flex-container ( /*generates a line-level flex container*/ display: -webkit-inline-flex; display: inline-flex)
After setting these property values, each child element automatically becomes a flex element, lining up in one row (along the main axis). In this case, block and inline child elements behave the same, i.e. The width of the blocks is equal to the width of their content, taking into account the internal margins and borders of the element.
![](https://i2.wp.com/html5book.ru/wp-content/uploads/2015/06/display-flex.png)
If the parent block contains text or images without wrappers, they become anonymous flex items. The text is aligned to the top edge of the container block, and the height of the image becomes equal to the height of the block, i.e. it is deformed.
3. Flex elements
Flex items are blocks that represent the contents of a flex container in a flow. The Flex container establishes a new formatting context for its content, which causes the following features:
- For flex items, their display property value is locked. display value: inline-block; and display: table-cell; evaluated in display: block; .
- Empty space between elements disappears: it does not become its own flex element, even if the inter-element text is wrapped in an anonymous flex element. An anonymous flex item's content cannot be styled, but will inherit styles (such as font options) from the flex container.
- An absolutely positioned flex element does not participate in the flex layout layout.
- The margins of adjacent flex elements do not collapse.
- Percentage margin and padding values are calculated from the internal size of the block containing them.
- margin: auto; expand, absorbing additional space in the corresponding dimension. They can be used to align or push adjacent flex items.
- Auto minimum size flex items default to the minimum size of their content, i.e. min-width: auto; . For scrollable containers, the automatic minimum size is usually zero.
4. Flex Item Display Order and Orientation
The contents of a flex container can be laid out in any direction and in any order (rearranging flex items within the container only affects visual rendering).
4.1. Main axis direction: flex-direction
The property refers to the flex container. Controls the direction of the main axis along which flex items are stacked, in accordance with the current writing mode. Not inherited.
flex-direction | |
---|---|
Values: | |
row | The default value is left to right (in rtl, right to left). Flex elements are laid out in a row. The start (main-start) and end (main-end) of the main axis direction correspond to the start (inline-start) and end (inline-end) of the inline-axis. |
row-reverse | The direction is from right to left (in rtl from left to right). Flex elements are laid out in a line relative to the right edge of the container (in rtl - the left). |
column | Direction from top to bottom. Flex elements are laid out in a column. |
column-reverse | Column with elements in reverse order, down up. |
initial | |
inherit |
![](https://i2.wp.com/html5book.ru/wp-content/uploads/2015/06/flex-direction.png)
Syntax
Flex-container ( display: -webkit-flex; -webkit-flex-direction: row-reverse; display: flex; flex-direction: row-reverse; )
4.2. Managing multi-line flex container: flex-wrap
The property determines whether the flex container will be single-line or multi-line, and also sets the direction of the cross axis, which determines the direction in which new lines of the flex container will be laid.
By default, flex items are stacked on one line, along the main axis. If they overflow, they will extend beyond the bounding box of the flex container. The property is not inherited.
![](https://i0.wp.com/html5book.ru/wp-content/uploads/2015/06/flex-wrap.png)
Syntax
Flex-container ( display: -webkit-flex; -webkit-flex-wrap: wrap; display: flex; flex-wrap: wrap; )
4.3. A short summary of direction and multi-line: flex-flow
The property allows you to define the directions of the main and transverse axes, as well as the ability to move flex elements, if necessary, onto several lines. This is a shorthand for the flex-direction and flex-wrap properties. Default value flex-flow: row nowrap; . the property is not inherited.
Syntax
Flex-container ( display: -webkit-flex; -webkit-flex-flow: row wrap; display: flex; flex-flow: row wrap; )
4.4. Display order of flex items: order
The property defines the order in which flex items are displayed and arranged within a flex container. Applies to flex items. The property is not inherited.
Initially all flex items have order: 0; . When you specify a value of -1 for an element, it is moved to the beginning of the timeline, and a value of 1 is moved to the end. If multiple flex items have the same order value, they will be rendered according to the original order.
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-order: 1; order: 1; ) Rice. 6. Display order of flex items
5. Flexibility of flex elements
The defining aspect of a flex layout is the ability to "flex" flex items, changing their width/height (depending on what size is on the main axis) to fill the available space in the main dimension. This is done using the flex property. A flex container distributes free space among its children (proportional to their flex-grow ratio) to fill the container, or shrinks them (proportional to their flex-shrink ratio) to prevent overflow.
A flex element will be completely "inflexible" if its flex-grow and flex-shrink values are zero, and "flexible" otherwise.
5.1. Setting flexible dimensions with one property: flex
The property is shorthand for the flex-grow, flex-shrink, and flex-basis properties. Default value: flex: 0 1 auto; . You can specify one or all three property values. The property is not inherited.
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex: 3 1 100px; -ms-flex: 3 1 100px; flex: 3 1 100px; )
5.2. Growth factor: flex-grow
The property determines the growth rate of one flex element relative to other flex elements in the flex container when distributing positive free space. If the sum of the flex-grow values of flex items in a row is less than 1, they take up less than 100% of the free space. The property is not inherited.
![](https://i0.wp.com/html5book.ru/wp-content/uploads/2015/06/box-model.png)
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-grow: 3; flex-grow: 3; )
5.3. Compression ratio: flex-shrink
The property specifies the compression ratio of a flex item relative to other flex items when distributing negative free space. Multiplied by the flex-basis base size. Negative space distributed proportionally to how much the item can shrink, so for example a small flex item won't shrink to zero until the flex item is noticeably smaller bigger size. The property is not inherited.
![](https://i2.wp.com/html5book.ru/wp-content/uploads/2015/06/flex-shrink.png)
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-shrink: 3; flex-shrink: 3; )
5.4. Basic size: flex-basis
The property sets the initial base size of a flex item before allocating free space according to flex factors. For all values except auto and content , the base flex size is defined the same as width in horizontal writing modes. Percentage values are defined relative to the size of the flex container, and if no size is specified, the value used for flex-basis is the dimensions of its contents. Not inherited.
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-flex-basis: 100px; flex-basis: 100px; )
6. Alignment
6.1. Main axis alignment: justify-content
The property aligns flex items along the main axis of the flex container, distributing the free space unoccupied by flex items. When an item is converted to a flex container, flex items are grouped together by default (unless they have margins set). Gaps are added after calculating the margin and flex-grow values. If any elements have a non-zero flex-grow or margin: auto; , the property will have no effect. The property is not inherited.
Values: | |
flex-start | Default value. Flex elements are laid out in a direction starting from the starting line of the flex container. |
flex-end | Flex elements are laid out in the direction coming from end line flex container. |
center | Flex items are aligned to the center of the flex container. |
space-between | Flex elements are distributed evenly along the line. The first flex item is placed flush with the edge of the start line, the last flex item is placed flush with the edge of the end line, and the remaining flex items on the line are spaced so that the distance between any two adjacent items is the same. If the remaining free space is negative or there is only one flex item per line, this value is identical to the flex-start parameter. |
space-around | The flex items on the line are distributed so that the distance between any two adjacent flex items is the same, and the distance between the first/last flex items and the edges of the flex container is half the distance between the flex items. |
initial | Sets the property value to the default value. |
inherit | Inherits the property value from the parent element. |
![](https://i1.wp.com/html5book.ru/wp-content/uploads/2015/06/justify-content.png)
Syntax
Flex-container ( display: -webkit-flex; -webkit-justify-content: flex-start; display: flex; justify-content: flex-start; )
6.2. Cross axis alignment: align-items and align-self
Flex elements can be aligned crosswise current line flex container. align-items sets the alignment for all flex container items, including anonymous flex items. align-self allows you to override this alignment for individual flex items. If any of the flex element's cross margins are set to auto , align-self has no effect.
6.2.1. Align-items
The property aligns flex elements, including anonymous flex elements, along the transverse axis. Not inherited.
Values: | |
flex-start | |
flex-end | |
center | |
baseline | The baselines of all flex items involved in alignment are the same. |
stretch | |
initial | Sets the property value to the default value. |
inherit | Inherits the property value from the parent element. |
![](https://i1.wp.com/html5book.ru/wp-content/uploads/2015/06/align-items.png)
Syntax
Flex-container ( display: -webkit-flex; -webkit-align-items: flex-start; display: flex; align-items: flex-start; )
6.2.2. Align-self
The property is responsible for aligning a single flex element to the height of the flex container. Overrides the alignment specified by align-items . Not inherited.
Values: | |
auto | Default value. A flex element uses the alignment specified in the align-items property of the flex container. |
flex-start | The top edge of the flex element is placed adjacent to the flex line (or at a distance, taking into account the specified margins and borders of the element) passing through the beginning of the cross axis. |
flex-end | The bottom edge of the flex element is placed adjacent to the flex line (or at a distance, taking into account the specified margins and borders of the element) passing through the end of the cross axis. |
center | The margin of a flex element is centered along the cross axis within the flex line. |
baseline | The flex element is aligned to the baseline. |
stretch | If a flex item's cross-size is auto and none of the cross-margin values are auto , the item is stretched. Default value. |
initial | Sets the property value to the default value. |
inherit | Inherits the property value from the parent element. |
![](https://i2.wp.com/html5book.ru/wp-content/uploads/2015/06/align-self.png)
Syntax
Flex-container ( display: -webkit-flex; display: flex; ) .flex-item ( -webkit-align-self: center; align-self: center; )
6.3. Aligning the lines of a flex container: align-content
The property aligns rows in a flex container when there is extra space on the cross axis, similar to justifying individual items on the main axis using the justify-content property. The property does not affect a single-line flex container. Not inherited.
Values: | |
flex-start | Rows are stacked towards the beginning of the flex container. The edge of the first line is placed close to the edge of the flex container, each subsequent line is placed close to the previous line. |
flex-end | Rows are stacked towards the end of the flex container. The edge of the last line is placed close to the edge of the flex container, each previous line is placed close to the next line. |
center | Rows are stacked towards the center of the flex container. The rows are located close to each other and aligned to the center of the flex container with equal distance between the starting edge of the flex container's contents and the first line, and between the ending edge of the flex container's contents and the last line. |
space-between | The rows are evenly distributed in the flex container. If the remaining free space is negative or there is only one flex line in the flex container, this value is identical to flex-start . Otherwise, the edge of the first line is placed close to the start edge of the flex container's content, and the edge of the last line is placed close to the end edge of the flex container's content. The remaining lines are distributed so that the distance between any two adjacent lines is the same. |
space-around | The lines are evenly spaced in the flex container with half space on both ends. If the remaining free space is negative, this value is identical to center center . Otherwise, the lines are distributed so that the distance between any two adjacent lines is the same, and the distance between the first/last lines and the edges of the flex container's contents is half the distance between the lines. |
stretch | Default value. Rows of flex items stretch evenly to fill all available space. If the remaining free space is negative, this value is identical to flex-start . Otherwise, the free space will be divided equally between all rows, increasing their lateral size. |
initial | Sets the property value to the default value. |
inherit | Inherits the property value from the parent element. |
![](https://i0.wp.com/html5book.ru/wp-content/uploads/2015/06/align-content.png)
Syntax
Flex-container ( display: -webkit-flex; -webkit-flex-flow: row wrap; -webkit-align-content: flex-end; display: flex; flex-flow: row wrap; align-content: flex-end ; height: 100px )
Why Flexbox?
For a long time, the only reliable cross browser-compatible tools available for creating CSS layouts were things like floats and positioning . These are fine and they work, but in some ways they are also rather limiting and frustrating.
The following simple layout requirements are either difficult or impossible to achieve with such tools, in any kind of convenient, flexible way:
- Vertically centering a block of content inside its parent.
- Making all the children of a container take up an equal amount of the available width/height, regardless of how much width/height is available.
- Making all columns in a multiple column layout adopt the same height even if they contain a different amount of content.
As you"ll see in subsequent sections, flexbox makes a lot of layout tasks much easier. Let"s dig in!
Introducing a simple example
In this article we are going to get you to work through a series of exercises to help you understand how flexbox works. To get started, you should make a local copy of the first starter file - flexbox0.html from our github repo - load it in a modern browser (like Firefox or Chrome), and have a look at the code in your code editor. You can also.
Flex-direction: column;
You"ll see that this puts the items back in a column layout, much like they were before we added any CSS. Before you move on, delete this declaration from your example.
Note: You can also lay out flex items in a reverse direction using the row-reverse and column-reverse values. Experiment with these values too!
Wrapping
One issue that arises when you have a fixed amount of width or height in your layout is that eventually your flexbox children will overflow their container, breaking the layout. Have a look at our flexbox-wrap0.html example, and try viewing it live (take a local copy of this file now if you want to follow along with this example):
Here we see that the children are indeed breaking out of their container. One way in which you can fix this is to add the following declaration to your element represents a standalone section - which doesn"t have a more specific semantic element to represent it contained within an html document.>
Flex-wrap: wrap; flex: 200px;
Try this now; you"ll see that the layout looks much better with this included:
We now have multiple rows - as many flexbox children are fitted onto each row as makes sense, and any overflow is moved down to the next line. The flex: 200px declaration set on the articles means that each will be at least 200px wide; we"ll discuss this property in more detail later on. You might also notice that the last few children on the last row are each made wider so that the entire row is still filled.
But there"s more we can do here. First of all, try changing your flex-direction property value to row-reverse - now you"ll see that you still have your multiple row layout, but it starts from the opposite corner of the browser window and flows in reverse.
flex-flow shorthand
At this point it is worth noting that a shorthand exists for flex-direction and flex-wrap - flex-flow . So for example, you can replace
Flex-direction: row; flex-wrap: wrap;
Flex-flow: row wrap;
Flexible sizing of flex items
Let's now return to our first example, and look at how we can control what proportion of space flex items take up. Fire up your local copy of flexbox0.html , or take a copy of flexbox1.html as a new starting point ( see it live).
First, add the following rule to the bottom of your CSS:
Article (flex: 1; )
This is a unitless proportion value that dictates how much of the available space along the main axis each flex item will take up. In this case, we are giving each element a value of 1, which means they will all take up an equal amount of the spare space left after things like padding and margin have been set. It is a proportion, meaning that giving each flex item a value of 400000 would have exactly the same effect.!}
Now add the following rule below the previous one:
Article:nth-of-type(3) ( flex: 2; )
Section - article article article - div - button div button div button button button
Let's look at the code we've used for the layout.
Summary
That concludes our tour of the basics of flexbox. We hope you had fun, and will have a good play around with it as you travel forward with your learning. Next we"ll have a look at another important aspect of CSS layouts - CSS Grids.
Flexbox is designed to save us from the nastiness of pure CSS (like vertical alignment), and it does a great job. But understanding the principles of its operation can sometimes be difficult, especially if you are a beginner.
The main goal of Flexbox is to make layers flexible and intuitive to work with. To achieve this goal, it allows containers to decide how to handle their children, including changing their size and spacing.
Sounds good, but let's see if it's so smooth in practice. In this article, we'll explore the 5 most popular Flexbox properties, what they do, and how they actually work.
Display: Flex
Here is an example page:
We have 4 different colored divs of different sizes that are inside a gray div. Each div has a display: block property. Therefore, each square takes up the entire width of the line.
To get started with Flexbox, we need to make our container a flex container. This is done like this:
#container ( display: flex; )
It seems like nothing much has changed - the divs just lined up. But you did something really powerful. You've given your squares a cool property called "flex-context".
Flex Direction
A flex container has two axes: the main axis and the one perpendicular to it.
By default, all objects are located along the main axis: from left to right. That's why our squares lined up when we applied display: flex . However, flex-direction allows the main axis to be rotated.
#container ( display: flex; flex-direction: column; )
It's important to note that flex-direction: column does not align squares along an axis perpendicular to the main one. The main axis itself changes its location and is now directed from top to bottom.
There are a couple more properties for flex-direction: row-reverse and column-reverse.
Justify Content
Justify-content is responsible for aligning elements along the main axis.
Let's go back to flex-direction: row .
#container ( display: flex; flex-direction: row; justify-content: flex-start; )
Justify-content can take 5 values:
- flex-start ;
- flex-end ;
- center ;
- space-between ;
- space-around.
Space-between sets the same distance between the squares, but not between the container and the squares. Space-around also sets the same distance between the squares, but now the distance between the container and the squares is half the distance between the squares.
Align Items
If justify-content works on the main axis, then align-items works on the axis perpendicular to the main axis.
Let's go back to flex-direction: row and go through the align-items commands:
- flex-start ;
- flex-end ;
- center ;
- stretch ;
- baseline.
It's worth noting that for align-items: stretch the height of the squares should be set to auto . For align-items: baseline there is no need to remove paragraph tags, otherwise it will turn out like this:
To better understand how axes work, let's combine justify-content with align-items and see how center alignment works for the two flex-direction properties:
Align Self
Align-self allows you to align elements individually.
#container ( align-items: flex-start; ) .square#one ( align-self: center; ) // Only this square will be centered.
Let's use align-self for two squares and use align-items: center and flex-direction: row for the rest.
Flex-Basis
Flex-basis is responsible for the initial size of elements before they are changed by other Flexbox properties:
Flex-basis affects the size of elements along the main axis.
Let's see what happens if we change the direction of the main axis:
Notice that we also had to change the height of the elements. Flex-basis can define both the height of elements and their width depending on the direction of the axis.
Flex Grow
This property is a little more complicated.
First, let's give our squares the same width of 120px:
By default, the flex-grow value is 0. This means that the squares are not allowed to grow (take up the remaining space in the container).
Let's try setting flex-grow to 1 for each square:
The squares took up the remaining space in the container. The flex-grow value overrides the width value.
But here one question arises: what does flex-grow: 1 mean?
Let's try setting flex-grow to 999:
And... nothing happened. This happened because flex-grow does not accept absolute values, but relative ones.
This means that it doesn't matter what the value of flex-grow is, what matters is what it is in relation to the other squares:
At first, the flex-grow of each square is 1, the total is 6. This means that our container is divided into 6 parts. Each square will take up 1/6 of the available space in the container.
When the flex-grow of the third square becomes 2, the container is divided into 7 parts (1 + 1 + 2 + 1 + 1 + 1).
Now the third square takes up 2/7 of the space, the rest - 1/7 each.
It's worth remembering that flex-grow only works for the main axis (until we change its direction).
Flex Shrink
Flex-shrink is the exact opposite of flex-grow. It determines how much the square can shrink in size.
Flex-shrink is used when elements do not fit into the container.
You determine which elements should shrink in size and which should not. By default, the flex-shrink value for each square is 1. This means that the squares will shrink as the container gets smaller.
Let's set flex-grow and flex-shrink to 1:
Now let's change the flex-shrink value for the third square to 0. It's not allowed to shrink, so its width will remain at 120px:
It's worth remembering that flex-shrink is based on proportions. That is, if a square has a flex-shrink of 6, and the rest have a flex-shrink of 2, then this means that our square will shrink three times faster than the others.
Flex
Flex replaces flex-grow , flex-shrink and flex-basis .
Default values are 0 (grow) 1 (shrink) and auto (basis).
Let's create two squares:
Square#one ( flex: 2 1 300px; ) .square#two ( flex: 1 2 300px; )
Both squares have the same flex-basis. This means they will both be 300px wide (container width: 600px plus margin and padding).
But when the container starts to grow in size, the first square (with the largest flex-grow) will grow twice as fast, and the second square (with the largest flex-shrink) will shrink twice as fast.
How things grow and shrink
When the first square increases, it does not become twice the size of the second square, and when the second square decreases, it does not become half the size of the first. This is because flex-grow and flex-shrink are responsible for the rate of growth and contraction.
A little math
Initial container size: 640px. Subtract 20px from each side for padding, and we are left with 600px, just enough for two squares.
When the container width becomes 430px (a loss of 210px), the first square (flex-shrink: 1) loses 70px. The second square (flex-shrink: 2) loses 140px.
When the container shrinks to 340px, we lose 300px. The first square loses 100px, the second - 200px.
The same thing happens with flex-grow .
Danny Markov
The design is quite simple - it consists of a center-aligned container, inside of which we have a header, a main section, a sidebar and a footer. Here are the main "tests" we should run while keeping the CSS and HTML as clean as possible:
- Place four main sections of the layout.
- Make the page responsive (the sidebar falls below the main content on small screens).
- Align header content - left navigation, right button.
As you can see, for the sake of comparison, we kept everything as simple as possible. Let's start with the first test.
Test 1: Laying out page sections
Flexbox solution
Add display: flex to the container and set the vertical direction of the child elements. This positions all the sections underneath each other.
Container ( display: flex; flex-direction: column; )
Now we need to make sure that the main section and the sidebar are located next to each other. Since flex containers are usually unidirectional, we need to add an extra element.
We then set this element's display: flex and flex-direction to the opposite direction.
Main-and-sidebar-wrapper ( display: flex; flex-direction: row; )
The last step is to set the dimensions of the main section and sidebar. We want the main content to be three times the width of the sidebar, which is easy to do with flex or percentages.
As you can see, Flexbox did everything well, but we also needed quite a lot of CSS properties plus an additional HTML element. Let's see how CSS Grid will work.
CSS Grid Solution
There are several options for using CSS Grid, but we will use the grid-template-areas syntax as the most suitable for our purposes.
First we'll define four grid-areas, one for each section of the page:
Now we can set up our mesh and define the location of each area. The code may seem quite complicated at first, but once you become familiar with the grid system, it becomes easier to understand.
Container ( display: grid; /* Define the size and number of columns of our grid. The fr unit works like Flexbox: the columns divide up the available space in the row according to their values. We will have two columns - the first is three times the size of the second. */ grid-template -columns: 3fr 1fr; /* Link the previously made areas to places in the grid. The first line is the header. The second line is divided between the main section and the sidebar */ grid-template-areas: "header header" main sidebar" "footer footer"; /* The spacing between grid cells will be 60 pixels */ grid-gap: 60px; )
That's all! Our layout will now follow the above structure and we've set it up so that we don't have to deal with margin or padding.
Test 2. Making the page responsive
Flexbox solution
This step is strictly related to the previous one. For a Flexbox solution, we will have to change the flex-direction and adjust the margin.
@media (max-width: 600px) ( .main-and-sidebar-wrapper ( flex-direction: column; ) .main ( margin-right: 0; margin-bottom: 60px; ) )
Our page is fairly simple, so there's not a lot of work in the media query, but a more complex layout would require a lot of rework.
CSS Grid Solution
Since we've already defined grid-areas , we just need to redefine their order in the media query. We can use the same speaker setup.
@media (max-width: 600px) ( .container ( /* Align grid areas for mobile layout */ grid-template-areas: "header header" "main main" "sidebar sidebar" "footer footer"; ) )
Or we can redefine the entire layout from scratch if we think this solution is cleaner.
@media (max-width: 600px) ( .container ( /* Convert the grid to a single-column layout */ grid-template-columns: 1fr; grid-template-areas: "header" "main" "sidebar" "footer"; ) )
Test 3: Aligning Header Components
Flexbox solution
We have already done a similar layout with Flexbox in one of our old articles -. The technique is quite simple:
Header ( display: flex; justify-content: space-between; )
The navigation list and button are now aligned correctly. All that remains is to place the items inside
Header nav ( display: flex; align-items: baseline; )
Only two lines! Not bad at all. Let's see how to deal with this CSS Grid.
CSS Grid Solution
To separate the navigation and button, we must add display: grid to the header and set up a two-column grid. We'll also need two extra lines of CSS to position everything on the appropriate borders.
Header( display: grid; grid-template-columns: 1fr 1fr; ) header nav ( justify-self: start; ) header button ( justify-self: end; )
Regarding single line links within navigation, we were unable to do this correctly with CSS Grid. Here's what our best attempt looks like:
Header nav ( display: grid; grid-template-columns: auto 1fr 1fr; align-items: end; )
It's clear that CSS Grid doesn't handle this part of the layout well, but that's not surprising - the focus is on the alignment of the containers, not the content inside them. This system is not for putting finishing touches.
conclusions
If you read the entire article (which is great job!), the conclusions should not surprise you. Actually no better system- both Flexbox and CSS Grid are good in their own way and should be used together, and not as an alternative to each other.
For those of you who jumped directly to the conclusions of this article (don't worry, we do that too), here's summary comparisons:
- CSS Grid is great for creating a big picture. This system makes it easier to manage page layout and can even deal with irregular and asymmetrical designs.
- Flexbox is great for aligning content within elements. Use this system to place small design details.
- Use CSS Grid for 2D layouts (rows AND columns).
- Flexbox works better in only one dimension (rows OR columns).
- There is no reason to use only CSS Grid or only Flexbox. Study them and use them together.