[wp-trac] [WordPress Trac] #27697: wp-admin.css class="hidden" bug renders screen options menu in admin blank

WordPress Trac noreply at wordpress.org
Mon Apr 7 17:24:03 UTC 2014


#27697: wp-admin.css class="hidden" bug renders screen options menu in admin blank
--------------------------+-----------------------------
 Reporter:  grabmedia     |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Menus         |    Version:  3.8.1
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 One of the publishers who uses our GrabPress plugin brought a serious
 issue to our attention. Initially they thought it was a bug with our
 plugin, but after looking further into the issue, it's clear that the
 issue is within the WordPress admin files.

 The Screen Options menu at the top of the WordPress admin dashboard
 becomes unusable, and the form elements appear hidden. Reproducing this
 issue was difficult to track, mainly because it just depends on when other
 CSS files conflict with it (which can be many). It leaves the '.hidden'
 class out there to potentially conflict against any other CSS file in the
 environment that uses the 'visibility:hidden' property instead of or in
 addition to 'display:none'

 One of our developers took a closer look and found the following.

 ''In the PHP file where the original state of the HTML for the screen
 options UI that is experiencing the issue is formed you'll see that the
 class="hidden" is present.
 wp-admin/includes/screen.php (line 917)''


 {{{
 <div id="screen-options-wrap" class="hidden" tabindex="-1" aria-
 label="<?php esc_attr_e('Screen Options Tab'); ?>">
 }}}


 ''They have this class tied up to the following CSS: wp-admin/css/wp-
 admin.css (line 234 thru 243)''


 {{{
 .hidden,
 .js .closed .inside,
 .js .hide-if-js,
 .no-js .hide-if-no-js,
 .js.wp-core-ui .hide-if-js,
 .js .wp-core-ui .hide-if-js,
 .no-js.wp-core-ui .hide-if-no-js,
 .no-js .wp-core-ui .hide-if-no-js {
         display: none;
 }
 }}}

 ''So you can see that the '.hidden' class (along with several others) has
 the property 'display: none;'. This is perfectly fine and normal if they
 plan to toggle on and off the '.hidden' class from the element. However
 they instead make use of jQuery's 'show()' and 'hide()' methods and leave
 the 'hidden' class.
 wp-admin/js/common.js (lines 99 thru 143)''


 {{{
 screenMeta = {
         element: null, // #screen-meta
         toggles: null, // .screen-meta-toggle
         page:    null, // #wpcontent

         init: function() {
                 this.element = $('#screen-meta');
                 this.toggles = $('.screen-meta-toggle a');
                 this.page    = $('#wpcontent');

                 this.toggles.click( this.toggleEvent );
         },

         toggleEvent: function( e ) {
                 var panel = $( this.href.replace(/.+#/, '#') );
                 e.preventDefault();

                 if ( !panel.length )
                         return;

                 if ( panel.is(':visible') )
                         screenMeta.close( panel, $(this) );
                 else
                         screenMeta.open( panel, $(this) );
         },

         open: function( panel, link ) {

                 $('.screen-meta-toggle').not( link.parent()
 ).css('visibility', 'hidden');

                 panel.parent().show();
                 panel.slideDown( 'fast', function() {
                         panel.focus();
                         link.addClass('screen-meta-active').attr('aria-
 expanded', true);
                 });
         },

         close: function( panel, link ) {
                 panel.slideUp( 'fast', function() {
                         link.removeClass('screen-meta-active').attr('aria-
 expanded', false);
                         $('.screen-meta-toggle').css('visibility', '');
                         panel.parent().hide();
                 });
         }
 };
 }}}

 ''The use of these methods is also okay. The 'show()' and 'hide()' methods
 toggle the element's display value between 'display:none' and
 'display:block'. The issue here is that WP used the '.hidden' class to set
 the default display state and then use the Jquery toggle methods to adjust
 on the fly. However, this leaves the '.hidden' class out there to snag
 itself in conflict against any CSS at play that uses the
 'visibility:hidden' property instead of or in addition to 'display:none'.
 Twitter Bootstrap for example, which GrabPress uses and is widely used
 across the web has the following declaration for '.hidden':''


 {{{
 .hidden {
   display: none;
   visibility: hidden;
 }
 }}}

 ''So my recommendation to WP would be to have their JavaScript toggle
 on/off the class 'hidden' from the element rather than leaving it there.
 To have 'hidden' on a unhidden element just makes no sense, even
 semantically speaking. It might also be good for them to toggle both the
 'display' property and the 'visibility' property of the element.''

--
Ticket URL: <https://core.trac.wordpress.org/ticket/27697>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list