Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Understanding the Drupal 11.4 Change: Block Content Attributes Moved to the Content Wrapper

By admin, 10 May, 2026

With the release of Drupal, an important rendering behavior has changed for block content render arrays. If your custom modules or themes rely on #attributes in block render arrays, this update may affect your frontend output.

The change was introduced in the Drupal core issue:

“Attributes of a block content are applied to block itself” (#2486267)

This article explains what changed, why it matters, and how to update your code correctly.


What Changed?

Before Drupal 11.4, attributes defined in a block render array under #attributes were automatically merged into the outer wrapper of the entire block.

Starting from Drupal 11.4, those attributes are now applied to the inner content wrapper instead.

To target the outer block container, developers must now use #wrapper_attributes.


Previous Behavior (Before Drupal 11.4)

Example render array:

return [
  '#attributes' => [
    'class' => [
      'foo',
    ],
    'data-content-custom' => 'bar',
  ],
  '#wrapper_attributes' => [
    'data-wrapper-custom' => 'baz',
  ],
  '#markup' => 'Sample content',
];

Generated HTML:

<div id="block-foobartest"
     class="foo"
     data-content-custom="bar"
     data-wrapper-custom="baz">

  <div class="content">
    Sample content.
  </div>
</div>

Here, everything from #attributes was merged into the outer block wrapper.


New Behavior in Drupal 11.4+

The same render array now produces:

<div id="block-foobartest"
     data-wrapper-custom="baz">

  <div class="content foo"
       data-content-custom="bar">

    Sample content.
  </div>
</div>

Now:

  • #wrapper_attributes → applied to the outer block wrapper
  • #attributes → applied to the .content wrapper

Why This Change Was Made

This behavior is more semantically correct and predictable.

Previously, developers often expected:

  • #attributes → content-level attributes
  • #wrapper_attributes → wrapper/container attributes

But Drupal internally merged both onto the outer block container, creating confusion and inconsistencies.

The new behavior clearly separates:

PurposeProperty
Entire block container#wrapper_attributes
Inner block content#attributes

This makes block rendering easier to reason about and aligns better with render API expectations.


Who Is Affected?

This change impacts:

  • Custom module developers
  • Theme developers
  • Site builders using preprocess hooks
  • Anyone injecting classes/data attributes into block render arrays

Especially affected:

  • CSS selectors targeting block wrappers
  • JavaScript relying on wrapper-level data attributes
  • Layout Builder integrations
  • Custom Twig templates expecting wrapper classes

Common Problems After Upgrading

After updating to Drupal 11.4, you may notice:

CSS styles stopped working

Example:

.foo {
  margin-bottom: 20px;
}

Previously .foo was on the outer block wrapper.

Now it is attached to .content.


JavaScript selectors break

Example:

document.querySelector('[data-content-custom]');

The attribute may now exist deeper in the DOM than expected.


Layout/styling inconsistencies

Flexbox, grid, spacing, or container-level styling may shift because classes moved from parent wrappers to child content wrappers.


How to Fix Existing Code

If you intended attributes to apply to the outer block wrapper, move them to #wrapper_attributes.

Old code

return [
  '#attributes' => [
    'class' => ['hero-block'],
  ],
];

Updated code

return [
  '#wrapper_attributes' => [
    'class' => ['hero-block'],
  ],
];

Recommended Best Practice Going Forward

Use:

'#wrapper_attributes'

for:

  • Layout classes
  • Grid/flex container behavior
  • Wrapper-level JavaScript hooks
  • Spacing utilities

Use:

'#attributes'

for:

  • Content styling
  • Inner content behavior
  • Accessibility attributes related to content
  • Content-specific JS targeting

Migration Checklist

After upgrading to Drupal 11.4:

  • Audit custom block plugins
  • Review preprocess functions
  • Check custom themes
  • Test JavaScript selectors
  • Inspect rendered HTML in browser DevTools
  • Search for #attributes usage in block render arrays

Useful command:

grep -R "#attributes" web/modules/custom

Final Thoughts

This is a relatively small change in Drupal core, but it can have a noticeable impact on frontend behavior in existing projects.

The good news is that the migration path is straightforward:

  • Wrapper attributes → #wrapper_attributes
  • Content attributes → #attributes

Once updated, your render arrays will be more explicit, maintainable, and aligned with Drupal’s rendering architecture moving forward.

Tags

  • Drupal
  • PHP
  • CMS
  • Open Source

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal