[Layout Tips] Centered overflow scrolling truncation problem under Flex layout

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 through justify-content and align-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 adding margin-left: auto to the first element of the sub-item, adding to the tail Adding elements margin-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:

  1. .g-wrap When the width of the flex item within is less than 100%, the entire .g-wrap is restricted by its parent container justify-content: center and will be expressed as horizontally centered;
  2. When the width of the flex item in .g-wrap exceeds 100%, since max-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 default justify-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:

  1. 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;
  2. 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;
  3. 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

Guess you like

Origin blog.csdn.net/qq_41221596/article/details/134960576