Theme-focused changes and filters in WordPress 5.9

A few theme-related notes are already published in the Miscellaneous Core Changes developer note, including:

  1. The comment text field is now marked as required, and some themes that have special styling for the asterisk or that create a custom logged_in_as or comment_notes_before message may have a reason to update.
  2. The role="navigation" attribute is removed from <nav> elements.

The following changes are especially relevant to theme authors as well.

A CSSCSS Cascading Style Sheets. custom property to offset the adminadmin (and super admin) toolbar height

This new custom property, --wp-admin--admin-bar--height, reflects the admin bar’s height and adjusts responsively on smaller screens. Offsetting content can prevent the admin bar from overlapping it, without needing to copy the media query.

Adjusting for fixed headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. navigation

When clicking “Continue reading” or “Skip to content” links, a header fixed to the top of the page can cover where that content starts.

With the --wp-admin--admin-bar--height CSS variable and scroll padding, modern browsers can compensate for the admin toolbar (when it shows). The toolbar offset of 32 or 46 pixels—depending on screen width—is available on the front end without editing the theme:

html {
	scroll-padding-top: var(--wp-admin--admin-bar--height);

Themes that have a fixed header element can add to that. For example, Twenty Seventeen has a fixed header 72 pixels tall, so the scroll padding for the theme includes that measurement:

html {
	scroll-padding-top: calc( var(--wp-admin--admin-bar--height, 0px) + 72px );

Twenty Sixteen does not have a fixed header, but the border styling requires a little more scroll padding because it uses a pseudo-element on the body:

html {
	scroll-padding-top: calc( var(--wp-admin--admin-bar--height, 0px) + 21px );

For more information, see TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. tickets #52623 (CSS variable) and #46371 (scroll padding for anchor links).

Custom header image attributes

Alternative text is customizable (and the alt attribute is empty by default)

Custom header image markup now applies the alternative text assigned to the image (in the Media Library). The alternative text was always the site title, which is not relevant in most use cases. The header image is often decorative only, so the attribute is empty when the text is not supplied.

This affects the following functions:

  • get_header_image_tag()
  • the_header_image_tag()
  • get_custom_header_markup()
  • the_custom_header_markup()

If a theme allows linking the header image (for example, with the get_header_image_tag filterFilter Filters are one of the two types of Hooks They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.), restoring the site title as backup alt text could prevent “empty link” accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). ( errors.

function linked_header_image_markup( $html, $header, $attr ) {
    // This variable might be a theme option instead.
    $header_image_link_option = home_url( '/' );

    $output = '';
    if ( ! empty( $header_image_link_option ) ) {
        $output .= '<a href="' . esc_url( $header_image_link_option ) . '">';
        // Replace empty alt text with site title when image is linked.
        $output .= str_replace( 'alt=""', 'alt="' . esc_attr( get_bloginfo( 'name' ) ) . '"', $html );
        $output .= '</a>';
    } else {
        $output .= $html;

    return $output;
add_filter( 'get_header_image_tag', 'linked_header_image_markup', 99, 3 );

New attributes filter

The get_header_image_tag_attributes hook allows developers to filter the attributes of the header image HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) before they are escaped, concatenated, and returned in the get_header_image_tag() function.

Filtering with this hook externally and preemptively intercepts the array of attributes, in a manner similar to the wp_get_attachment_image_attributes hook.

Adding classes is one possibility:

function header_image_add_class( $attr ) {
    if ( isset( $attr['class'] ) ) {
        $attr['class'] .= ' special classes';
    } else {
        $attr['class'] = 'special classes';
    return $attr;
add_filter( 'get_header_image_tag_attributes', 'header_image_add_class', 10, 1 );

If an attribute should change due to part of the $header object, the filter has a second argument:

function header_add_data_thumbnail_url( $attr, $header ) {
    if ( ! empty( $header->thumbnail_url ) ) {
        $attr['data-thumbnail'] = $header->thumbnail_url;
    return $attr;
add_filter( 'get_header_image_tag_attributes', 'header_add_data_thumbnail_url', 10, 2 );

For more information, see Trac tickets #46124 (alt attribute) and #38942 (filter).

Note that this pertains to the Classic RSS widget; the blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience.-based RSS widget does not include the icon.

With the new rss_widget_feed_link filter, some people may remove or replace the markup for the icon link instead of hiding it with CSS. This can prevent accessibility errors such as empty links, or it can simply remove undesired markup.

If the image is hidden but not the link, that can result in an empty link. A theme that hides .rss-widget-icon in the styles can update the stylesheet with an additional .rss-widget-feed selector.

.widget_rss a.rsswidget .rss-widget-feed,
.widget_rss a.rsswidget .rss-widget-icon {
    display: none;

If the theme uses :first-child or :first-of-type to target the feed link, including :not(.rss-widget-title) can support people using the filter as well as people still using older versions of WordPress.

For example, Twenty Seventeen floats the link to the side:

.widget_rss .widget-title .rsswidget:first-child:not(.rss-widget-title) {
    float: right;

Twenty Twenty hides the link, when it is in the markup:

.widget_rss .widget-title a.rsswidget:first-of-type:not(.rss-widget-title) {
    display: none;

Themes and plugins can remove the icon link with the rss_widget_feed_link hook:

add_filter( 'rss_widget_feed_link', '__return_false' );

For Twenty Twenty-One, the after_setup_theme action contains the filter.

For theme authors who want a custom image or some other change, the filter also allows new content.

function remove_link_from_rss_widget_image( $feed_link ) {
    $feed_icon = includes_url( 'images/rss.png' );
    $feed_link = sprintf(
        '<img class="rss-widget-icon" style="border:0" width="14" height="14" src="%1$s" alt="%2$s"%3$s /> ',
        esc_url( $feed_icon ),
        esc_attr__( 'RSS' ),
        ( wp_lazy_loading_enabled( 'img', 'rss_widget_feed_icon' ) ? ' loading="lazy"' : '' )

    // Output is the image without the link, but this replaces both the link and the image.
    return $feed_link;
add_filter( 'rss_widget_feed_link', 'remove_link_from_rss_widget_image', 10, 1 );

Additional revisionsRevisions The WordPress revisions system stores a record of each saved draft or published update. The revision system allows you to see what changes were made in each revision by dragging a slider (or using the Next/Previous buttons). The display indicates what has changed in each revision. to the default output

  1. Themes can style the feed link with the rss-widget-feed class and/or the title link with rss-widget-title, as long as they require at least 5.9.
  1. The image includes the lazy loading attribute when support is declared, either in all situations or specifically in the rss_widget_feed_icon context. 
function disable_rss_widget_image_lazy_loading( $default, $tag_name, $context ) {
    if ( 'img' === $tag_name && 'rss_widget_feed_icon' === $context ) {
        return false;
    return $default;
add_filter( 'wp_lazy_loading_enabled', 'disable_rss_widget_image_lazy_loading', 10, 3 );

For more information, see Trac ticketticket Created for both bug reports and feature development on the bug tracker. #52224.

Thanks @ryelle for help with the toolbar section, and thanks to @joedolson and @ryokuhi for reviewing.

#5-9, #dev-notes, #themes