[wp-trac] [WordPress Trac] #64271: Move screen options and help to after the main screen heading

WordPress Trac noreply at wordpress.org
Thu Mar 12 09:11:42 UTC 2026


#64271: Move screen options and help to after the main screen heading
--------------------------+--------------------------------
 Reporter:  joedolson     |       Owner:  joedolson
     Type:  defect (bug)  |      Status:  accepted
 Priority:  normal        |   Milestone:  Future Release
Component:  Help/About    |     Version:
 Severity:  normal        |  Resolution:
 Keywords:  needs-patch   |     Focuses:  ui, accessibility
--------------------------+--------------------------------

Comment (by sanket.parmar):

 == Proposed Solution

 The core issue is that `render_screen_meta()` is called at the top of
 `#wpbody-content` in `admin-header.php`, before any page template has
 output its `<h1>`. This places Help and Screen Options before the page
 heading in DOM/source order.

 === Approach A (Preferred): New action hook + template updates

 1. Introduce a new action hook — `wp_after_admin_page_title` — to be fired
 by each admin page template immediately after its `<h1>` output.
 2. Move the `render_screen_meta()` call from `admin-header.php` onto that
 hook.
 3. Add a fallback using `did_action()` so that third-party or custom pages
 that don't call the new hook still get screen meta rendered (backward
 compatible).

 This requires '''no visual or CSS changes''' — the tabs are already
 positioned via float/absolute CSS, so their rendered visual location stays
 the same. It purely corrects the DOM source order.

 ==== Files requiring changes

 '''`wp-admin/admin-header.php`'''
  - Replace the direct `$current_screen->render_screen_meta()` call with a
 hooked + fallback version.

 '''Standard admin page templates''' (each needs `do_action(
 'wp_after_admin_page_title' )` after its `<h1>`):

 {{{
 wp-admin/edit.php
 wp-admin/edit-tags.php
 wp-admin/edit-tag-form.php
 wp-admin/edit-form-blocks.php
 wp-admin/edit-form-comment.php
 wp-admin/edit-link-form.php
 wp-admin/comment.php
 wp-admin/upload.php
 wp-admin/media-new.php
 wp-admin/plugins.php
 wp-admin/plugin-install.php
 wp-admin/plugin-editor.php
 wp-admin/themes.php
 wp-admin/theme-install.php
 wp-admin/theme-editor.php
 wp-admin/users.php
 wp-admin/user-edit.php
 wp-admin/user-new.php
 wp-admin/options-general.php
 wp-admin/options-writing.php
 wp-admin/options-reading.php
 wp-admin/options-discussion.php
 wp-admin/options-media.php
 wp-admin/options.php
 wp-admin/tools.php
 wp-admin/import.php
 wp-admin/export.php
 wp-admin/erase-personal-data.php
 wp-admin/export-personal-data.php
 wp-admin/privacy.php
 wp-admin/privacy-policy-guide.php
 wp-admin/nav-menus.php
 wp-admin/widgets-form.php
 wp-admin/widgets-form-blocks.php
 wp-admin/link-manager.php
 wp-admin/my-sites.php
 wp-admin/site-health.php
 wp-admin/site-editor.php
 wp-admin/update-core.php
 wp-admin/authorize-application.php
 wp-admin/network.php
 wp-admin/about.php
 wp-admin/credits.php
 wp-admin/freedoms.php
 wp-admin/index.php
 }}}

 '''Network admin page templates''' (`wp-admin/network/`):

 {{{
 wp-admin/network/index.php
 wp-admin/network/sites.php
 wp-admin/network/site-new.php
 wp-admin/network/site-info.php
 wp-admin/network/site-settings.php
 wp-admin/network/site-themes.php
 wp-admin/network/site-users.php
 wp-admin/network/users.php
 wp-admin/network/user-new.php
 wp-admin/network/themes.php
 wp-admin/network/settings.php
 wp-admin/network/upgrade.php
 }}}

 ==== Example diff (sketch)

 '''`admin-header.php`''' — replace the direct call with a hooked fallback:

 {{{
 #!diff
 -$current_screen->render_screen_meta();
 +/**
 + * Fires after the main heading on an admin screen, allowing screen meta
 + * (Help/Screen Options) to be rendered in correct source order.
 + *
 + * @since X.X.0
 + */
 +add_action( 'wp_after_admin_page_title', array( $current_screen,
 'render_screen_meta' ) );
 +
 +// Fallback: if no template fires the hook (e.g. third-party pages),
 render here.
 +add_action( 'admin_notices', function() use ( $current_screen ) {
 +    if ( ! did_action( 'wp_after_admin_page_title' ) ) {
 +        $current_screen->render_screen_meta();
 +    }
 +}, 0 );
 }}}

 '''Each affected template''' — fire the hook immediately after the closing
 `</h1>`:

 {{{
 #!diff
 -<h1 class="wp-heading-inline"><?php echo esc_html( $title ); ?></h1>
 +<h1 class="wp-heading-inline"><?php echo esc_html( $title ); ?></h1>
 +<?php do_action( 'wp_after_admin_page_title' ); ?>
 }}}

 ----

 === Approach B (Single-file, JS): DOM reordering via `wp-header-end`

 All standard admin templates already output `<hr class="wp-header-end">`
 immediately after their heading block. A small addition to `wp-
 admin/js/common.js` (loaded on every admin page) can move `#screen-meta`
 to just after that marker before the user interacts with the page:

 {{{
 // Move screen-meta (Help/Screen Options) after the page heading for
 correct source order.
 document.addEventListener( 'DOMContentLoaded', function() {
     var screenMeta = document.getElementById( 'screen-meta' );
     var headerEnd  = document.querySelector( 'hr.wp-header-end' );
     if ( screenMeta && headerEnd ) {
         headerEnd.parentNode.insertBefore( screenMeta,
 headerEnd.nextSibling );
     }
 } );
 }}}

  - '''Pros:''' Single file change. No template modifications.
 Automatically covers third-party admin pages that use `wp-header-end`.
 Works for custom post types without any extra per-template work.
  - '''Cons:''' Relies on JS (acceptable for the admin), and produces a DOM
 mutation after initial parse. Does not fix the raw HTML source order
 (relevant for non-JS screen readers, though these are rare in practice).

 This could ship as a quick, low-risk interim fix while the full Approach A
 patch is developed.

 ----

 === Approach C (Single-file, PHP): Output buffering ✗

 Starting a global output buffer in `admin-header.php`, capturing the full
 page, and using regex or DOM parsing to inject `#screen-meta` after the
 first `<h1>` in `admin-footer.php` would technically work without touching
 any template. However this approach is fragile, has a performance cost on
 every admin page load, is extremely hard to maintain, and is not
 appropriate for core. '''Not recommended.'''

 ----

 === Considerations (all approaches)

  - Plugins that call `render_screen_meta()` directly or hook into screen
 meta output are unaffected in all approaches.
  - Needs testing across all standard admin screens with keyboard
 navigation and a screen reader to verify the corrected announcement order.
  - This is scoped purely to source order and does not block the larger
 redesign work tracked in #21583.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64271#comment:9>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list