Skip to content

Improve classic editor visibility controls layout - #12298

Closed
poligilad-auto wants to merge 4 commits into
WordPress:trunkfrom
poligilad-auto:poligilad-auto/core-visibility-select
Closed

Improve classic editor visibility controls layout#12298
poligilad-auto wants to merge 4 commits into
WordPress:trunkfrom
poligilad-auto:poligilad-auto/core-visibility-select

Conversation

@poligilad-auto

@poligilad-auto poligilad-auto commented Jun 24, 2026

Copy link
Copy Markdown

Trac ticket: https://core.trac.wordpress.org/ticket/65530

Summary

  • Improves spacing and alignment for the classic editor Publish box Visibility controls.
  • Visually nests the Sticky checkbox and password field as secondary controls under their related visibility options.
  • Makes the password input fit the available width within the Visibility panel.
Visibility - 2

Context

This keeps the existing classic editor markup and behavior intact while making the Visibility controls cleaner and easier to scan. The visual indentation further reinforces that Sticky belongs to the Public visibility option, and that the password field belongs to the Password protected option.

The radio options remain in their existing order, and the Sticky checkbox and password field keep their existing DOM positions. This PR does not change post status behavior or the meaning of public, password protected, or private visibility. The save behavior and existing visibility=public|password|private values are unchanged.

Related tickets:

  • Sync packages for WordPress 6.7 RC4 #7745 discusses the longer-standing Status/Visibility coupling for private posts. This PR is narrower and does not attempt to change private post status behavior.
  • #25459 addressed accessibility improvements in the Publish box.
  • #24792 touched the password-protected visibility password field.
  • #47153 provides broader admin form control accessibility context.

Testing

  • Open the classic editor Add New Post screen.
  • Open Visibility in the Publish box.
  • Confirm Public, Password protected, and Private remain in the existing order.
  • Confirm Sticky appears under Public when Public is selected.
  • Confirm the password field appears under Password protected when selected.
  • Confirm the secondary controls are consistently indented and spaced.
  • Confirm the password input fits within the panel.

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props poligilad, tyxla, fcoveram.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Hi there! 👋

Thank you for your contribution to WordPress! 💖

It looks like this is your first pull request to wordpress-develop. Here are a few things to be aware of that may help you out!

No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description.

Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making.

More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook.

Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook.

If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook.

The Developer Hub also documents the various coding standards that are followed:

Thank you,
The WordPress Project

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@tyxla tyxla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this work @poligilad-auto.

I appreciate the a11y intent here and I like the side JS selector improvement.

I do have a few concerns:

  • The classic editor Publish box is long-standing, maintenance-mode surface. The order and structure of #post-visibility-select is something a lot of plugins/themes hook into, so re-ordering the DOM carries real backward-compat risk that I'd want called out and justified.
  • The conditional field positing was intentional: Sticky sat under Public and the Password field under Password protected, each directly below the radio it relates to. The new layout puts the conditional controls in the opposite order from their radios. Could you explain the reasoning?

Comment thread src/js/_enqueues/admin/post.js Outdated
$('#sticky').prop('checked', $('#hidden-post-sticky').prop('checked'));
$('#post-visibility-display').html(visibility);
$('#visibility .edit-visibility').show().trigger( 'focus' );
updateVisibility();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why was this necessary?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed. The revised patch no longer changes the Visibility JS; this PR is now limited to CSS spacing/alignment.

Comment thread src/js/_enqueues/admin/post.js Outdated

