In page layout, we often encounter/use such a common layout, that is, the list content is horizontally centered in the container, like this:
<ul class="g-contaner">
<li></li>
<li></li>
</ul>
ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
gap: 10px;
}
The effect is as follows:
Here, the outer container has a fixed width, and the inner flex-item also has a fixed width.
When the number of flex-items is small, there is no problem. However, if there is too much content in the element and flex-wrap: nowrap
is set, the content will overflow the container:
At this time, we have several solutions. One of them is to set overflow: auto
or overflow: hidden
for the parent container so that the parent container can scroll, like This is it:
ul {
// ...
overflow: auto;
}
The effect becomes like this:
When we try to scroll this container, we will find a fatal problem:The container can only scroll to the left and cannot scroll to the right, so only the truncated second half can be seen content without being able to see the first half of the truncated content:
What does that mean? Combining the above Gif with the following diagram, you can understand it at a glance:
In response to this problem. One of the good analogy solutions is that when flex-item is not enough to overflow, flex-item is displayed in the center, and when the number of flex-item exceeds the width of the parent container, the layout is similar to styles are arranged to ensure that all content can be seen during scrolling . justify-content: flex-start
The normal effect should be as follows:
The first and second lines above are When the flex-item is not enough to overflow, the flex-item is displayed in the center, and the third line < /span> , which ensures that the content is scrolled during the scrolling process. All can be seen in . , that is, when the number of flex-items exceeds the width of the parent container, the layout is arranged in a style similar to justify-content: flex-start
Therefore, in this article we will explore together several different ways to solve this problem.
Method 1: Keywords safe and unsafe under Flex layout
In fact, the specification has also noticed this centered scrolling problem under layout.
Therefore, starting from Chrome 115, two new keywords safe
and unsafe
have been added under the flex layout.
Based on CSS Box Alignment Module Level 3, explicitly lists this safe Layout instructions for and unsafe :
Today, we can solve this problem directly in alignment mode through the safe
keyword.
Let’s simply transform our flex layout code above and change justify-content: center
to justify-content: safe center
:
ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
- justify-content: center;
+ justify-content: safe center;
align-items: center;
gap: 10px;
}
At this time, the flex layout can automatically identify whether the number of flex-items under the current flex container exceeds the width/height of the container, thuschange the alignment.
Currently, the only problem with this method is compatibility,< a i=4> It will take some time for keywords to be used on a large scale. safe
Method 2: Use margin: auto instead of justify-content: center
Therefore, it is necessary for us to continue to explore other solutions.
In addition to justify-content: center
, we can actually use margin: auto
to achieve horizontal centering of the sub-flex-item.
Let’s modify the DEMO diagram at the beginning of the article:
ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: 10px;
}
li {
margin: auto;
}
When the number of flex-items is not enough to overflow the container width, the effect is as follows:
At this time, flex-item, under the action of margin: auto
, will evenly divide the remaining space of the entire container, both horizontally and vertically.
In standard terms, the element with
margin: auto
set, before alignment throughjustify-content
andalign-self
, Any free space will be allocated to the automatic margin in that direction.
So, margin: auto
is also a very important technique for centering, although we often use this technique for vertical centering under flex layout. You can take a look at the two articles provided above.
What’s interesting is that when the number of flex-items exceeds the width of the parent container, since there is no remaining space, is actually equivalent to It has failed, so the layout effect is also arranged using an effect similar to . margin: auto
justify-content: flex-start
It can also achieve our goal:
Method 3: Add an additional layer of nesting
The above margin:auto
has no compatibility issues, but there are a few flaws. Let's carefully compare the performance of margin: auto
and justify-content: center
when flex-item is not enough to overflow:
The flaw is that when is used , the spacing between flex-items is uncontrollable. Because they will always divide the remaining free space equally. margin: auto
Updated on 2023-12-06, based on the uncontrollable method of
margin: auto
, in fact, by only addingmargin-left: auto
to the first element of the sub-item, adding to the tail Adding elementsmargin-right: auto
can actually solve the spacing problem.
Therefore, the best way for compatibility is to add one more layer, which can also cleverly solve this problem.
Original structure:
<ul class="g-contaner">
<li></li>
// ...
<li></li>
</ul>
Renovated structure:
<ul class="g-contaner">
<ul class="g-wrap">
<li></li>
// ...
<li></li>
</ul>
</ul>
Transformed CSS:
.g-contaner {
width: 500px;
height: 200px;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: center;
align-items: center;
overflow: auto;
}
.g-wrap {
display: flex;
gap: 10px;
max-width: 100%;
}
We set up an extra layer g-wrap
and set max-width: 100%
. Of course, it is also a flex container.
Therefore when:
.g-wrap
When the width of the flex item within is less than 100%, the entire.g-wrap
is restricted by its parent containerjustify-content: center
and will be expressed as horizontally centered;- When the width of the flex item in
.g-wrap
exceeds 100%, sincemax-width: 100%
is set, the maximum width of the entire container is.g-container
width. At this time, the performance of the child flex item is the defaultjustify-content: flex-start
, so the content is displayed from the beginning, and there is no problem in the scrolling scene
At this point, we have solved the entire problem perfectly with the help of multiple nesting levels. The effect is similar to the method, so there is no need to post additional Gif images.
in conclusion
Okay, let’s quickly summarize the advantages and disadvantages of the three methods:
- Method 1: Use the keywords safe and unsafe under Flex layout, modify the code with the least amount, and the effect is perfect. The core problem is that the compatibility is currently poor;
- Method 2: Use margin: auto instead of justify-content: center, which has good compatibility. The problem is that when the flex item is less than 100% of the parent container, the spacing between elements cannot be controlled;
- Method 3: Add an extra layer of nesting, the effect is perfect, and the amount of transformation is slightly more.
Each of the three methods has its own advantages and disadvantages, and you should make your choice based on the actual business scenarios you face.
At the same time, this article uses an example in the horizontal direction. In fact, in business, we may also encounter the same problems in the vertical direction. The solutions in this article are universal. Moreover, in the safe-based solution, in addition to justify-content: safe center
, the safe
keyword can also be applied to align-items
and < a i=4>, in actual use, select the most suitable writing method based on the specifications. align-self