WordPress.org

Make WordPress Core

Changeset 44900


Ignore:
Timestamp:
03/15/2019 10:42:35 AM (8 months ago)
Author:
afercia
Message:

Accessibility: improve the "URL" and "Alt text" fields in the media modals.

Many users found the attachment URL field confusing: it says "URL" so it may appear like a field meant to paste a URL into.
Also, the Alt text field is the most important one in terms of content, while the Title field needs to be de-emphasized.

  • changes the URL field label to "Copy link"
  • moves the alt text field to the top as first field
  • avoids to set initial focus on the alt text field
  • adds an explanatory text with a link pointing to the W3C "alt decision tree" tutorial
  • adds aria-describedby to target the explanatory text
  • adjusts the CSS accordingly
  • updates the QUnit index.html file

Props melchoyce, audrasjb, afercia.
Fixes #41612.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/media/views/attachment/details.js

    r43309 r44900  
    4343        });
    4444
    45         this.on( 'ready', this.initialFocus );
    4645        // Call 'initialize' directly on the parent class.
    4746        Attachment.prototype.initialize.apply( this, arguments );
    4847    },
    4948
    50     initialFocus: function() {
    51         if ( ! wp.media.isTouchDevice ) {
    52             /*
    53             Previously focused the first ':input' (the readonly URL text field).
    54             Since the first ':input' is now a button (delete/trash): when pressing
    55             spacebar on an attachment, Firefox fires deleteAttachment/trashAttachment
    56             as soon as focus is moved. Explicitly target the first text field for now.
    57             @todo change initial focus logic, also for accessibility.
    58             */
    59             this.$( 'input[type="text"]' ).eq( 0 ).focus();
    60         }
    61     },
    6249    /**
    6350     * @param {Object} event
  • trunk/src/wp-includes/css/media-views.css

    r44791 r44900  
    432432.attachment-details .setting input[type="url"],
    433433.attachment-details .setting textarea,
    434 .attachment-details .setting .value {
     434.attachment-details .setting .value,
     435.attachment-details .setting + .description {
    435436    box-sizing: border-box;
    436437    margin: 1px;
     
    440441
    441442.media-sidebar .setting .value,
    442 .attachment-details .setting .value {
     443.attachment-details .setting .value,
     444.attachment-details .setting + .description {
    443445    margin: 0 1px;
    444446    text-align: left;
     447}
     448
     449.attachment-details .setting + .description {
     450    font-size: 12px;
     451    font-style: normal;
     452    margin-bottom: 0.5em;
    445453}
    446454
     
    20412049}
    20422050
     2051.media-embed .setting.has-description {
     2052    margin-bottom: 5px;
     2053}
     2054
     2055.media-embed .description {
     2056    clear: both;
     2057    font-style: normal;
     2058}
     2059
    20432060.image-details .embed-media-settings .setting {
    20442061    float: none;
     
    20702087.image-details .embed-media-settings .setting input.link-to-custom,
    20712088.image-details .embed-media-settings .link-target,
    2072 .image-details .embed-media-settings .custom-size {
     2089.image-details .embed-media-settings .custom-size,
     2090.image-details .description {
    20732091    margin-left: 27%;
    20742092    width: 70%;
     2093}
     2094
     2095.image-details .description {
     2096    font-style: normal;
     2097    margin-top: 0;
    20752098}
    20762099
  • trunk/src/wp-includes/media-template.php

    r43976 r44900  
    162162        $class .= ' ie7';
    163163    }
     164
     165    $alt_text_description = sprintf(
     166        /* translators: 1: link start tag, 2: accessibility text, 3: link end tag */
     167        __( 'Describe %1$sthe purpose of the image%2$s%3$s. Leave empty if the image is purely decorative.' ),
     168        '<a href="' . esc_url( 'https://www.w3.org/WAI/tutorials/images/decision-tree' ) . '" target="_blank" rel="noopener noreferrer">',
     169        sprintf(
     170            '<span class="screen-reader-text"> %s</span>',
     171            /* translators: accessibility text */
     172            __( '(opens in a new tab)' )
     173        ),
     174        '</a>'
     175    );
    164176    ?>
    165177    <!--[if lte IE 8]>
     
    405417
    406418            <div class="settings">
    407                 <label class="setting" data-setting="url">
    408                     <span class="name"><?php _e( 'URL' ); ?></span>
    409                     <input type="text" value="{{ data.url }}" readonly />
    410                 </label>
    411419                <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     420                <# if ( 'image' === data.type ) { #>
     421                    <label class="setting" data-setting="alt">
     422                        <span class="name"><?php _e( 'Alternative Text' ); ?></span>
     423                        <input type="text" value="{{ data.alt }}" aria-describedby="alt-text-description" {{ maybeReadOnly }} />
     424                    </label>
     425                    <p class="description" id="alt-text-description"><?php echo $alt_text_description; ?></p>
     426                <# } #>
    412427                <?php if ( post_type_supports( 'attachment', 'title' ) ) : ?>
    413428                <label class="setting" data-setting="title">
     
    433448                    <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
    434449                </label>
    435                 <# if ( 'image' === data.type ) { #>
    436                     <label class="setting" data-setting="alt">
    437                         <span class="name"><?php _e( 'Alt Text' ); ?></span>
    438                         <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
    439                     </label>
    440                 <# } #>
    441450                <label class="setting" data-setting="description">
    442451                    <span class="name"><?php _e( 'Description' ); ?></span>
     
    457466                    </div>
    458467                <# } #>
     468                <label class="setting" data-setting="url">
     469                    <span class="name"><?php _e( 'Copy Link' ); ?></span>
     470                    <input type="text" value="{{ data.url }}" readonly />
     471                </label>
    459472                <div class="attachment-compat"></div>
    460473            </div>
     
    596609        </div>
    597610
    598         <label class="setting" data-setting="url">
    599             <span class="name"><?php _e( 'URL' ); ?></span>
    600             <input type="text" value="{{ data.url }}" readonly />
    601         </label>
    602611        <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     612        <# if ( 'image' === data.type ) { #>
     613            <label class="setting" data-setting="alt">
     614                <span class="name"><?php _e( 'Alt Text' ); ?></span>
     615                <input type="text" value="{{ data.alt }}" aria-describedby="alt-text-description" {{ maybeReadOnly }} />
     616            </label>
     617            <p class="description" id="alt-text-description"><?php echo $alt_text_description; ?></p>
     618        <# } #>
    603619        <?php if ( post_type_supports( 'attachment', 'title' ) ) : ?>
    604620        <label class="setting" data-setting="title">
     
    624640            <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
    625641        </label>
    626         <# if ( 'image' === data.type ) { #>
    627             <label class="setting" data-setting="alt">
    628                 <span class="name"><?php _e( 'Alt Text' ); ?></span>
    629                 <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
    630             </label>
    631         <# } #>
    632642        <label class="setting" data-setting="description">
    633643            <span class="name"><?php _e( 'Description' ); ?></span>
    634644            <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     645        </label>
     646        <label class="setting" data-setting="url">
     647            <span class="name"><?php _e( 'Copy Link' ); ?></span>
     648            <input type="text" value="{{ data.url }}" readonly />
    635649        </label>
    636650    </script>
     
    883897        </div>
    884898
     899        <label class="setting alt-text has-description">
     900            <span><?php _e( 'Alternative Text' ); ?></span>
     901            <input type="text" data-setting="alt" aria-describedby="alt-text-description" />
     902        </label>
     903        <p class="description" id="alt-text-description"><?php echo $alt_text_description; ?></p>
     904
    885905        <?php
    886906        /** This filter is documented in wp-admin/includes/media.php */
     
    892912            </label>
    893913        <?php endif; ?>
    894 
    895         <label class="setting alt-text">
    896             <span><?php _e( 'Alt Text' ); ?></span>
    897             <input type="text" data-setting="alt" />
    898         </label>
    899914
    900915        <div class="setting align">
     
    949964                </div>
    950965                <div class="column-settings">
     966                    <label class="setting alt-text has-description">
     967                        <span><?php _e( 'Alternative Text' ); ?></span>
     968                        <input type="text" data-setting="alt" value="{{ data.model.alt }}" aria-describedby="alt-text-description" />
     969                    </label>
     970                    <p class="description" id="alt-text-description"><?php echo $alt_text_description; ?></p>
     971
    951972                    <?php
    952973                    /** This filter is documented in wp-admin/includes/media.php */
     
    958979                        </label>
    959980                    <?php endif; ?>
    960 
    961                     <label class="setting alt-text">
    962                         <span><?php _e( 'Alternative Text' ); ?></span>
    963                         <input type="text" data-setting="alt" value="{{ data.model.alt }}" />
    964                     </label>
    965981
    966982                    <h2><?php _e( 'Display Settings' ); ?></h2>
  • trunk/tests/qunit/index.html

    r44796 r44900  
    11191119                <# if ( 'image' === data.type && ! data.uploading ) { #>
    11201120                    <# if ( data.width && data.height ) { #>
    1121                         <div class="dimensions"><strong>Dimensions:</strong> {{ data.width }} &times; {{ data.height }}</div>
     1121                        <div class="dimensions"><strong>Dimensions:</strong>
     1122                            {{ data.width }} by {{ data.height }} pixels                        </div>
    11221123                    <# } #>
    11231124                <# } #>
    11241125
    1125                 <# if ( data.fileLength ) { #>
    1126                     <div class="file-length"><strong>Length:</strong> {{ data.fileLength }}</div>
     1126                <# if ( data.fileLength && data.fileLengthHumanReadable ) { #>
     1127                    <div class="file-length"><strong>Length:</strong>
     1128                        <span aria-hidden="true">{{ data.fileLength }}</span>
     1129                        <span class="screen-reader-text">{{ data.fileLengthHumanReadable }}</span>
     1130                    </div>
    11271131                <# } #>
    11281132
     
    11441148
    11451149            <div class="settings">
    1146                 <label class="setting" data-setting="url">
    1147                     <span class="name">URL</span>
    1148                     <input type="text" value="{{ data.url }}" readonly />
    1149                 </label>
    11501150                <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     1151                <# if ( 'image' === data.type ) { #>
     1152                    <label class="setting" data-setting="alt">
     1153                        <span class="name">Alternative Text</span>
     1154                        <input type="text" value="{{ data.alt }}" aria-describedby="alt-text-description" {{ maybeReadOnly }} />
     1155                    </label>
     1156                    <p class="description" id="alt-text-description">Describe <a href="https://www.w3.org/WAI/tutorials/images/decision-tree" target="_blank" rel="noopener noreferrer">the purpose of the image<span class="screen-reader-text"> (opens in a new tab)</span></a>. Leave empty if the image is purely decorative.</p>
     1157                <# } #>
    11511158                                <label class="setting" data-setting="title">
    11521159                    <span class="name">Title</span>
     
    11671174                    <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
    11681175                </label>
    1169                 <# if ( 'image' === data.type ) { #>
    1170                     <label class="setting" data-setting="alt">
    1171                         <span class="name">Alt Text</span>
    1172                         <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
    1173                     </label>
    1174                 <# } #>
    11751176                <label class="setting" data-setting="description">
    11761177                    <span class="name">Description</span>
    11771178                    <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
    11781179                </label>
    1179                 <label class="setting">
     1180                <div class="setting">
    11801181                    <span class="name">Uploaded By</span>
    11811182                    <span class="value">{{ data.authorName }}</span>
    1182                 </label>
     1183                </div>
    11831184                <# if ( data.uploadedToTitle ) { #>
    1184                     <label class="setting">
     1185                    <div class="setting">
    11851186                        <span class="name">Uploaded To</span>
    11861187                        <# if ( data.uploadedToLink ) { #>
     
    11891190                            <span class="value">{{ data.uploadedToTitle }}</span>
    11901191                        <# } #>
    1191                     </label>
    1192                 <# } #>
     1192                    </div>
     1193                <# } #>
     1194                <label class="setting" data-setting="url">
     1195                    <span class="name">Copy Link</span>
     1196                    <input type="text" value="{{ data.url }}" readonly />
     1197                </label>
    11931198                <div class="attachment-compat"></div>
    11941199            </div>
     
    11971202                <a class="view-attachment" href="{{ data.link }}">View attachment page</a>
    11981203                <# if ( data.can.save ) { #> |
    1199                     <a href="post.php?post={{ data.id }}&action=edit">Edit more details</a>
     1204                    <a href="{{ data.editLink }}">Edit more details</a>
    12001205                <# } #>
    12011206                <# if ( ! data.uploading && data.can.remove ) { #> |
     
    12811286                <# if ( 'image' === data.type && ! data.uploading ) { #>
    12821287                    <# if ( data.width && data.height ) { #>
    1283                         <div class="dimensions">{{ data.width }} &times; {{ data.height }}</div>
     1288                        <div class="dimensions">
     1289                            {{ data.width }} by {{ data.height }} pixels                        </div>
    12841290                    <# } #>
    12851291
     
    12891295                <# } #>
    12901296
    1291                 <# if ( data.fileLength ) { #>
    1292                     <div class="file-length">Length: {{ data.fileLength }}</div>
     1297                <# if ( data.fileLength && data.fileLengthHumanReadable ) { #>
     1298                    <div class="file-length">Length:                        <span aria-hidden="true">{{ data.fileLength }}</span>
     1299                        <span class="screen-reader-text">{{ data.fileLengthHumanReadable }}</span>
     1300                    </div>
    12931301                <# } #>
    12941302
     
    13051313        </div>
    13061314
    1307         <label class="setting" data-setting="url">
    1308             <span class="name">URL</span>
    1309             <input type="text" value="{{ data.url }}" readonly />
    1310         </label>
    13111315        <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     1316        <# if ( 'image' === data.type ) { #>
     1317            <label class="setting" data-setting="alt">
     1318                <span class="name">Alt Text</span>
     1319                <input type="text" value="{{ data.alt }}" aria-describedby="alt-text-description" {{ maybeReadOnly }} />
     1320            </label>
     1321            <p class="description" id="alt-text-description">Describe <a href="https://www.w3.org/WAI/tutorials/images/decision-tree" target="_blank" rel="noopener noreferrer">the purpose of the image<span class="screen-reader-text"> (opens in a new tab)</span></a>. Leave empty if the image is purely decorative.</p>
     1322        <# } #>
    13121323                <label class="setting" data-setting="title">
    13131324            <span class="name">Title</span>
     
    13281339            <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
    13291340        </label>
    1330         <# if ( 'image' === data.type ) { #>
    1331             <label class="setting" data-setting="alt">
    1332                 <span class="name">Alt Text</span>
    1333                 <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
    1334             </label>
    1335         <# } #>
    13361341        <label class="setting" data-setting="description">
    13371342            <span class="name">Description</span>
    13381343            <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     1344        </label>
     1345        <label class="setting" data-setting="url">
     1346            <span class="name">Copy Link</span>
     1347            <input type="text" value="{{ data.url }}" readonly />
    13391348        </label>
    13401349    </script>
     
    15981607        </div>
    15991608
     1609        <label class="setting alt-text has-description">
     1610            <span>Alternative Text</span>
     1611            <input type="text" data-setting="alt" aria-describedby="alt-text-description" />
     1612        </label>
     1613        <p class="description" id="alt-text-description">Describe <a href="https://www.w3.org/WAI/tutorials/images/decision-tree" target="_blank" rel="noopener noreferrer">the purpose of the image<span class="screen-reader-text"> (opens in a new tab)</span></a>. Leave empty if the image is purely decorative.</p>
     1614
    16001615                    <label class="setting caption">
    16011616                <span>Caption</span>
    16021617                <textarea data-setting="caption" />
    16031618            </label>
    1604 
    1605         <label class="setting alt-text">
    1606             <span>Alt Text</span>
    1607             <input type="text" data-setting="alt" />
    1608         </label>
    16091619
    16101620        <div class="setting align">
     
    16521662                </div>
    16531663                <div class="column-settings">
     1664                    <label class="setting alt-text has-description">
     1665                        <span>Alternative Text</span>
     1666                        <input type="text" data-setting="alt" value="{{ data.model.alt }}" aria-describedby="alt-text-description" />
     1667                    </label>
     1668                    <p class="description" id="alt-text-description">Describe <a href="https://www.w3.org/WAI/tutorials/images/decision-tree" target="_blank" rel="noopener noreferrer">the purpose of the image<span class="screen-reader-text"> (opens in a new tab)</span></a>. Leave empty if the image is purely decorative.</p>
     1669
    16541670                                            <label class="setting caption">
    16551671                            <span>Caption</span>
    16561672                            <textarea data-setting="caption">{{ data.model.caption }}</textarea>
    16571673                        </label>
    1658 
    1659                     <label class="setting alt-text">
    1660                         <span>Alternative Text</span>
    1661                         <input type="text" data-setting="alt" value="{{ data.model.alt }}" />
    1662                     </label>
    16631674
    16641675                    <h2>Display Settings</h2>
     
    17621773                                <label class="setting link-rel">
    17631774                                    <span>Link Rel</span>
    1764                                     <input type="text" data-setting="linkRel" value="{{ data.model.linkClassName }}" />
     1775                                    <input type="text" data-setting="linkRel" value="{{ data.model.linkRel }}" />
    17651776                                </label>
    17661777                                <label class="setting link-class-name">
Note: See TracChangeset for help on using the changeset viewer.