Everything you need to know about alignment in Flexbox

Original author: Rachel Andrew
  • Transfer

The cycle of publications on the features of CSS-technology Flexbox from Rachel Andrew.


  1. What happens when you create a Flexbox container .


Summary

In this article, we will look at the alignment properties in the Flexbox, as well as the basic rules to help remember how alignment works on both the main and transverse axes.



In the first article in this series, I explained what happens when display: flex is declared for an element. This time we will look at the alignment properties and how they work with the Flexbox . If you've ever been confused about when to align , and when justify , I hope this article will remove all the questions!


History of flexbox leveling


In the entire history of CSS layout, the ability to correctly align elements on both axes seemed to me to be the most difficult problem of web design. Those. The ability to properly align elements and groups of elements was for many of us the most exciting feature of the Flexbox when it first appeared in browsers. Alignment has become just two lines in CSS:



Alignment properties, which can be thought of as flexbox alignment properties , are now fully defined in the Box Alignment specification . It describes in detail how alignment works in different layout contexts. This means that we can use the same alignment properties in the CSS Grid as in Flexbox , and in the future, in other layout contexts. Thus, any new alignment feature for flexbox will be described in detail in the Box Alignment specification , and not at the next Flexbox level .


Properties


Many people tell me that they are struggling to remember whether to use properties that begin in flexbox with align- , or those that start with justify- . It should be remembered that:


  • justify performs the alignment of the main axis. Align in the same direction as your flex-direction;
  • align performs the perpendicular axis alignment. Alignment in a direction perpendicular to the flex-direction.

Thinking from the point of view of the main and transverse axis, not horizontal and vertical, really helps here. It does not matter where the axis is physically directed.


Align the main axis with justify-content


Let's start with the alignment of the main axis. On the main axis, alignment is performed using the justify-content property . This property treats all flex-elements as a group and controls the distribution of space between them.


The initial value of the justify-content property is flex-start . That is why when declaring display: flexall flex-elements line up at the beginning of the flex line. If your flex-direction has the value row (row) and the text input direction of the language from left to right, like English, then the elements will start on the left.


Items line up from start.
Fig_1. Items line up from start.


Please note that the justify-content property can perform actions only if there is free space for distribution. Therefore, if your set of flex elements occupies all the space on the main axis, using justify-content will not change anything.


No space for redistribution
Fig_2. No space for redistribution


If we give the justify-content property a flex-end value , then all elements will be moved to the end of the line. The free space will now be located at the beginning.


Items line up at the end
Fig_3. Items line up at the end


We can do other things with this space. We could ask it to be distributed between our flex-elements using justify-content: space-between. In this case, the first and last elements will be flush with the ends of the container and the whole space will be divided equally between the elements.


Free space is distributed between elements.
Fig_4. Free space is distributed between elements.


We can request space around our flex elements using justify-content: space-around. In this case, the available space is distributed and allocated on each side of the elements.


Elements now have space on either side
Pic_5. Elements now have space on either side


The most recent value of the justify-content property can be found in the Box Alignment specification ; it does not appear in the Flexbox specification . This is space-evenly . In this case, the elements will be distributed in the container evenly, and the additional space will be between them and on both sides.


Elements are evenly distributed.
Fig_6. Elements are evenly distributed.


You can play with all the values ​​in the demo:



These values ​​work the same way if your flex-direction is a column. However, you may not have extra space to distribute in a column unless you add height or block size to a flex container, as in the following demo.



Align perpendicular axis with align-content


If you have added flex-wrap: wrap to a flex-container and have several flex lines, then you can use the align-content property to align the flex lines on the transverse axis. However, this will require additional space on the transverse axis. In the demo below, my transverse axis goes in a block direction, i.e. in the column, and I set the height of the container to 60vh. Since this is more than necessary to display my flex elements, I have vertical free space in the container.


Then I can use align-content with any of the values:



If my flex-direction is a column, then align-content will work as in the following example.



As in the case of justify-content , we work with strings in a group and allocate free space.


The short form of the place-content property


In the Box Alignment specification, we find the abbreviated form of the place-content property . Using this property, you can set justify-content and align-content right away. The first parameter is specified for align-content , the second is for justify-content . If you specify only one value, then it is set for both parameters, therefore:


.container {
    place-content: space-between stretch;
}

same as:


.container {
    align-content: space-between; 
    justify-content: stretch;
}

If you used:


.container {
    place-content: space-between;
}

then it will be the same as:


.container {
    align-content: space-between; 
    justify-content: space-between;
}

Aligning the perpendicular axis with align-items


We now know that we can align our set of flex elements or our flex lines as a group.


However, there is another way that we can align our elements - this is by aligning the elements relative to each other on the transverse axis. Your container has a height. This height could be determined by the height of the tallest element as in this figure.


The height of the container is determined by the third element.
Fig_7. The height of the container is determined by the third element.


Instead, it can be defined by adding a height to the flex container:


The height is determined by the size of the flex container.
Fig_8. The height is determined by the size of the flex container.


The reason why flex elements are stretched to the size of the tallest element is that the initial value of the align-items parameter is stretch . And the elements are stretched along the transverse axis to get the size of the flex-container in this direction.