// When the selection changes, update labels.
$postVisibilitySelect.find('input:radio').on( 'change', function() {
$postVisibilitySelect.find( 'input[name="visibility"]' ).on( 'change', function() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the name="visibility" is a nice improvement over just targeting input:radio before.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is no longer part of the patch after narrowing the approach.

Comment thread src/wp-admin/includes/meta-boxes.php Outdated

<input type="hidden" name="hidden_post_visibility" id="hidden-post-visibility" value="<?php echo esc_attr( $visibility ); ?>" />
<input type="radio" name="visibility" id="visibility-radio-public" value="public" <?php checked( $visibility, 'public' ); ?> /> <label for="visibility-radio-public" class="selectit"><?php _e( 'Public' ); ?></label><br />
<fieldset id="post-visibility-fieldset">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-ordering DOM in the Publish metabox is not a cosmetic-only change. The order and structure of #post-visibility-select children is a long-standing public surface that countless plugins/themes hook into (inserting controls after the sticky span, after a specific radio, etc.). Moving #password-span and #sticky-span out of their historical positions is a backward-compat risk that the PR doesn't acknowledge.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. The revised patch keeps the existing DOM order and no longer adds a fieldset wrapper or moves #password-span. The remaining change is visual spacing/alignment only.

Comment on lines 220 to 222
<?php if ( 'post' === $post_type && current_user_can( 'edit_others_posts' ) ) : ?>
<span id="sticky-span"><input id="sticky" name="sticky" type="checkbox" value="sticky" <?php checked( is_sticky( $post_id ) ); ?> /> <label for="sticky" class="selectit"><?php _e( 'Stick this post to the front page' ); ?></label><br /></span>
<?php endif; ?>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

AFAIK "sticky" intentionally used to be under "Public" since it only applies to Public posts. So I believe this is an unexpected / unwanted change.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. #sticky-span remains under Public, matching the existing structure and behavior.

Comment thread src/wp-admin/css/edit.css Outdated
margin-left: 0;
}

#post-visibility-select input#post_password {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This selector already exists above, let's merge

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Simplified. The password input styling is now scoped in a single #post-visibility-select input#post_password rule.

Comment thread src/wp-admin/css/edit.css
Comment on lines -337 to -339
#side-sortables input#post_password {
width: 94%
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any chance this might have some unforeseen consequences?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. The existing rule is no longer removed; the PR only adds scoped styling for the password field inside #post-visibility-select.

Comment thread src/wp-admin/css/edit.css
}

#post-visibility-fieldset input,
#post-visibility-select input#sticky {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's a #post-visibility-select { line-height: 280%; } mobile breakpoint - should we update it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added a mobile-specific line-height override for #password-span, while leaving the existing larger mobile line-height for the rest of the visibility controls.

Comment thread src/wp-admin/css/edit.css Outdated
#post-visibility-select input#post_password {
box-sizing: border-box;
width: 100%;
max-width: 100%;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we need max-width: 100% if we also have width: 100% here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed. width: 100% with box-sizing: border-box is enough here.

Comment on lines -217 to -218
<input type="radio" name="visibility" id="visibility-radio-password" value="password" <?php checked( $visibility, 'password' ); ?> /> <label for="visibility-radio-password" class="selectit"><?php _e( 'Password protected' ); ?></label><br />
<span id="password-span"><label for="post_password"><?php _e( 'Password:' ); ?></label> <input type="text" name="post_password" id="post_password" class="ltr" value="<?php echo esc_attr( $post->post_password ); ?>" maxlength="255" /><br /></span>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above with the password field

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. The password field is back in its original DOM position immediately after Password protected. The remaining change is visual spacing/alignment only.

@@ -0,0 +1,59 @@
<?php

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this test isn't useful and can be removed

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed. Since the revised patch no longer changes the markup structure, the test was no longer useful.

@poligilad-auto

Copy link
Copy Markdown
Author

Thank you @tyxla!

Updated the approach based on your review feedback.

The PR no longer changes the Publish box markup, moves the password field, or adds a markup-focused PHPUnit test. It now keeps the existing DOM order and behavior, and limits the change to CSS spacing/alignment for the secondary Visibility controls.

The goal is to make the UI cleaner and reinforce that Sticky belongs to Public, and the password field belongs to Password protected, without changing the existing save behavior or visibility=public|password|private values.

@tyxla tyxla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for repurposing this work into something more contained @poligilad-auto!

I really appreciate the improved spacing here. 👏 Would love to get this landed soon!

However, there are some rough edges that can help us both simplify and improve the new styles. Please see my inline comments.

Comment thread src/wp-admin/css/edit.css

#post-visibility-select input#post_password {
box-sizing: border-box;
width: 100%;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is now overwriting the pre-existing width: 94% in this same file. We might want to remove the lower specificity rule as it's redundant.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good point. I kept the existing lower-specificity #side-sortables input#post_password rule in place to avoid expanding the scope of this PR by removing a long-standing selector. The new width: 100% rule is scoped to #post-visibility-select, where the password field now needs to fit the indented Visibility controls.

Comment thread src/wp-admin/css/edit.css Outdated
margin-top: 3px;
}

#post-visibility-select input[name="visibility"],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would prefer styling the field type consistently, not the field name. The field name should usually be concerned with the form submission and not with how the form looks.

Suggested change
#post-visibility-select input[name="visibility"],
#post-visibility-select input[type="radio"],

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted, thanks. This now targets input[type="radio"] instead of the field name.

Comment thread src/wp-admin/css/edit.css
}

#post-visibility-select p {
margin: 12px 0 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ideally this would have been a bottom margin of the upper element, but I can see why we're doing it - targeting this when we also have a toggleable password field won't make it simpler. So, good to leave as-is.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, left this as-is for the reason you mentioned: the password field is toggleable, so keeping the spacing scoped here keeps the CSS simpler.

Comment thread src/wp-admin/css/edit.css Outdated
Comment on lines +727 to +739
#post-visibility-select #sticky-span {
display: block;
margin-left: 23px;
margin-top: 2px;
margin-bottom: 2px;
}

#post-visibility-select #password-span {
display: block;
margin-left: 23px;
margin-top: 2px;
margin-bottom: 6px;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can reuse all styles here between the sticky field and the password field wrappers.

Then the extra bottom margin of 4px could be added to the #post_password field.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. The shared wrapper styles for Sticky and Password are now grouped together, with only the differing bottom margin split out.

Comment thread src/wp-admin/css/edit.css Outdated

#post-visibility-select input[name="visibility"],
#post-visibility-select input#sticky {
margin: 2px 3px 5px 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One thing I still don't appreciate about this box is how many different margins we still have. Check this out:

Image

Specifically, the Status / Visibility labels are misaligned with both:

  • "Public" / "Password protected" / "Private" labels
  • The "Stick this post" field and the "Password" field

Would be great if we could have everything aligned with each other.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adjusted. The expanded Visibility controls now align the radio labels with the Visibility: summary text, while the dependent Sticky checkbox and Password field share the same indentation. This keeps the existing markup and behavior unchanged.

@fcoveram

Copy link
Copy Markdown

This looks good to me 🚀

@poligilad-auto

Copy link
Copy Markdown
Author

Thanks @tyxla!

Addressed everything, looks more polished! I checked on mobile too, looks good 👌

@poligilad-auto
poligilad-auto force-pushed the poligilad-auto/core-visibility-select branch from 688d3ba to eac43f6 Compare June 30, 2026 19:56
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 62605
GitHub commit: 980fa87

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants