Flexbox: How Big Is That Flexible Box? , by Rachel Andrew
This is the third article in the Flexbox series. In the first two, I covered what happens when we use Display: Flex. , discusses alignment in Flexbox. In this article you’ll learn how to control the size of Flex projects and how the browser assigns project sizes by default.
Initial value for the Flex project
Suppose we now have some elements with unequal content and set display: flex to their parent element. The items are displayed in a row and arranged from the beginning of the axis. The three projects in the following example all contain content that, because there is plenty of space, displays properly without folding lines. We know that flex-grow has an initial value of 0, so flex projects do not stretch and there is free space at the end of the Flex container.
There is currently ample space for Flex projects to be displayed in an array
If I modify it, add something to the project, the text starts to fold. Each project gets a percentage of the space in the container based on its actual capacity – Flex projects with more content get more space, which prevents the projects with more content from being too narrow and tall when the next project has less content (say, just one word).
Projects with more content get more space
This behavior is easy to spot if you use Flexbox layout a lot, and you’ve probably wondered how browsers make space for projects. The details of calculating the size of an item are explained in detail in the specification, and each browser vendor that implements the specification will work out how much space to allocate to which item according to the specification definition. We can find this information by looking at the specifications.
Internal and external dimensions of the CSS
When consulting the Flexbox specification, it soon became clear that when it came to Sizing, we were guided to another specification — CSS Intrisnic and Extrinsic Sizing. This is because the concept of size is not limited to Flexbox, just as the alignment properties of Flexbox can be used in other layout contexts. However, if you want to see how these concepts are applied to Flexbox, look at the Flexbox specification. You find yourself going back and forth between the two specifications (somewhat cumbersome), so here are a few key definitions for you to use in the rest of the article.
The preferred size
The preferred size of a box is defined by width and height, and the corresponding logical aliases are inline-size and block-size. That is to say:
.box {
width: 500px;
}
Copy the code
Or use the logical alias inline-size:
.box {
inline-size: 500px;
}
Copy the code
The style set here is to get a box 500 pixels wide, or 500 pixels in the inline direction.
Min – the content size
Min-content size refers to the minimum size of the box without overflow. If your box contains text, this size is the length of the longest English word (if it’s all Chinese, the smallest size is a Chinese character).
Max – the content size
Max-content is the maximum size that a box containing content can reach. That is, the size that the contents of the box would occupy without folding at all, so that the box would appear as long as possible.
Spindle dimensions for Flex project
The main size of a Flex project refers to the amount of space that the project occupies on the main Dimension. In English, if it is in the direction of row, the spindle size corresponds to the width; If it’s in the column direction, this spindle size corresponds to the height.
On the spindle dimension, we can also limit the minimum/maximum spindle size that a Flex project can achieve by setting min-width and max-width.
Calculate the dimensions of the Flex project
Now that we’ve defined some terms, let’s look at how the dimensions of a Flex project are calculated. The initial values of the Flex properties applied to the project are as follows:
flex-grow: 0
flex-shrink: 1
flex-basis: auto
Flex-basis is the basis for calculating the final dimensions. If we set flex-basis to 0 and Flex-grow to 1, then all items have no starting width, so the space in the Flex container is allocated equally to each item, which means that each item occupies the same amount of space.
See the Pen Smashing Flexbox Series 3: flex: 1 1 0; by Rachel Andrew
If flex-basis: Auto and Flex-Grow: 1 are set, only the remaining space is allocated, again based on the current contents of each project.
See the Pen Smashing Flexbox Series 3: Flex: 1 1 Auto Essay Book by Rachel Andrew
There is also a situation where there is no space to allocate, for example, if there is too much content to display on a line, there is no space left.
See the Pen Smashing Flexbox Series 3: Flex: 1 1 Auto Long text by Rachel Andrew
Understanding what auto means here is crucial to understanding how Flexbox calculates the dimensions of Flex projects. So let’s start with auto.
Define the auto
In the CSS, auto is defined as a value. This key word in different contexts, have different meanings, or is worth our further study. The CSS working group spent a lot of time defining the role of Auto in various contexts, as shown in a talk given by spec editor Fantasai.
In the specification, we can find the meaning of the use of auto in flex-basis, and the definitions introduced above help us understand the following statement:
When flex-basis is specified as auto for a Flex project, this keyword retrieves the value of the main size property, using content if auto.
If flex-basis is set to auto, Flexbox looks for the spindle size attribute. If we set width for the Flex project, this is the spindle size. In the following example, all items are set to 110px width, so this is the actual spindle size used when Flex-basis uses the initial value auto.
See the Pen Smashing Flexbox Series 3: flex items with a width by Rachel Andrew
In the original example, we did not set width for the Flex project, which means the spindle size is auto. Let’s look at the next sentence: “If the value is auto, use the value content.”
Let’s take a look at how the content keyword is interpreted in the specification. This is another value you can use for Flex-basis (on supported browsers), for example:
.item {
flex: 1 1 content;
}
Copy the code
The specification defines coCNtent as follows:
“It represents an automatic dimension based on Flex project content. It is usually equivalent to max-content, but adjusted in some cases, such as aspect ratios, intrinsic sizing constraints, or orthogonal flows.”
In our example, the Flex project only contains text, so we ignore the adjustments mentioned above and treat content as max-content.
This explains why, in projects with a small amount of text, the text does not fold. Flex projects are auto-sized, Flexbox views the max-content of projects that can be laid out completely in the container, and the layout is complete.
Not yet, as we added more content to the box, we couldn’t keep it at the max-content size. If you do not, the project will overflow through the Flex container. Once the project fills the Flex container space, the contents are folded, and Flex projects become different sizes based on their contents.
Analytic elastic length
At this point, the interpretation of the specification begins to become quite complex, but the steps taken are as follows:
First, compare all Flex projects together with the available space of the container to see if they are smaller or larger.
If the container has more space than all the projects combined use, we care about the Flex-grow factor because we have room to stretch.
In the first use case, our Flex project has plenty of room to stretch
If the container has less space than all the projects combined use, we care about the Flex-shrink factor, because we need to shrink.
In the second use case, the Flex project takes up too much space for the container and needs to shrink to fit the container space
If flex-grow is in effect, its initial value is 0, so when the Flex project is expanded to max-width, it keeps that size on the main axis because it does not allow stretching.
If flex-shrink is used: 0. We’ll see that Flex projects remain in max-Content state and do not shrink to fit the container space.
See the Pen Smashing Flexbox Series 3: flex: 0 0 auto by Rachel Andrew
In our example — using the initial value of the Flex project — the project can be shrunk. So the step proceeds to the next loop of the algorithm, where it calculates how much space to allocate or delete. Above we set Flex-shrink: 0, where all items together are larger than the container size, so we need to remove space from the Flex project.
Flex-shrink applies to the inner base size, which in our case means max-Content. If a project removes space only according to the Flex-shrink factor, then small projects may actually disappear because all of their space is removed, while larger projects still have room to shrink.
This is a simplified version of the specification, and I haven’t explored some of the more marginal use case scenarios. If you don’t have to go for pixel-level Flexbox layouts, remember that the following two are useful in most situations:
If stretched from auto, the flex-basis of the project is treated as the width or height of the project (if width or height is specified), or max-Content (if width or height is not specified). Then, using this size as a starting point, the space is allocated proportionally based on the Flex-grow factor.
If you shrink from Auto, flex-basis is treated as the width or height of the project, or as max-content. The space is then deleted proportionally based on the Flex-basis, flex-shrink factor, and based on the max-content of the project.
Control extension and contraction
I spent a lot of time in this article describing how project sizes are allocated in Flexbox. Of course, you can also use Flex properties to gain a greater degree of control over your Flex project, especially after you understand the rationale behind it.
By manually setting up Flex-basis, or specifying the size of the project (used by Flex-Basis), we get a higher priority than the browser rendering algorithm, allowing Flexbox to stretch and shrink to a specific size the way we expect. You can also set flex-grow and Flex-shrink to 0 to turn off the project’s stretching and shrinking effects. In the use of the stretch and contract functions, you will have some sense of whether you are using the layout correctly. When trying to align Flex projects in two dimensions, you probably want a Grid layout.
Bebug size related issues
If your Flex project doesn’t have the desired size, it’s usually because Flex-basis auto gets a width from somewhere and flex-basis uses it. You can use DevTools to check the source of the dimensions. Or you can set Flex-basis to 0, which is the base size of the Flex project. Even if we don’t end up with the results we want, this will help determine whether the use of Flex-basis is the cause of the problem.
The Flex clearance
A very popular feature of Flexbox is the ability to specify gaps or grooves between Flex items, just as we can specify gaps in grid layouts and multi-column layouts. This function is specified in Box Alignment. Firefox provides the Gap attribute for Flexbox in Firefox 63. The following example needs to be seen in Firefox 63+.
See the Pen Smashing Flexbox Series 3: flex-gaps by Rachel Andrew
Similar to Grid layouts, gaps are removed before allocating space to Flex projects.
conclusion
In this article, I try to explain how Flexbox calculates Flex project dimensions. It may be a bit academic, but knowing this can save you a lot of time when you’re using Flexbox for page layout. I found Flexbox’s default layout to be reasonable when dealing with a bunch of projects of different sizes. Projects with more content will allocate more space. If you don’t need this behavior, you can control it by setting flex-basis.
(after)