Note that in the case of align-items, the value is concerned , and in the presence of a multi-line flex-container, each line acts as a new flex-container. The highest element in this line will determine the size of all line elements.


In addition to the initial value stretch can assign elements align-items value flex-start , in this case they are aligned on the top of the container and is no longer stretched adjustment.


Elements aligned to the beginning of the transverse axis.
Figure_9. Elements aligned to the beginning of the transverse axis.


The flex-end value moves them to the end of the container along the transverse axis.


Elements aligned at the end of the transverse axis.
Figure 10. Elements aligned at the end of the transverse axis.


If you use the center value, the elements are all centered against each other:


Elements in the center of the transverse axis
Fig_11. Elements in the center of the transverse axis


We can also do a baseline alignment. This ensures alignment of the base lines of the text, and not alignment of the fields around the content.


Baseline alignment
Fig_12. Baseline alignment


You can try these values ​​in the demo:



Individual alignment with align-self


The align-items property means that you can set the alignment of all items at the same time. In fact, it sets the values ​​of the align-self property of individual flex-elements for the whole group.


You can also use the align-self property of any individual flex element to align it inside the flex line with other flex elements.


In the following example, I used the align-items in the container to set the alignment for the group in the center, but also used the align-self for the first and last items to change their alignment value.



Why is there no self-leveling?


Often the question arises why it is impossible to align one element or group of elements along the main axis. Why is there no -self property in Flexbox for alignment with the main axis? If you think of justify-content and align-content as space allocation, the reason for the lack of self-tuning becomes more obvious. We deal with flex-elements as a group and distribute the available space in a certain way - either at the beginning, or at the end of the group, or between elements.


If it can also be useful to think about how to justify-content and align-content-work in a CSS grid layout. In the Grid, these properties are used to allocate free space in the grid container between the grid tracks. Once again, we take the tracks as a group, and these properties give us the opportunity to distribute any additional space between them. Since we act in a group in both the Grid and the Flexbox, we cannot aim at an element ourselves and do something else with it. However, there is a way to achieve the kind of layout that you ask for when you ask for the self property on the main axis, and that is to use automatic fields.


Using auto-indentation on the main axis


If you've ever centered a block in CSS (for example, a shell for the contents of the main page, setting the margin to the left and right in auto ), then you already have some experience with automatic fields. The indent set in auto will try to get as big as possible in the set direction. In the case of using indents to center a block, we set both left and right in auto . Each of them is trying to take as much space as possible, and therefore squeezes our block into the center.


Automatic indents work very well in Flexbox to align individual elements or groups of elements on the main axis. In the following example, I reach the overall design pattern. I have a navigation bar using Flexbox , the items are displayed as a string and use the initial value justify-content: start. I would like the last item to be displayed separately from the others at the end of the flex line, provided that there is enough space in the line.


I aim at this menu item and give it a margin-left auto . This means that the field is trying to get as much space as possible to the left of the item, pushing it all the way to the right.



If you use auto-indenting on the main axis, then the justify-content property will no longer create any effect, since auto-indenting will take up all the space that would otherwise be allocated using justify-content .


Back alignment


Each leveling method describes in detail the backup distribution, this is what happens if the requested leveling cannot be achieved. For example, if you have only one element in a flex container and you request justify-content: space-between , what should happen? The answer is that backup alignment uses flex-start , and one element will be aligned to the beginning of the flex container. In the case of justify-content: space-around , backup alignment in the center is used.


In the current specification, you cannot change the backup alignment settings. Therefore, if you prefer the backup option for space-between to be the center rather than flex-start , then there is no way to do this. But there is a note in the specification that states that this feature can be included in future levels.


Safe and unsafe alignment


A very recent addition to the Box Alignment specification is the concept of secure and insecure alignment using secure and insecure keywords.


In the following code, the last element is too wide for the container, and with unsafe alignment and a flexible container on the left side of the page, the element is trimmed because the overflow extends beyond the page border.


.container {  
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: unsafe center;
}
.item:last-child {
    width: 200px;
}

Insecure alignment will provide the required alignment, but may result in data loss.
Fig_13. Insecure alignment will provide the required alignment, but may result in data loss.


Safe alignment will prevent data loss by moving the overflow to the other side.


.container {  
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: safe center;
}
.item:last-child {
    width: 200px;
}

Safe alignment attempts to prevent data loss
Figure 14 Safe alignment attempts to prevent data loss


These keywords have limited browser support right now; however, they demonstrate the essence of the additional controls introduced in Flexbox through the Box Alignment specification .



At last


The alignment properties began as a list in Flexbox , but now they have their own specification and apply also to other layout contexts. A few key facts will help you remember how to use them in the Flexbox :


  • justify- main axis and align- transverse axis;
  • To use align-content and justify-content , you need free space to play;
  • The align-content and justify-content properties deal with elements as a group, dividing the space. Thus, you cannot adjust them to a separate element, and therefore there is no self-leveling for these properties;
  • If you want to align one element or divide a group on the main axis, use automatic indents for this;
  • The align-items property sets all values ​​for the align-self group. Use align-self on the child to set the value for an individual element.

Also popular now: