Block Editor Theme-related updates in WordPress 5.3

WordPress 5.3 includes a lot of additions and refactoring to existing blocks in order to support new features. Some of this features require special care from theme authors in order to optimize the Block Editor theme integration.

The Group block

A Group block to act as an all-purpose container for other blocks has been introduce. If a theme does not support wide and full alignments, no CSS changes should be necessary. 

If a theme does support for wide and full alignments, some additional theme styles may be required to ensure child blocks appear as intended: depending on how your CSS is written, a theme’s usual alignwide and alignfull styles may not appear as intended when they’re applied inside of a Group block. 

The Group block contains an inner container (wp-block-group__inner-container) to help make styling easier. In many cases, that div can be used as a proxy for entry-content styles, allowing wide and full child blocks to appear as intended without modification. 

To illustrate this, here’s a simplified example of a common method for implementing wide and full block layout on the front end, using negative margins:

.entry-content {
	width: 60vw;
	margin: 0 auto;

.alignwide {
	margin-left: -10vw;
	width: 80vw;

.alignfull {
	margin-left: -20vw;
	width: 100vw;

In this scenario, only a few additional lines of code are necessary to implement Group block styles: 

// Apply entry-content styles to the group block’s inner container as well. 
.wp-block-group__inner-container {
	width: 60vw;
	margin: 0 auto;

// When a group block has a wide alignment, make sure that its full-width children do not extend beyond the width of the container. 
.wp-block-group.alignwide .alignfull {
	margin-left: -10vw;
	width: 80vw;

.alignfull {
	margin-left: -20vw;
	width: 100vw;

// Ensure wide and full-width children do not extend beyond the width of a standard-aligned Group block.
.wp-block-group:not(.alignwide):not(.alignfull) * {
	max-width: 100%;
	margin-left: 0;

Related PRs: 13964.

Reduced Block Styles specificity

In WordPress 5.3, the specificity of block editor CSS has been reduced. Specifically it changes how default block margins are applied, now targeting [data-block]. This should give more control to theme and plugin developers.

By default, all blocks will be born with a base margin. You can set that margin to zero in an editor-style:

[data-block] {
	margin-top: 0;
	margin-bottom: 0;

Related PRs: 14407.

Using class names for text alignment

In the previous versions of WordPress, inline styles were used to change the text alignment for the following core blocks:

  • Heading
  • Paragraph
  • Quote
  • Verse

This produced high CSS specificity making it very hard for theme authors to customize the look of those blocks. WordPress 5.3 uses classnames for text alignment to address these issues:

  • has-text-align-right – when block’s text is aligned to the right
  • has-text-align-center – when block’s text is aligned to the center
  • has-text-align-left – when block’s text is aligned to the left

All previously published posts should work as before. The affected blocks will automatically get converted to use the corresponding class names as soon as they are opened and saved in the block editor.

Related PRs: 16035, 16777, 16779, 16794.

Columns block classnames

The columns block have been updated to support custom widths per column. This led to the removal of the has-x-columns classname. Themes could have potentially relied on this classname to set the width of the columns.

Related PRs: 16129.

Color support for the separator block

The separator block now supports custom colors, this may impact themes that defines the separator color manually in their stylesheets. Themes should assign default colors to the separator only if the user didn’t apply a color explicitly. You can check the fix that was applied to the Twenty Nineteen theme to see how to achieve this.

Related PRs: 16784.

Table block markup update

The table block is now wrapped in a <figure> element, so that <table class="wp-block-table"> has been replaced by  <figure class="wp-block-table"><table>. This is to allow large tables to horizontally scroll within the figure container instead of forcing cell content to break and become unreadable on small screens.

Themes may be impacted by this change if they have used chained selectors like table.wp-block-table for styling. Themes should now instead use .wp-block-table to target the container, or .wp-block-table table to target the table element itself.

Related PRs: 16324.

Gallery block markup update

The gallery block is now wrapped in a <figure> element as well and may optionally contain a <figcaption> as a caption for the whole gallery.

Themes can style the caption using the classname .blocks-gallery-caption. The markup change will affect any themes using chained selectors such as ul.wp-block-gallery to style galleries. Themes should now instead use only .wp-block-gallery to style the container and the new .blocks-gallery-grid classname to style the ul element itself.

Related PRs: 17101.

Props to @kjellr, @joen, @gziolo, @assassinateur and @isabel_brison for helping with this dev note.

#5-3, #core-editor, #core-themes, #dev-notes

What’s new in Site Health for WordPress 5.3

The Site Health component of WordPress covers both the new self-service area under Tools > Site Health, and the error protection which provides means to access a site while it is experiencing technical difficulties.

For WordPress 5.3, a handful of enhancements have been made to both these parts of the component, as well as multiple minor improvements to provide the best possible experience. Let’s cover the more notable changes and features that are now available.

Changes to the grading indicator

Following ticket #47046, modifications have been made to the site grading shown when Site Health Checks are run.

The modified Site Health header with the new grading indicator

The previous iteration included only an indicator and a percentage. This was meant to indicate how many tests were passing, not how perfect a site was. There was also no clear indication that the Site Health checks had not yet completed. The grading circle would pulse, but this was not obvious, nor was a good solution for those who may have a difficulty discerning this subtle change.

To address this, the numbers were removed in favor of two simple states: Should be improved, and Good. As for the indicator while work is being done, the pulsing animation is still there, but the status is shown as Results are still loading… to better relay what is happening on the page.

Observations of how developers extended the page also lead to changes in how the grading is weighted. This means that the existence of a critical issue will always lead to a recommendation of needing improvements. To offset the amount of checks some may add, the recommended results now carry less weight, making them have a lower impact on the overall outcome.

The indicator itself was kept as it is a visual nudge for many users, with the removal of the percentage it no longer has the same negative association, and now serves more as a reminder that work can be done, but the text associated with it lets the user know that it also doesn’t need to happen right this instance, hopefully leading to less mental anguish.

Recovery email enhancements

If a site failure occurs, an attempt to send a recovery email is made, although already a useful tool, if problems persisted, or you as a user had a hard time understanding what was happening, it might be difficult to get help.

To address this, the recovery email now also includes the bare essentials that is useful for debugging a problem if reaching out to any kind of support, added in ticket #48090.

The debug information provided can be modified using the new recovery_email_debug_info filter, the information is provided as an associated array, and by default contains the following information:

  • WordPress version
  • PHP version
  • Current theme and version
  • If a plugin caused the issue: The plugin name and version

A quick example of extending this would be a host wanting to declare which server the error occurred on, in the event that it’s an extension causing issues:

add_filter( 'recovery_email_debug_info', 'myhost_debug_node_name' );
function myhost_debug_node_name( $debug_array ) {
	$debug_array['node_name'] => 'Node: host01-rack03-box11';
	return $debug_array;

Filters for completed Site Health status tests

When a Site Health test has completed, it is now exposed to the new site_status_test_result filter, introduced with ticket #47864.

This is a particularly interesting filter, as it exists both in PHP, for direct tests, and as an identical JavaScript implementation for the asynchronous ones.

In keeping with the host-related examples, consider a site checking for HTTPS, if it isn’t set up, the host can add an action link to their control panel for enabling the feature:

add_filter( 'site_status_test_result', 'myhost_site_health_https_link' );
function myhost_site_health_https_link( $site_health_check ) {
	// If the filtered test is not the `https_status` one, return the original result.
	if ( 'https_status' !== $site_health_check['test'] ) {
		return $site_health_check;

	// Only add our action if the check did not pass.
	if ( 'good' !== $site_health_check['status'] ) {
		$site_health_check['actions'] .= sprintf(
			'<a href="%s">%s</a>',
			esc_attr( 'https://panel.myhost.test' ),
			__( 'Enable HTTPs in MyHost Control Panel', 'myhost' )

	return $site_health_check;

For a full list of changes to the Site Health component in WordPress 5.3, check the full list on trac.

#5-3, #dev-notes

New Block APIs in WordPress 5.3

In addition to a number of improvements and features for the block editor, WordPress 5.3 comes with new Block-related APIs for developers.

Server-side block style variations API

It includes server-side helpers that simplify registering and unregistering block styles.

Previously, in order to register block styles, one was required to write a JavaScript script performing the registration and ensure that the script was enqueued properly. With WordPress 5.3, you can use the register_block_style and unregister_block_style PHP helpers for the whole process.


The register_block_style function receives the name of the block as the first argument and an array describing properties of the style as the second argument.

The properties of the style array must include name and label:

  • name: The identifier of the style used to compute a CSS class.
  • label: A human-readable label for the style.

Besides the two mandatory properties, the styles properties array should also include an inline_style or a style_handle property:

  • inline_style: Contains inline CSS code that registers the CSS class required for the style.
  • style_handle: Contains the handle to an already registered style that should be enqueued in places where block styles are needed.

The following code sample registers a style for the quote block named “Blue Quote”, and provides an inline style that makes quote blocks with the “Blue Quote” style have blue color:

        'name'         => 'blue-quote',
        'label'        => __( 'Blue Quote' ),
        'inline_style' => ' { color: blue; }',

Alternatively, if a stylesheet was already registered containing the CSS for the style variation, it is possible to just pass the stylesheet’s handle so register_block_style function will make sure it is enqueued properly.

wp_register_style( 'myguten-style', get_template_directory_uri() . '/custom-style.css' );

        'name'         => 'fancy-quote',
        'label'        => 'Fancy Quote',
        'style_handle' => 'myguten-style',


unregister_block_style allows unregistering a block style previously registered on the server using register_block_style.

The function’s first argument is the registered name of the block, and the name of the style as the second argument.

The following code sample unregisteres the style named ‘fancy-quote’ from the quote block:

unregister_block_style( 'core/quote', 'fancy-quote' );

Important: The function unregister_block_style only unregisters styles that were registered on the server using register_block_style. The function does not unregister a style registered using client-side code.

Related PRs: 16356.

Block Example API

WordPress 5.3 also includes the ability to preview blocks from the library before inserting them. This can help users figure out at a glance which block they want to insert.

To support this feature in your custom blocks, make sure to define the example property in your block settings.

 const blockSettings = {
  // ... other settings

  example: {
      attributes: { 
          content: __( 'Content of the block' )
      innerBlocks: []


registerBlockType( name, settings );

Related PRs: 17124.

Props to @jorgefilipecosta for helping with this dev note.

#5-3, #core-editor, #dev-notes

Date/Time component improvements in WordPress 5.3

Date/Time component encompasses all input, output, and storage of time and date information. Its code dates back to PHP 4 implementation in an early version and went through partial PHP 5 retrofit.

For over a year and several WP releases, we ran a project dubbed “wp_date” to fix and improve the component. Final parts of this effort will ship with WordPress 5.3.

  1. All existing code will have more correct and reliable operation. We fixed bugs, added unit tests, and corrected inline documentation for many functions.
  2. WP 5.3+ code will get access to the new API functions, for convenience and PHP interoperability.

New API functions

We improved the component’s API, made possible by raising the required PHP version to 5.6 in the core.

Unified time zone retrieval

  • wp_timezone_string() a single way to retrieve site time zone, regardless of settings (timezone_string/gmt_offset options). Might return Region/Location string or ±NN:NN offset. Both are now valid inputs for PHP versions supported by core.
  • wp_timezone() retrieves site time zone as DateTimeZone object.

New date localization

  • titular wp_date() is a ground–up rewrite of date localization with WordPress locale. It works with Unix timestamps and PHP time zone objects.
    • date_i18n() function is now a legacy wrapper around wp_date().

PHP interoperability

  • current_datetime() retrieves current moment of time as DateTimeImmutable object.
  • get_post_datetime() retrieves post time as DateTimeImmutable object.
  • get_post_timestamp() retrieves post time as Unix timestamp.

Phasing out WP timestamps

Date/Time component relied on so–called “WordPress timestamp” — a sum of Unix timestamp with a time zone offset. This was causing many bugs and lack of interoperability with upstream PHP or any external systems. Inline documentation erroneously referred to these as Unix timestamps.

It is impossible to remove WP timestamps without backwards compatibility break. But we made significant progress to:

  • cut their use in core;
  • correct invalid inline documentation;
  • offer new API using real Unix timestamps.

Not recommended

  • don’t retrieve time as WP timestamp:
  • don’t localize time based on WP timestamp:
    • date_i18n( DATE_RFC3339, $timestamp + $offset )
  • don’t store WP timestamps persistently;
  • don’t compare WP timestamps;
  • don’t change PHP time zone with date_default_timezone_set() (this one is hard requirement for correct core operation!)


  • retrieve time as Unix timestamp or DateTimeImmutable object:
    • time()
    • current_datetime()
    • get_post_datetime()
    • get_post_timestamp()
  • localize time based on Unix timestamp:
    • wp_date( DATE_RFC3339, $timestamp )
  • store Unix timestamps or formats that are precise moment in time, such as DATE_RFC3339;
  • compare Unix timestamps, DateTimeInterface objects, or string–comparable dates in same time zone;
  • use DateTimeZone and DateTimeImmutable objects (with wp_date() for localization), if you need to operate with different time zones.


Date/Time core component had received much–needed fixes and a set of improvements. Code on WordPress platform will be more convenient and reliable with times and dates.

If you have questions about the improvements or component in general feel free to drop by #core-datetime channel in WordPress Slack.

#5-3, #dev-notes

Core Widgets: new aria-current attribute in WordPress 5.3

When a page is created and users view it, its name appears in several widgets, however there is no visual or semantic indication that this link relates to the current page.

Since it’s possible for authors to create multiple posts or taxonomy terms with the same name, the lack of indication may cause confusion for users with cognitive disabilities and screen reader users.

Whenever the current page is reflected in a menu on that page, the applicable link should have aria-current="page" attribute to add an indication for users. It is also recommended to use this attribute to add a distinctive visual style to separate the applicable link from other links.

For reference, see the relevant standards in Web Content Accessibility Guidelines 2.0:

Concerned core widgets:

  • Recent Posts
  • Navigation Menu
  • Pages
  • Category
  • Archives

WordPress 5.3 will programmatically add aria-current="page" attributes to those widgets. For reference, see #47094.

Theme authors are encouraged to add a distinctive visual style to those links, using the following CSS declaration:

a[aria-current] {
    /* Your CSS styles for current link */

#5-3, #accessibility, #accessibility-docs, #dev-notes

Integer menu slugs are no longer supported from WordPress 5.3

Previously, menus could be registered with an integer slug. This used to cause unintended issues that are difficult to debug.

Consider the following use of register_nav_menus:

        'primary' => 'Primary', 
        1 => 'First', 
        2 => 'Second',

The assumption is that the resulting list of menus would match what was passed. Instead, the result is this:

    'primary' => 'Primary', 
    0 => 'First', 
    1 => 'Second', 

This would cause wp_nav_menu( array( 'theme_location' => 1 ) ) to return the wrong menu.

From WordPress 5.3, it will trigger a _doing_it_wrong() warning when registering a nav menu with a numeric index. This will at least inform developers of the potential issue, and would also encourage better practices of using a string slug for nav menus.

For reference, see the related Trac ticket: #45361

#5-3, #dev-notes

Changes on Twenty Nineteen HTML structure in WordPress 5.3

In some templates, Twenty Nineteen was using a <main> HTML element which was appearing as a direct descendant of a <section> HTML element. This resulted in markup errors on the following templates:

  • 404.php
  • archive.php
  • image.php
  • index.php
  • page.php
  • search.php
  • single.php

For reference, see HTML specifications:

A hierarchically correct main element is one whose ancestor elements are limited to html, body, div, form without an accessible name, and autonomous custom elements.

Source: HTML Living Standard

WordPress 5.3 will change that behavior by using a neutral <div> element instead of <section>.

Previous HTML rendering example:

<section id="primary" class="content-area">
    <main id="main" class="site-main">

New HTML rendering example:

<div id="primary" class="content-area">
    <main id="main" class="site-main">

WordPress users who are using Twenty Nineteen as a parent theme are encouraged to check their child themes stylesheets are not using selectors like section#primary or section.content-area and to update them to #primary or .content-area if needed.

For reference, see the related Trac ticket: #47066

#5-3, #dev-notes

Changes to prevent search engines indexing sites.

In WordPress 5.3 the method used to discourage indexing will change on sites enabling the option “discourage search engines from indexing this site” in the WordPress dashboard. These changes were made as part of ticket #43590.

These changes are intended to better discourage search engines from listing a site rather than only preventing them from crawling the site.

robots.txt file changes.

In previous versions of WordPress, Disallow: / was added to the robots.txt file to prevent search engines from crawling the site. This has been removed for non-public websites in WordPress 5.3.

As Joost de Valk writes in an explainer on search engine exclusion, disallowing crawling can have the effect of allowing a site to be indexed:

A site doesn’t have to be [crawled] to be listed. If a link points to a page, domain or wherever, Google follows that link. If the robots.txt on that domain prevents [crawling] of that page by a search engine, it’ll still show the URL in the results if it can gather … it might be worth looking at.

Meta tag changes.

Sites with the “discourage search engines from indexing this site” option enabled will display an updated robots meta tag to prevent the site from being listed in search engines: <meta name='robots' content='noindex,nofollow' />.

This meta tag requests search engines exclude the page from indexing and discourages them from further crawling the website.

Excluding development servers from search engines.

The most effective method to exclude development sites from being indexed by search engines is to include the HTTP Header X-Robots-Tag: noindex, nofollow when serving all assets for your site: images, PDFs, video and other assets.

As most non-HTML assets are served directly by the web server on a WordPress site, the core software is unable to set this HTTP header. You should consult your web server’s documentation or your host to ensure these assets are excluded on development sites.

#5-3, #dev-notes