Block Model Version 3#
Summary#
Block Model v3 introduces a unified container architecture (block anatomy) that ensures consistent styling and spacing between View and Edit modes. This eliminates the previous issues where Edit mode appeared different from the View and simplifies CSS by providing a standardized two-level container system.
Key Benefits:
Consistent rendering across View and Edit modes
Simplified CSS with standardized container structure
Improved spacing control through block categories
Reduced maintenance overhead
Visual Architecture#
┌────────────────────────────────────────────────────────────┐
│ Main/Outer Container (.block.${type}.category-${category}) │
│ • Full width (edge to edge) │
│ • Background color & theme variables │
│ • Vertical spacing via padding on BG color changes │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Secondary/Inner Container (.block-inner-container) │ │
│ │ • Content width & horizontal centering │ │
│ │ • Default vertical spacing between blocks │ │
│ │ • Content alignment via CSS Grid │ │
│ │ │ │
│ │ [Block Content Here] │ │
│ │ │ │
│ └───────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
History and Evolution#
Block Model (v1)#
The block contained all rendering information but required exhaustive, error-prone rules that were difficult to maintain comprehensively.
VLT Block Model (v2)#
Introduced block wrappers in view mode with grouped properties, background colors, and containers. This simplified CSS significantly but created inconsistency between view and edit modes, making them appear different due to wrapper structures conflicting with drag-and-drop functionality.
Current Edit Mode Structure#
<div
style="$StyleWrapperStyles"
class="block-editor-{$type} $StyleWrapperClassNames"
>
<div style="position: relative;">
<div class="drag handle wrapper" />
<div class="ui drag block inner $type">
<div class="block $type selected">
<div class="block $type">
{Edit component}
</div>
</div>
<button class="ui basic icon button delete-button" />
<button class="ui basic icon button block-add-button new-add-block" />
</div>
</div>
</div>
Block Model v3 Solution#
Provides identical container structures in both View and Edit modes, enabling unified CSS that works consistently across both rendering contexts–a cross-contextual block. It relies heavily on the Sidebar Order tab to move blocks on the page.
Container Architecture#
Main/Outer Container#
Purpose: Handles block positioning within the page layout and applies theme styling.
Characteristics:
Full width: Must extend from left edge to right edge of page
No horizontal spacing: Must not have horizontal margin or padding
Vertical spacing only: Uses padding (not margin) to maintain background color consistency
Theme integration: Receives injected classNames and styles from StyleWrapper
CSS Classes: .block.${type}.category-${category}
Secondary/Inner Container#
Purpose: Manages content width constraints and provides consistent inter-block spacing.
Characteristics:
Content width control: Can use full width (e.g., Slider) or constrained width (e.g., text blocks)
Horizontal centering: Uses CSS Grid with
place-contentfor alignmentVertical spacing: Provides default spacing between blocks via
padding-bottom, which can be adjusted based on the blocks' category.Content alignment: Supports alignment options through CSS variables
CSS Class: .block-inner-container
Block Categories#
Block categories determine spacing relationships and default behaviors between adjacent blocks based on their category attribute available at config.blocks.blocksConfig.[$type].category.
Spacing Rules#
Vertical spacing between blocks is provided by the upper block following this convention:
Block content, in general, should be flush with the top of its container
Bottom padding creates space for the following block
Different category combinations may have specific spacing adjustments
As a general rule, if the block's content requires internal spacing in all possible cases, then it should be applied to the content itself. Otherwise, it is recommended to rely on the block category system to manage spatial relationships between blocks.
Implementation#
View Mode Structure#
<div
style="$StyleWrapperStyles"
className="block $type category-$category $StyleWrapperClassNames"
>
<div className="block-inner-container">
{View component}
</div>
</div>
Edit Mode Structure#
<div
style="$StyleWrapperStyles"
className="block $type category-$category $StyleWrapperClassNames"
>
<div className="block-inner-container">
{Edit component}
</div>
<div className="block-edit-helpers">
{/* Delete block button, move block buttons, etc. */}
</div>
</div>
CSS Framework#
.block {
background: var(--theme-color, --background-color);
color: var(--theme-foreground-color, --font-color);
.block-inner-container {
@include default-container-width(); /* This mixin sets a max-width and left/right margins to auto */
display: grid;
/* Spacing between sibling blocks, this is the place to increase spacing based on block categories */
padding-bottom: $block-vertical-space; /* Default spacing between blocks */
/* Generic content alignment */
place-content: var(--block-alignment, start);
}
}
Block Component Simplicity#
Block Model v3 aims for simplicity in block components. A button block should be just a <button> element, no additional wrappers or styling divs. The standardized container system, through general use block widgets, handles all layout, spacing, backgrounds, and theme integration, allowing block developers to focus purely on content and functionality.
Configuration#
Project-Level Configuration#
Set config.settings.blockModel: 3 to enable v3 for all compatible blocks.
Block-Level Configuration#
Individual blocks can opt into v3 via config.blocks.blocksConfig.[$type].blockModel: config.settings.blockModel.
Block Category Configuration#
Block categories are available at config.blocks.blocksConfig.[$type].category.
⚠️ Important: It is recommended to only set project-level block model to 3 when all blocks in the registry are v3-compatible (indicated by banner in block's GitHub repository).
Compatibility Considerations#
Block Model v3 is introduced as opt-in to maintain backward compatibility with existing implementations.