Skip to content

Conversation

@stokesman
Copy link
Contributor

@stokesman stokesman commented Mar 26, 2025

What?

Alternative to #69665
Closes #69635

Utilizes the <dialog> element to wrap the navigation content and invokes it as a modal for the overlay.

Why?

  • This ensures the overlay’s layout is not unexpectedly contained by ancestors
  • Prepares the way for the overlay to function without JS

How?

  • Replaces a <div> with <dialog>
  • Uses Invoker command and commandfor attributes on the buttons to open and close the dialog
  • Feature detects support of Invoker commands and if lacking uses JS to open and close the dialog
  • Removes implementation of “focus trapping” in the dialog
  • In the editor, adds code to prevent root/document scrolling while the dialog is open (this is outside the focus of this PR and could be dropped)

Testing Instructions

#69635 is an issue that is reproducible in Firefox or Safari so test with one of those browsers.

Here is markup for testing, though you’ll have to update the navigation for your site.

<!-- wp:cover {"url":"https://pd.w.org/2021/05/97060b09513e73a89.38852584-2048x1536.jpeg","dimRatio":50,"customOverlayColor":"#001240","isUserOverlayColor":true,"minHeight":20,"minHeightUnit":"vw","sizeSlug":"full","style":{"border":{"radius":"99em","color":"#0069e9","width":"6px"}},"layout":{"type":"constrained"}} -->
<div class="wp-block-cover has-border-color" style="border-color:#0069e9;border-width:6px;border-radius:99em;min-height:20vw"><img class="wp-block-cover__image-background size-full" alt="" src="https://pd.w.org/2021/05/97060b09513e73a89.38852584-2048x1536.jpeg" data-object-fit="cover"/><span aria-hidden="true" class="wp-block-cover__background has-background-dim" style="background-color:#001240"></span><div class="wp-block-cover__inner-container"><!-- wp:group {"style":{"position":{"type":"sticky","top":"0px"}},"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:navigation {"ref":4} /--></div>
<!-- /wp:group --></div></div>
<!-- /wp:cover -->
  1. Open a post
  2. Paste in the markup from above and update the navigation
  3. Switch to "Mobile" device preview
  4. Open the navigation menu inside the Cover block
  5. Verify the overlaid menu appears as expected
  6. View/Preview the post
  7. Ensure the viewport is narrow enough that the navigation is in mobile/overlay mode
  8. Open the navigation menu
  9. Verify the overlaid menu appears as expected

Screenshots or screencast

Editor

Before After
editor-nav-overlay-before.mp4
editor-nav-overlay-69720.mov

Front end

Before After
front-end-nav-overlay-before.mp4
front-end-nav-overlay-69720.mov

@github-actions
Copy link

github-actions bot commented Mar 26, 2025

Size Change: +122 B (+0.01%)

Total Size: 1.84 MB

Filename Size Change
build-module/block-library/navigation/view.min.js 1.16 kB -31 B (-2.61%)
build/block-library/blocks/navigation/editor-rtl.css 2.21 kB +9 B (+0.41%)
build/block-library/blocks/navigation/editor.css 2.21 kB +9 B (+0.41%)
build/block-library/blocks/navigation/style-rtl.css 2.21 kB -23 B (-1.03%)
build/block-library/blocks/navigation/style.css 2.21 kB -21 B (-0.94%)
build/block-library/editor-rtl.css 11.2 kB +9 B (+0.08%)
build/block-library/editor.css 11.2 kB +9 B (+0.08%)
build/block-library/index.min.js 226 kB +172 B (+0.08%)
build/block-library/style-rtl.css 15 kB -2 B (-0.01%)
build/block-library/style.css 15 kB -9 B (-0.06%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.8 kB
build-module/block-library/query/view.min.js 767 B
build-module/block-library/search/view.min.js 639 B
build-module/interactivity-router/index.min.js 3.03 kB
build-module/interactivity/debug.min.js 17.5 kB
build-module/interactivity/index.min.js 13.9 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.4 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.18 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.42 kB
build/block-editor/content.css 4.41 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-editor/index.min.js 263 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/archives/editor-rtl.css 84 B
build/block-library/blocks/archives/editor.css 83 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 555 B
build/block-library/blocks/button/style.css 555 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 345 B
build/block-library/blocks/buttons/style.css 345 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 191 B
build/block-library/blocks/comment-template/style.css 191 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 238 B
build/block-library/blocks/comments-pagination/editor.css 231 B
build/block-library/blocks/comments-pagination/style-rtl.css 245 B
build/block-library/blocks/comments-pagination/style.css 241 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 349 B
build/block-library/blocks/form-input/style.css 349 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.59 kB
build/block-library/blocks/freeform/editor.css 2.59 kB
build/block-library/blocks/gallery/editor-rtl.css 688 B
build/block-library/blocks/gallery/editor.css 691 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.82 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 763 B
build/block-library/blocks/image/editor.css 763 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 543 B
build/block-library/blocks/media-text/style.css 542 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 566 B
build/block-library/blocks/navigation-link/editor.css 568 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 251 B
build/block-library/blocks/paragraph/editor.css 251 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/editor-rtl.css 107 B
build/block-library/blocks/post-author/editor.css 107 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-count/style-rtl.css 72 B
build/block-library/blocks/post-comments-count/style.css 72 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 537 B
build/block-library/blocks/post-comments-form/style.css 537 B
build/block-library/blocks/post-comments-link/style-rtl.css 71 B
build/block-library/blocks/post-comments-link/style.css 71 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 722 B
build/block-library/blocks/post-featured-image/editor.css 720 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/style-rtl.css 414 B
build/block-library/blocks/post-template/style.css 414 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 358 B
build/block-library/blocks/pullquote/style.css 358 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query-total/style-rtl.css 64 B
build/block-library/blocks/query-total/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 404 B
build/block-library/blocks/query/editor.css 404 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 131 B
build/block-library/blocks/read-more/style.css 131 B
build/block-library/blocks/rss/editor-rtl.css 126 B
build/block-library/blocks/rss/editor.css 126 B
build/block-library/blocks/rss/style-rtl.css 284 B
build/block-library/blocks/rss/style.css 283 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 674 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 773 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 314 B
build/block-library/blocks/social-link/editor.css 314 B
build/block-library/blocks/social-links/editor-rtl.css 339 B
build/block-library/blocks/social-links/editor.css 338 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 92 B
build/block-library/blocks/tag-cloud/editor.css 92 B
build/block-library/blocks/tag-cloud/style-rtl.css 248 B
build/block-library/blocks/tag-cloud/style.css 248 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 441 B
build/block-library/blocks/video/editor.css 442 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/theme-rtl.css 708 B
build/block-library/theme.css 712 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.6 kB
build/commands/index.min.js 16.2 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/index.min.js 230 kB
build/components/style-rtl.css 12.5 kB
build/components/style.css 12.5 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 3.09 kB
build/core-data/index.min.js 74.3 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.69 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.67 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/index.min.js 13.4 kB
build/edit-post/style-rtl.css 2.74 kB
build/edit-post/style.css 2.73 kB
build/edit-site/index.min.js 222 kB
build/edit-site/posts-rtl.css 7.5 kB
build/edit-site/posts.css 7.5 kB
build/edit-site/style-rtl.css 13.6 kB
build/edit-site/style.css 13.6 kB
build/edit-widgets/index.min.js 17.6 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 116 kB
build/editor/style-rtl.css 9.09 kB
build/editor/style.css 9.09 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.08 kB
build/format-library/style-rtl.css 474 B
build/format-library/style.css 474 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 852 B
build/list-reusable-blocks/style.css 852 B
build/media-utils/index.min.js 3.69 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 767 B
build/nux/style.css 763 B
build/patterns/index.min.js 7.37 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.86 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 978 B
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.55 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.3 kB
build/router/index.min.js 5.44 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.93 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@stokesman stokesman force-pushed the try/navigation-block-dialog branch from 48eac1f to a693293 Compare March 28, 2025 21:29
<div { ...dialogProps }>
<div
className="wp-block-navigation__responsive-dialog"
aria-label={ isOpen && __( 'Menu' ) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned recently that aria-label doesn't do anything on elements that don't have a role: https://gomakethings.com/aria-label-requires-a-valid-role/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct but it's worth reminding the <dialog> element does have e native role. As such, it is exposed in the browser's accessibility tree as role=dialog. Adding an aria-label does work as expected. Screenshot illustrating how manually adding an aria-label on the MDN demo does work:

Screenshot 2025-03-30 at 13 58 52

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for highlighting this. The attribute was already here but I did move the code for it—it was here. Now this element is wrapped in the dialog so I’d removed the role and aria-modal attributes. I suppose this label should move to the dialog element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the aria-label to the dialog element in 01643fa. This could still use some scrutiny. The label is applied only when the overlay is open. That’s how it was yet now the overlay can open without JS and the label won’t be applied. I think the idea behind conditionally applying it is to avoid its presence when the navigation has no overlay—i.e. in larger viewports. With this PR, the dialog element is there regardless of the viewport size and perhaps it’s not wrong for it to have the label even when it’s not acting as a modal.

@westonruter
Copy link
Member

Question: In #69665 (comment) you said you started this branch from my PR?

Just curious because I don't see my commit in this PR's history.

Comment on lines 155 to 159
// Toggles `has-modal-open` class on the <html> root.
document.documentElement.classList.toggle(
'has-modal-open',
state.isMenuOpen
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be ideal if this class toggling wasn't required. Namely, the CSS rule could check if body:has(dialog.wp-block-navigation__responsive-container:open) instead. Then this would not require any JS to apply the styling.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Namely:

// The menu adds wrapping containers.
.wp-block-navigation__responsive-close {
width: 100%;
.has-modal-open & {
// Try to inherit wide-width when defined, so the X can align to a top-right aligned menu.
max-width: var(--wp--style--global--wide-size, 100%);
margin-left: auto;
margin-right: auto;
}

and

// Prevent scrolling of the parent content when the modal is open.
html.has-modal-open,
html:has(.wp-block-navigation__responsive-container[open]) {
overflow: hidden;
}

html.has-modal-open can be replaced with html:has(dialog.wp-block-navigation__responsive-container:open).

And I suppose .has-modal-open & can be replaced with html:has(dialog.wp-block-navigation__responsive-container:open) &

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be ideal if this class toggling wasn't required.

I’d agree yet I kept the classes in accord this part of the BC guidelines:

Class names and DOM nodes used inside the tree of React components are not considered part of the public API and can be modified.

Changes to these should be done with caution as it can affect the styling and behavior of third-party code (Even if they should not rely on these in the first place). Keep the old ones if possible. If not, document the changes and write a dev note.

Thanks to your suggestions though I realized I missed adding a no-JS equivalent selector for this one:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it. Ok, I think we should then keep the class name for now, but we can add a comment to say it is deprecated, and we can write a dev note to comment this. I'll do a search for themes in the directory to see if anyone is targeting this class name so we'll have a list for outreach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 132 themes that are using this class name, at least at the time that WPdirectory last indexed the directory: https://wpdirectory.net/search/01JQQ5VY70TAAEMSXTAQVE69GW

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even were these class names to be kept indefinitely it would be nice to do outreach that recommends updating any selectors using them because otherwise the theme’s styles won’t apply if JS is unavailable.

@t-hamano t-hamano added [Type] Enhancement A suggestion for improvement. [Block] Navigation Affects the Navigation Block labels Mar 31, 2025
Comment on lines 69 to 76
await pageUtils.pressKeys( 'Tab', { times: 2, delay: 50 } );
await expect( closeMenuButton ).toBeFocused();
await pageUtils.pressKeys( 'Shift+Tab', { times: 2, delay: 50 } );
await expect( overlayMenuFirstElement ).toBeFocused();
/**
* @todo Determine if focus trapping is required. If not, these assertions
* can be removed and seemingly the next test too — see its comment.
*/
// await pageUtils.pressKeys( 'Tab', { times: 2, delay: 50 } );
// await expect( closeMenuButton ).toBeFocused();
// await pageUtils.pressKeys( 'Shift+Tab', { times: 2, delay: 50 } );
// await expect( overlayMenuFirstElement ).toBeFocused();
Copy link
Contributor Author

@stokesman stokesman Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests focus wrapping, i.e. the focus moving either to the first tabbable to the last or vice versa. Since this PR removes the logic for this, focus doesn’t wrap (and tends to move into the browser’s UI). Yet thanks to the modal dialog nothing in the document outside the modal can be focused. I think that suffices and seems more accessible because focus isn’t trapped within the document by wrapping it. I just wanted to highlight this in case someone thinks differently.

I’ll go ahead and push a commit that removes these commented lines.

@stokesman
Copy link
Contributor Author

you said you started this branch from my PR?

I did but ended up squashing the commit. I’d done it before hearing from you and mostly because my first commit revised almost everything so it seemed a diff of little interest.

Comment on lines 51 to 63
openMenuOnHover() {
const { type, overlayOpenedBy } = getContext();
if (
type === 'submenu' &&
// Only open on hover if the overlay is closed.
Object.values( overlayOpenedBy || {} ).filter( Boolean )
.length === 0
) {
const { overlayOpenedBy } = getContext();
// Opens only if the overlay is closed.
if ( Object.values( overlayOpenedBy || {} ).some( Boolean ) ) {
actions.openMenu( 'hover' );
}
},
closeMenuOnHover() {
const { type, overlayOpenedBy, submenuOpenedBy } = getContext();
const { overlayOpenedBy, submenuOpenedBy } = getContext();
// Closes only if not opened by click and the overlay is closed.
if (
type === 'submenu' &&
// Close only if not opened by click.
submenuOpenedBy.click === false &&
// Only close on hover if the overlay is closed.
Object.values( overlayOpenedBy || {} ).filter( Boolean )
.length === 0
Object.values( overlayOpenedBy || {} ).some( Boolean )
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn’t necessary but should introduce no behavioral differences. The type === 'submenu' conditions were useless because these handlers are only invoked by submenus (not the overlay). The .filter( Boolean ).length === 0 is basically a more verbose version of .some( Boolean ) which replaces it. Other than that this just revises the comments a bit.

@westonruter
Copy link
Member

See also @felixarntz's #63917 (comment):

There's also #68755, so we may want to compare the approaches and scope of the changes between that and #69720.

In my PR (which admittedly is so far just experimental), I'm using popover for both the navigation overlay (by default only used on mobile) and for submenus (across all viewports).

One thing to call out is that unfortunately the Interactivity API implementation for the overlay and submenus is very intertwined - maybe this was done to reduce some code to write, but to me that doesn't look like a good choice because there are so many subtle nuances in different behavior. And now it makes decoupling more painful than it should be.

This is partly the reason why I think we need to consider changing both the overlay and the submenus implementation together. Because if you only change one of them to use popover or dialog, most of the Interactivity API code will still stick around for the other one.

Comment on lines -741 to -750
// Adjust open dialog top margin when admin-bar is visible.
// Needs to be scoped to .is-menu-open, or it will shift the position of any other navigations that may be present.
.has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog {
margin-top: $admin-bar-height-big;

// Handle smaller admin-bar.
@include break-medium() {
margin-top: $admin-bar-height;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overlay (dialog) is now in the top-layer and the admin bar is unable to appear in front of it so these styles are irrelevant.

Comment on lines 491 to 497
// If the responsive wrapper is present but overlay is not open, overlay colors
// shouldn't apply and !important is to override color classes or inline styles.
&:not(.is-menu-open) {
color: inherit !important;
background-color: inherit !important;
}

Copy link
Contributor Author

@stokesman stokesman Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had removed these because these properties were set to inherit otherwise and I didn’t realize the !important bit was key. I double-checked and found that out. Removing them hadn’t caused the e2e tests for colors to fail so along with restoring this I added an e2e test that fails without these.

// In a future version, we can explore more customizability.
&.is-menu-open {
display: flex; // Needs to be set to override "none".
&:is(.is-menu-open, [open]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be :open as opposed to [open]? I consulted Gemini who suggests they are functionally equivalent, but then says:

:open is often preferred: It's semantically clearer as it targets the state of the element (being open) rather than the implementation detail (having the open attribute). This aligns conceptually with other state pseudo-classes like :checked, :disabled, or :focus.
Suggested change
&:is(.is-menu-open, [open]) {
&:is(.is-menu-open, :open) {

It's also 1 character shorter 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I agree :open should be used. Done in 370b204. Our style lint doesn’t like it but ignores work for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out Safari doesn’t yet support :open and that was causing most of the recent e2e test failures. Even besides Safari the versions of Chrome and Firefox that don’t support it are still at usage levels above %1 which means we shouldn’t use it yet. So 966098f switches back to [open].

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just marking this as changes-requested since we still need to figure out the autofocus behavior when the nav menu is opened with an invoker command: #69720 (comment)

If we change the JS to focus on the close button instead, then we don't need to add an autofocus attribute on the first focusable nav menu item since the browser will handle this by default. However, if for a11y reasons it is preferable to focus on the first nav menu item, then it seems we'll need to clone the nav menu specifically for the DIALOG for use on mobile, with the non-mobile nav menu not needing to be wrapped in a DIALOG. And if we do that, then we'll need to finish the HTML Tag Processor implementation to find additional focusable elements: https://github.com/WordPress/gutenberg/pull/69720/files#r2023568298

@adamsilverstein adamsilverstein added the Needs Accessibility Feedback Need input from accessibility label Apr 9, 2025
await colorControl.testFrontendColors( expectedNavigationColors );
} );

test( 'The submenu/overlay colors do not apply to all navigation links unless the overlay is open', async ( {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes seem unrelated? (thru line 330)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes these are not directly related. This adds coverage for something I broke while trying to clean up some styles. It’s possible that one of the existing tests could be modified so it would fail instead of adding this new one but I figured this is more explicit.

* remove this test and only rely on the Overlay Interactions test above and add a (@firefox, @webkit)
* directive to the describe() statement. https://github.com/WordPress/gutenberg/pull/55198
*/
test( 'Overlay menu interactions in Safari (@webkit)', async ( {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test no longer work or apply?

Copy link
Contributor Author

@stokesman stokesman Apr 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test duplicates the test above it. As the comment preceding it indicates, the intention was to avoid flakiness of the test in Safari purportedly caused by Tab key presses. I removed those parts of the test so I followed up with the rest of what the comment recommends.

The reason I removed the assertions for Tab key and focus is because the “focus trapping“ implementation is removed and testing for it is not needed. The “focus trapping” can be removed because the dialog element, as a modal, makes all content outside it inert. Edit: also commented here

Aside: this test was a complete duplicate of the one above it and included Tab key presses so I don’t see how it was actually making any difference for Safari in the first place.

@westonruter
Copy link
Member

Something that just came to mind: Chrome and Edge both support invoker commands, and they are also implemented behind flags in Safari and Firefox (caniuse). Once invoker commands ship in stable versions of Safari and Firefox, should we even keep the Interactivity API implementation here? We could instead ship the invoker commands polyfill, if the current a11y limitation is resolved. There is precedence for this in core as a polyfill for import maps was added in Core-60348. It was removed in Core-60970 after it was determined that all browsers support import maps. We could similarly have a wp-load-polyfill-invokercommands which the navigation block enqueues by default (or which any other block could enqueue if they use invoker commands), or even core could enqueue this automatically if the tag processor detects the commandfor attribute in any tag.

Removing the Interactivity API implementation would reduce maintenance and it would reduce script from being served to the browser, thus improving performance.

It's still too early here to do this, as there are other aspects of the Interactivity API which aren't yet able to be replaced with invokers, namely the dropdown menus. These rely on browsers implementing interest invokers. These are just now implemented in an origin trial in Chrome 135, and the PR to add this to the HTML spec is still just a draft.

In any case, I just wanted to look ahead for what this implementation could eventually look like.

cc @swissspidy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Block] Navigation Affects the Navigation Block Needs Accessibility Feedback Need input from accessibility [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cover Block + Sticky Group + Navigation block

6 participants