WordPress.org

WordPress Developer Blog

A walk-through of layout classes in WordPress 6.1

WordPress 6.1 introduced several necessary changes to its layout framework. Namely, core has now centralized its layout definitions, created semantic class names, and reduced code duplication on container blocks.

Originally, this post was intended to be a quick look at the changes to the system for theme authors. However, given the heftiness of the topic, it has evolved into a full overview of the layout framework.

The primary goals for this walk-through are to provide developers with an overall view of the system and to know which classes are able to be targeted via CSS.

Layout-related classes are given to container-type blocks in WordPress. They define how nested blocks are aligned within their parent.

Most extenders will immediately associate layout classes with the Group block and its Row and Stack variations. However, WordPress uses the classes for other blocks, such as Social Icons, Navigation, and Buttons. Layouts may also be used with third-party blocks, even though support is currently marked as an experimental feature.

The following list is a bird’s-eye view of the currently-available classes in WordPress 6.1. Most of the class names should describe their roles, but don’t worry if you don’t understand all of them yet. In this walk-through, you will learn what each does.

  • Layout Classes:
    • is-layout-constrained
    • is-layout-flow
    • is-layout-flex
  • Flex Orientation (Direction) Classes:
    • .is-vertical
    • .is-horizontal
  • Content Justification Classes:
    • .is-content-justification-left
    • .is-content-justification-center
    • .is-content-justification-right
    • .is-content-justification-space-between
  • Flex Wrap Classes:
    • .is-nowrap
  • Container Classes:
    • .wp-container-{id}

Block gaps and vertical rhythm

Before diving into each layout type, it’s important to understand how vertical spacing between blocks works. Much of the system relies on this feature.

As any good designer will tell you, vertical rhythm is a crucial aspect of any design. And vertical spacing between elements, while only one aspect of the rhythm, plays a vital part in getting the design right.

In WordPress, this is the blockGap property. Do not let the name confuse you. While it maps to the CSS gap property in some layouts, it is also used to set margin-block-start in others.

Any theme can set the default via styles.spacing.blockGap in their theme.json, as shown in the following code snippet:

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 2,
    "styles": {
        "spacing": {
            "blockGap": "2rem"
        }
    }
}

Themes can also target the blockGap property for blocks that support it. The following code example shows how to set the default spacing while customizing it for the Group block:

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 2,
    "styles": {
        "spacing": {
            "blockGap": "2rem"
        },
        "blocks": {
            "core/group": {
                "spacing": {
                    "blockGap": "1rem"
                }
            }
        }
    }
}

There may be edge cases where you need to overrule the default via CSS. For those scenarios, it’s typically best to change the value of the --wp--style--block-gap CSS property rather than targeting a block’s gap or margin. You would do this as shown in the following CSS code:

.some-target-class {
    --wp--style--block-gap: 3rem;
}

That may not always work. If a block (via theme.json) or user (via the interface) has defined a specific value for blockGap, that value will be used instead of the CSS property. In those cases, you should not attempt to overwrite the choice via CSS.

With an understanding of how the space between blocks is defined, you now have the foundation for seeing how that operates within different layout types.

Constrained and flow layouts

Both of these layout types are technically flow layouts. This is how browsers handle the normal flow of a webpage without any intervention from CSS. WordPress defines the spacing between blocks by applying the blockGap value to the margin-block-start property of nested blocks (margin-block-end is zeroed out).

There is one key difference between the two layouts in WordPress:

  • Nested blocks within a constrained layout are limited by the theme’s content width by default (this can be overwritten with wide/full alignments).
  • Nested blocks within a flow layout fill up the width of their parent block.

As of WordPress 6.1, the constrained layout type is the default for the Group block. Other blocks may define different defaults.

In the following screenshot, you can see a wide-aligned Group block with a Paragraph and Image nested inside. However, these child blocks are “constrained” to the content width by the Inner blocks use content width setting in the sidebar:

If you toggle the switch for Inner blocks use content width to the off position, the layout would become a “flow” layout.

