Live examples are available at http://standardista.com/flexbox/flexfiles. You can either click the icon while reading this book to go directly to a live version of the code example referenced, or visit the link for a list of all of the code examples found in these chapters.
Flexbox was designed for a specific type of layout, that of single-dimensional content distribution.
The display, flex-direction, flex-wrap, and flex-flowproperties impact the ordering and orientation of the flex container. The justify-content, align-items, and align-contentproperties can be applied to the flex container to impact the alignment of the container’s children.
FLEX-FLOW
Values: <flex-direction> || <flex-wrap>
Initial value: row nowrap
Applies to: Flex containers
Inherited: No
Percentages: Not applicable
Animatable: No
FLEX-DIRECTION
Values: row | row-reverse | column | column-reverse
Initial value: row
Applies to: Flex containers
Inherited: No
Percentages: Not applicable
Animatable: No
flex-direction: row
will lay the flex items in the same direction as the text direction, also known as the writing mode, whether it’s a RTL or LTR language. While most websites are presented in left-to-right languages, some sites are in right-to-left languages, and yet others are top to bottom. With flexbox, you can include a single layout. When you change the writing mode, flexbox takes care of changing the flex direction for you.
The writing mode is set by the writing-mode, direction, and text-orientation properties or the dir attribute in HTML. When the writing mode is right to left — whether set in HTML with the dir="rtl"
attribute/value pair or via CSS with direction: rtl;
— the direction of the main axis, and therefore the flex items within the flex container, will go from right to left by default or when the flex-direction: row
is explicitly set.
The writing-mode property specifies the block flow direction, defining whether lines of text are laid out horizontally or vertically and the direction in which blocks progress. It defines the direction in which block-level containers are stacked and the direction in which text and other inline-level content flows within a block container. It is appropriate to use writing-mode for top to bottom languages, and to rotate text. Don’t use writing-mode to override the direction simply for layout reasons: instead, use the flex-direction property.
Flex items are laid out along the main-axis. Flex lines are added in the direction of the cross-axis. The “main-” terms have to do with flex items. The “cross-” terms come into play on multiline flex containers: when wrap or wrap-reverse is set and the flex items actually wrap onto more than one line.
Table 2-2. Dimensions and directions of the main- and cross-axis, along with their start point, end points, and directions in left-to-right layout
It is recommended to use the dir
attribute and CSS writing-mode
property because HTML’s dir attribute concerns HTML content, and the writing-mode property concerns layout.
The justify-content
property controls how flex items in a flex line are distributed along the main-axis. The align-content
defines how flex lines are distributed along the cross-axis of the flex container. The align-items
property defines how the flex items are distributed along the cross-axis of each of those flex lines.
The justify-content property enables us to define how flex items will be distributed along the main-axis of the flex container.
The layout when there is negative free space should now be more intuitive:
• flex-start
and space-between
overflow at main-end.
• flex-end
overflows at main-start.
• center
and space-around
overflow on both ends.
ALIGN-ITEMS
With the align-items
property, you can align flex items to the start, end, or center of the cross-axis of their flex line. Set on the container element, align-items
is similar to justify-content but in the perpendicular direction, setting the cross-axis alignment for all flex items.
While align-items
sets the alignment for all the flex items within a container, the align-self
property enables overriding the alignment for individual flex items.
The general idea is flex-start
places the flex items on the cross-start, flex-end
puts them on the cross-end edge, center
centers them on the cross-axis, the default stretch
stretches the flex item from cross-start to cross-end, and baseline
looks similar to flex-start but actually lines up the baselines of the flex items and then pushes the group of flex items toward cross-start.
The default and the explicitly set align-items: stretch
stretches all the stretchable flex items in a line to be as tall or wide as the tallest or widest flex item on the line. What does “stretchable” mean? While by default all the flex items will stretch to take up 100% of the cross-size, if min-height, min-width, max-height, max-width, width, or height are set, those properties will take precedence.
The cross-size of the flex items includes the margins.
align-items: flex-start
The flex-start value lines up each flex items’ cross-start edge flush against the cross-start edge of their flex line. The flex item’s cross-start edge is on the outside of the margin: if a flex item has a margin that is greater than 0, flex item will not appear flush with the flex line’s cross-start edge
Setting align-items: flex-end
will align the cross-end edge of all the flex items along the cross-end edge of the line they are in.
The baseline
value may be a little more confusing. With baseline, the flex items in each line are all aligned at their baselines, which is basically the bottom of the first line of text, if there is any. The flex item on each flex line with the biggest distance between its baseline and its cross-start margin edge is placed flush against the cross-start edge of the line, with all other flex items’ baselines lined up with the baseline of that flex item.
The align-content property aligns a flex container’s lines within a flex container that has extra space in the cross-axis direction, and dictates which direction will have overflow when there is not enough room to fit the flex lines.
ALIGN-CONTENT
The align-content
property allows us to dictate how any extra cross-direction space in a flex container is distributed between and around flex lines. This is different from the previously discussed align-items property which dictates flex item positioning within each flex line.
The align-content
property determines how flex lines are aligned within a multi-line flex container. When there is extra space in the cross-axis direction, you can dictate whether the lines are grouped at cross-start, cross-end, centered, or stretched to take up all the available space, or distributed across the flex container with the extra space distributed between or around the flex lines.
Think of align-content as similar to how justify-content aligns individual items along the main-axis of the flex container, but for flex lines across the cross-axis of the container. This property only applies to multiline flex containers, having no effect on nonwrapping and otherwise single-line flex containers.
The absolutely-positioned children of flex containers, just like any other absolutely-positioned element, are taken out of the flow of the document.
They do not get converted to flex items. They are not in the document flow. They do not participate in flex layout. However, they can be impacted by the properties set on the flex container, just like a child can be impacted by a parent element that isn’t a flex container. In addition to inheriting inheritable properties as they would had the parent not been a flex container, the parent’s properties impact the origin of the positioning.
The absolutely positioned child of a flex container is impacted by both the justify-content value of the parent flex container and its own align-self value, if there is one. For example, if you set align-content: center; on the absolutely positioned child, it will by default be centered on the flex container parent’s cross-axis.
The flex
shorthand property, along with its component properties of flex-grow
, flex-shrink
, and flex-basis
, control the flexibility of the flex items. The align-self
helps control a flex item’s alignment. The order
property provides for more granular control of the visual ordering of individual or groups of flex items.
The flex
property specifies the components of a flexible length: the “length” of the flex item being the length of the flex item along the main-axis. When a box is a flex item, flex is consulted instead of the main-size (height or width) property of the flex item to determine the size of the box. The “components” of the flex property include the flex growth factor, flex shrink factor, and the flex basis. If the target of a selector is not a flex item, applying the flex property to it will have no effect.
When the flex property declaration explicitly sets or defaults the flex-basis to 0 px and a flex item’s growth factor is 0, the length of the main-axis of the nongrowing flex items will shrink to the smallest width the content allows, or smaller.
Only declaring flex-grow means flex-basis defaults to auto. When set to auto, only the extra space, not all the space, is distributed proportionally. This lack of simplicity is why it is highly encouraged to always use the flex shorthand instead of flex-grow, flex-shrink, and flex-basis separately or not at all.
When omitted in the shorthand flex property value or when both flex and flex-shrink are omitted, the shrink factor defaults to 1.
Because the flex property’s shrink factor reduces the width of flex items proportionally, the number of lines of text in the flex items will grow or shrink as the width shrinks or grows, leading to similar height content within sibling flex items when the shrink factors are similar.
In Figure 3-9, we are trying to fit 1,000 pixels into a 750 px-width flex container. We have an excess of 250 px to be removed from five shrink factors.
the first and last flex items had a width of 250 px and the middle flex item had a width of 500px.
We have 250 px of negative space to proportionally distribute. To get the shrink factor proportions, we divide the negative space by the actual space times their shrink factors:
Using this equation, we learn the shrink factor percent:
= 250px / ((250px * 1) + (500px * 1) + (250px * 3))
= 250px / 1500px
= 0.166666667
We get flex items that are 208.33 px(即250px * (1 - 0.16666667)
), 416.67 px, and 125 px wide, respectively.
When flex-basis is
set, instead of flex, flex items can shrink but will not grow, as if flex: 0 1 <flex-basis>
were set.
By default, when an element is not a flex item, the size is determined by the size of its parent, content, and box-model properties. When no size properties are explicitly declared or inherited, the size defaults to its individual content, border, and padding, which is 100% of the width of its parent for block-level elements.
You can tell a flex item to inherit the flex-basis
from its parent with the inherit
value.
The global values of initial resets the flex basis to the initial value of auto, so you might as well declare auto. In turn, auto evaluates to the width (or height) if declared. If the value of width (or height) is set to auto, then the value is evaluated to content.
When set to auto, or omitted, the flex-basis is the main-size of the node had the element not been turned into a flex item. For length values, flex-basis resolves to the width or height value, with the exception that when the value of the width or height is auto, the value resolves to content.
If the basis is explicitly set to auto, or omitted and therefore defaults to auto, and all the flex items can fit within the parent flex container, the flex items will be their pre-flexed size.
When there are both flex-basis and width values, the basis trumps the width.
While the declared basis can override the main-size of flex items, the size can be impacted by other properties, such as min-width, min-height, max-width, and max-height. These are not ignored.
Remembering that “auto” is the width of the nonwrapping content
If neither the flex-basis
property nor the flex shorthand is included at all, the basis defaults to auto. When the flex property is included, but the basis component of the shorthand is omitted from the shorthand, the basis defaults to 0%.
It is only the extra space that is distributed proportionally based on the flex growth factors. In the case of flex-basis: auto;, the basis is the main size of their content. If the basis of each of the flex items is 0, the “available” space is all the space, or main-size of the parent flex container. This “available” space is distributed proportionally based on the growth factors of each flex item. In the case of a basis of 0%, the size of the container is divided up and distributed proportionally to each flex item based on their growth factors — their default original main-size as defined by height, width, or content, is not taken into account, though min-width, max-width, min-height, and max-height do impact the flexed size.
flex: initial
This value sizes flex items based on the width/height properties, while allowing shrinking.
flex: auto
This flex value also sizes flex items based on the width/height properties, but makes them fully flexible, allowing both shrinking and growing.
flex: none
This value again sizes flex items based on the width/height properties, but makes them completely inflexible: they can’t shrink or grow.
flex: n
This value doesn’t care about the width/height values as the shrink factor is set to 0. In this case, the flex item’s size is be proportional to the flex factor n.
Setting flex: auto; on a flex item is the same as setting flex: 1 1 auto. The following two statements are equivalent:
flex: auto;
flex: 1 1 auto;
Setting flex: none
is equivalent to setting flex: 0 0 auto, making the following two lines of CSS equivalent:
flex: none;
flex: 0 0 auto;
The flex: none items are inflexible: the flex items will neither shrink nor grow.
The basis resolves to auto, meaning each flex item’s main-size is determined by the main-size of the node had the element not been turned into a flex item: the flex-basis resolves to the width or height value. If that value resolved to auto, the basis would be the main-size of the content.
flex: n
When the values of the flex property is a single, positive numeric value, that value will be the growth factor, while the shrink factor will default to 0(备注:flex-shrink现在已经默认成了1), and the basis will default to 0%:
flex-grow: n;
flex-shrink: 0;
flex-basis: 0%;
The following two CSS declarations are equivalent(备注:flex-shrink现在已经默认成了1):
flex: 3;
flex: 3 0 0%;
In the case of all the flex items having flex: n declared, where n is a single or variety of positive numbers, the growth will be proportional based only on n, not on the underlying main size, as the basis for each flex item is 0.
When flex-basis is set to auto, as shown in the first example in Figure 3-25, the main-size of each flex item is based on the content. Looking at the growth factor, you may have thought the middle item would be the narrowest as the growth factor is the smallest, but there is no “growing.” In this example there is no available distributable space. Rather, they’re all shrinking equally as they all have the same shrink factor and the basis of auto means the basis is the width of the content. In this case the flex items’ content are all of equal height, as the size of each is based on the flex basis, rather than the growth factor.
In the second example in Figure 3-25, the basis is 0%, so the main-size is determined by the various growth factors. In this case, the first flex item, with flex: 2 1 0% is twice as wide as the second flex item with flex: 1 1 0%. This second item, in turn, has a main-size that is one-third as wide as the last flex item with flex: 3 1 0%;.
We included a shrink factor in this example to make it parallel to the the first example, but it was completely not necessary. When using a 0 (or 0%) basis, the shrink factor has no impact on the main-size of the flex items. We could have included any of the three statements in each declaration:
item1 {
flex: 2 1 0%;
flex: 2 0 0%;
flex: 2;
}
item2 {
flex: 1 1 0%;
flex: 1 0 0%;
flex: 1;
}
item3 {
flex: 3 1 0%;
flex: 3 0 0%;
flex: 3;
}
The align-self
’s default value of auto, meaning they inherit the alignment from the container’s align-items property.
The value of the order property specifies which ordinal group the flex item belongs to. Any flex items with a negative value will appear to come before those defaulting to 0 when drawn to the page, and all the flex items with a positive value will appear to come after those defaulting to 0. While visually altered, the source order remains the same. Screen readers and tabbing order remains as defined by the source order of the HTML.
Remember, the flex property, including the basis (see “The flex-basis Property”), is set on the flex items, not the container.