preface
Flex layouts have become very popular and can do most of the layout requirements. Older float layouts, table layouts, and so on were less popular. But nothing is perfect, and neither is flex layout, which has its flaws, such as the alignment of the last line in flex layout that we’ll talk about today.
1. Why is the last line left aligned
We all know that the Flex layout is a two-dimensional coordinate system with horizontal and vertical axes, and the child elements are arranged according to the initial orientation of the horizontal and vertical axes that we originally defined, as shown below:
In Flex layouts, the context-content attribute is used to specify the arrangement of horizontal elements. It is used in one of the following ways:
- Justify: context-content: space-between;
- Left-justify: justify-content: flex-start;
- Justify right: justify-content: flex-end;
- Center aligned: justify-content: center;
When we use two ends alignment, the last line of elements will have a problem, resulting in an unsightly style, as shown below:
The code is as follows:
<style>
.container {
width: 300px;
border: 1px solid #000;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.list {
width: 66px;
height: 66px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
}
</style>
<div class="container">
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
</div>
Copy the code
At this point we might want to make the last row of elements left-aligned.
2. Each row has a fixed number
If each row has a fixed element, like we have four elements in each row, there are two ways to solve the left alignment problem.
2.1 Simulation ends are aligned
What we mean by simulation here is that we do not justify-content: space-between, but we want to justify both ends, and we want gaps between each child element.
To achieve this effect, we need to dynamically calculate the gap between each child element. We use margin to control the gap, and the code is as follows:
.container { width: 300px; border: 1px solid #000; display: flex; flex-wrap: wrap; } .list { width: 66px; height: 66px; margin-bottom: 10px; background-color: rgb(148, 148, 131); } // List :not(:nth-child(4n)) {margin-right: 22px; }Copy the code
This method can be used to align both ends, but requires calculating the right margin of each child element.
2.2 Dynamically set margin according to the number
Here, the dynamic setting margin refers to setting the margin value of the last element. If we set the right margin of the last element in the last line to the element width + the gap width, the left alignment effect can be achieved if we set the right margin of the last element in the last line to the element width + the gap width.
But at this point we need to know how many elements are in the last line. Here we use a CSS selector:
- .list:last-child:nth-child(4n-1) Indicates that the last row has either three or seven elements…
- .list:last-child:nth-child(4n-2) Indicates that the last row has either two or six elements…
The above two lines of code take the third element and the second element of the last line and dynamically set the margin as follows:
.container {
width: 300px;
border: 1px solid #000;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.list {
width: 65px;
height: 65px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
}
.list:last-child:nth-child(4n - 1) {
margin-right: calc(66px + 12px);
}
.list:last-child:nth-child(4n - 2) {
margin-right: calc(66px + 66px + 12px + 12px);
}
Copy the code
When the last line has three elements, the right margin of the last element = the element width + the gap width.
3. The width of child elements in each row is not fixed
Sometimes the width of each row is not fixed, so we have two ways to align the last line left.
3.1 margin – right: auto
This method is easy to implement, we just need to set the last element margin-right to auto, the code is as follows:
.container {
width: 300px;
border: 1px solid #000;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.list {
width: 65px;
height: 65px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
margin-right: 10px;
}
.list:nth-child(1) {
width: 65px;
height: 65px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
margin-right: 10px;
}
.list:nth-child(2) {
width: 60px;
height: 60px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
margin-right: 10px;
}
.list:nth-child(3n) {
width: 50px;
height: 50px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
margin-right: 10px;
}
.list:last-child {
margin-right: auto;
}
Copy the code
To make it easier for you to understand, I’ve set a lot of list elements to different widths, and you can see that the last line of elements is left aligned, but the right-most element is not perfectly aligned, so that’s one of the minor drawbacks of this approach.
3.2 Setting pseudo-elements
In addition to using margin-right:auto, we can also use the pseudo-element to align the last line left, create the pseudo-element and set flex:auto or flex:1 as follows:
.container { width: 300px; border: 1px solid #000; display: flex; flex-wrap: wrap; justify-content: space-between; } .list { width: 65px; height: 65px; margin-bottom: 10px; background-color: rgb(148, 148, 131); margin-right: 10px; } .list:nth-child(1) { width: 65px; height: 65px; margin-bottom: 10px; background-color: rgb(148, 148, 131); margin-right: 10px; } .list:nth-child(2) { width: 60px; height: 60px; margin-bottom: 10px; background-color: rgb(148, 148, 131); margin-right: 10px; } .list:nth-child(3n) { width: 50px; height: 50px; margin-bottom: 10px; background-color: rgb(148, 148, 131); margin-right: 10px; } .container::after { content: ''; flex: auto; /* flex: 1 */}Copy the code
This effect is consistent with Margin: Auto.
4. The number of columns is not fixed
When the number of rows is variable, the above method is not very suitable, we need to use another method to achieve the left alignment of the last row: use enough space space to fill the space, the number of space elements is determined by the number of columns.
.container {
border: 1px solid #000;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.list {
width: 65px;
height: 65px;
margin-bottom: 10px;
background-color: rgb(148, 148, 131);
margin-right: 10px;
}
.container>i {
width: 65px;
margin-right: 10px;
}
<div class="container">
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<i></i><i></i><i></i><i></i><i></i>
</div>
Copy the code
Here we declare a lot of placeholder I tag elements, and we give it a width, because we don’t give it a height, so it doesn’t affect our layout. This also makes the last line left aligned, but it changes the HTML structure.
conclusion
There are four ways to align the last line of a Flex layout to the left, but each of them is flawed. The most widely used method is using placeholder elements, because it is not only suitable for scenarios where the elements in each row are not fixed, but also when there are a fixed number of elements in each row.
But if you want perfect alignment at both ends, consider a grid layout.