HTML and CSS course Β· Module 4: Flexbox

Shorthand Properties

5 min read Β·
In this lesson4

A container that lays out its elements in a column and wraps them onto a new line takes two separate declarations. An element that should grow, never shrink and start at 200 pixels takes three more. In a stylesheet with dozens of rules, lines like these multiply like scrolls in a temple archive. Egyptian scribes knew the remedy: next to hieroglyphs they used hieratic script, a faster and simplified form of the same signs. CSS has shorthand forms too, and in Flexbox two of them matter most: flex for items and flex-flow for the container.

The flex shorthand - three values in one

The flex property sets three properties of a flex item at once, always in the same order:

  • flex-grow defines how the element should expand when free space is left in the container,
  • flex-shrink defines how the element should shrink when space runs out,
  • flex-basis defines the initial size of the element before the browser starts growing or shrinking it.

The formal syntax from the documentation looks like this: flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]. A single vertical bar means "or", a question mark marks an optional value, and a double bar says that the parts may appear in any order. Even so, stick to the grow, shrink, basis order, because that is how every developer reads it. Let's see the shorthand in action:

.box {
  flex: 1 0 200px;
}

The element with the box class gets flex-grow: 1, so it can expand, flex-shrink: 0, so it cannot shrink, and flex-basis: 200px, so it starts at 200 pixels. Neither the content nor the HTML of the element changes, because the shorthand only sets sizing rules. Watch out for one thing: an element with flex-shrink: 0 will not go below 200 pixels, so on a narrow screen it may stick out of the container.

Omitted values

The shorthand does not have to contain three values. You will also meet one- and two-value forms such as flex: 1 or flex: none. The omitted parts do not fall back to the usual defaults, though: flex: 1 sets flex-basis to 0, not to auto. We will take these forms apart in the next lesson.

The flex-flow shorthand - direction and wrapping together

The second shorthand belongs to the container and combines two properties you already know. flex-direction defines the direction in which elements are placed in the container, and flex-wrap decides whether they should wrap onto a new line when space runs out. The formal syntax is flex-flow: <'flex-direction'> || <'flex-wrap'>, and the default value is row nowrap. Here is an example:

.container {
  flex-flow: column wrap;
}

The container with the container class gets flex-direction: column, so the elements are stacked vertically, and flex-wrap: wrap, so they move to a new line when space runs out. In a column, a new line is another column next to it, and wrapping only kicks in when the container has a limited height. Without one, the column simply keeps growing downwards. Most often, though, you will see flex-flow: row wrap, a horizontal row that wraps like consecutive shelves in a treasury.

Shorthand and align-content

When flex-flow includes wrap, the container can end up with several lines. Remember from the previous lesson who controls them? align-content distributes whole lines along the cross axis, just as justify-content distributes individual items along the main axis. It only works in a container with wrapping turned on:

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: center;
  height: 400px;
}

The rows of items gather in the middle of the tall container. The height is needed here, because align-content only distributes the free space on the cross axis. Items within a single row are still positioned by align-items, while align-content moves whole rows at once.

When to use shorthands?

Shorthand forms let you describe the flexibility and layout of elements more concisely, and your CSS becomes easier to read. My advice: reach for flex whenever you set more than one of the three values. The Flexbox specification itself recommends the shorthand over the separate properties, because it also sets correctly what you did not write. With flex-flow it depends: when you change both settings, the shorthand is handy, but when you only want wrapping, flex-wrap: wrap on its own says more. In the next lesson we will take flex apart and calculate how the browser shares out free space.

In the editor below, each row shows a different flex-basis value. Replace the flex-basis and flex-grow pairs with a single shorthand, for example flex: 1 1 100px, and check that the layout does not change.

Code for this lesson: index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox - Flex Basis</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>Flex Basis - Base Size of Elements</h1>
        <p class="subtitle">Define the initial element size before distributing space</p>

        <section class="demo-section">
            <h2>flex-basis: auto (default)</h2>
            <div class="flex-container">
                <div class="flex-item basis-auto">Short</div>
                <div class="flex-item basis-auto">Longer text in element</div>
                <div class="flex-item basis-auto">Medium</div>
            </div>
            <p class="description">Size is based on element content</p>
        </section>

        <section class="demo-section">
            <h2>flex-basis: 0</h2>
            <div class="flex-container">
                <div class="flex-item basis-zero grow">Short</div>
                <div class="flex-item basis-zero grow">Longer text in element</div>
                <div class="flex-item basis-zero grow">Medium</div>
            </div>
            <p class="description">All elements start from zero and grow evenly</p>
        </section>

        <section class="demo-section">
            <h2>flex-basis: Fixed values</h2>
            <div class="flex-container">
                <div class="flex-item basis-100">basis: 100px</div>
                <div class="flex-item basis-200">basis: 200px</div>
                <div class="flex-item basis-150">basis: 150px</div>
            </div>
            <p class="description">Each element has a defined base size</p>
        </section>

        <section class="demo-section">
            <h2>flex-basis: Percentages</h2>
            <div class="flex-container">
                <div class="flex-item basis-25">25%</div>
                <div class="flex-item basis-50">50%</div>
                <div class="flex-item basis-25">25%</div>
            </div>
            <p class="description">Base sizes as a percentage of the container</p>
        </section>

        <section class="demo-section">
            <h2>flex-basis + flex-grow</h2>
            <div class="flex-container">
                <div class="flex-item basis-100 grow">basis: 100px + grow: 1</div>
                <div class="flex-item basis-50 grow">basis: 50px + grow: 1</div>
                <div class="flex-item basis-100 grow">basis: 100px + grow: 1</div>
            </div>
            <p class="description">Elements start from different sizes and grow evenly</p>
        </section>

        <section class="demo-section practice">
            <h2>Practice: Egyptian containers</h2>
            <p class="practice-description">Storing grain in granaries of different base sizes</p>

            <div class="granary">
                <div class="storage small-storage">
                    <div class="lid">β—“</div>
                    <div class="content">
                        <p>Small granary</p>
                        <p class="size">basis: 80px</p>
                    </div>
                </div>

                <div class="storage medium-storage">
                    <div class="lid">β—“</div>
                    <div class="content">
                        <p>Medium granary</p>
                        <p class="size">basis: 150px</p>
                    </div>
                </div>

                <div class="storage large-storage">
                    <div class="lid">β—“</div>
                    <div class="content">
                        <p>Large granary</p>
                        <p class="size">basis: 220px</p>
                    </div>
                </div>

                <div class="storage flexible-storage">
                    <div class="lid">β—“</div>
                    <div class="content">
                        <p>Flexible</p>
                        <p class="size">basis: 0 + grow: 1</p>
                    </div>
                </div>
            </div>
        </section>
    </div>
</body>
</html>

Remember: a shorthand is the hieratic script of CSS, with the same meaning as the full notation, only written faster and more concisely.

Docs entries used in this lesson

Spotted a mistake in this lesson?

Hands-on tasks in the game

  • Click in order

    Arrange the shorthand flex-flow declaration that sets vertical direction with wrapping:

  • Code editor

    Create a flex container with flex-wrap: wrap and multiple elements, then use align-content: center to vertically center the rows.

  • Vertical ordering

    Arrange the CSS rule that creates a multi-row Flexbox container with centered rows:

Useful articles