WordPress handles all of this out of the box. Theme authors should primarily be aware of the classes associated with each layout, which are .is-layout-constrained and .is-layout-flow. For the majority of use cases, there will never be a need to use those. However, when you need to style blocks or elements specifically within those layouts, target the specific layout class.

Flex layouts

Flex layouts in WordPress work on the Flexbox system in CSS. In reality, it is a limited subset of what is possible with Flexbox that fits within WordPress’ design framework.

One major difference between flex and constrained/flow layout types is how they handle block spacing. Instead of applying the blockGap value to a block’s margin-block-start property, the value is applied to the containing block’s gap property. Flex layouts also have options between vertical and horizontal layouts.

Several container-type blocks have flex layouts by default, including:

  • Buttons
  • Social Icons
  • Navigation

Looking at the Group block example from earlier, you should see Layout variations for creating a Stack and Row in the block inspector. Take a look at the Row variation, which has a horizontal layout:

If the Stack variation had been chosen, the blocks would have been aligned vertically.

With the addition of vertical and horizontal options, there are a few layout-specific classes that theme authors can target when necessary:

  • .is-layout-flex: Whether the layout has the flex type.
  • .is-vertical: Whether the layout has a vertical orientation.
  • .is-horizontal: Whether the layout has a horizontal orientation.

Those last two map to the flex-direction CSS property. Horizontal layouts are given the row value and vertical layouts the column value.

Note: The the default orientation for a block may not exist as a class in the block’s HTML, so you would need to target the layout class directly in that case.

Flex layouts also have another option to disallow nested blocks from wrapping to a new line as they grow. This is tied to the flex-wrap CSS property. The default value is for blocks to wrap, which is noticeable as you add multiple blocks to a horizontal layout. However, this can be disabled via the editor. In those cases, WordPress applies the .is-nowrap class to the element.

Content Justification

In WordPress 6.1, the constrained and flex layout types both have content justification classes. These handle how the nested elements are aligned within their parent block.

Looking at the same example Group block from earlier, the following screenshot has a constrained layout with the content justified right:

There are four different content justification options for container blocks, each with their own CSS class:

  • .is-content-justification-left: Nested blocks are aligned left.
  • .is-content-justification-center: Nested blocks are aligned center-aligned.
  • .is-content-justification-right: Nested blocks are aligned right.
  • .is-content-justification-space-between: Nested blocks are allowed to spread evenly with equal space between each. For flex layouts only.

Avoid .wp-container-* Classes

Some blocks may have a .wp-container-* class attached to them. In the past, there have been instances when it was necessary to target those classes to address some shortcoming of the layout system. However, this should be avoided altogether. There is no way to know whether the classes will exist in the future or whether their behavior will change.

Always opt for one of the specific classes outlined earlier. They are the standard going forward.

Future Layout Types

CSS allows for all types of layouts, so it should be interesting to see what the future of the block editor brings—perhaps even a grid layout type. The goal is not necessarily to cover every potential use case. Rather, it is to offer a solid foundation that can be iterated upon as the web continues to change.

The layout system in WordPress is still marked as an “experimental” block feature, which means it is under active development. However, WordPress 6.1 has brought us one step closer to a well-rounded and standard framework for how current and future layouts will work.

Resources to learn more

Props to @bph and @daisyo for feedback and review.

4 responses to “A walk-through of layout classes in WordPress 6.1”

  1. Jessica Avatar
    Jessica

    What about responsiveness? Flex-wrap isn’t always a sufficient option.

    1. Justin Tadlock Avatar

      Can you provide more details on what you want to do? The question isn’t specific enough to accurately reply.

  2. Matt Pettefer Avatar
    Matt Pettefer

    Gutenberg is erasing all margins between paragraphs in a core/group no matter how many places I set blockGap in theme.json. And no matter what the settings are for the blocks.

  3. Matt Pettefer Avatar
    Matt Pettefer

    Revised: it works fine with only paragraphs but if the group contains another group containing the header it breaks all the blockGaps.

Leave a Reply

Your email address will not be published. Required fields are marked *