Permalink
Browse files

Add .ui-hidden-accessible for hiding elements in an accessible way; a…

…dd .ui-hide-label to similarly hide labels/adjust layout within field containers.
  • Loading branch information...
Wilto committed Oct 14, 2011
1 parent 0f81773 commit a6892a67fc53f1df3b46d68f95eb1fb501ec6e0f
View
@@ -35,54 +35,53 @@ <h2>Form structure</h2>
</code>
-<h2>Markup Conventions</h2>
+<h2>Markup conventions</h2>
<p>When constructing forms to be used in jQuery Mobile, most of the standard guidelines used to create forms that submit via normal HTTP post or get still apply. However, one thing to keep in mind is that the <code>id</code> attributes of form controls need to be not only unique on a given page, but also unique across the pages in a site. This is because jQuery Mobile's single-page navigation model allows many different "pages" to be present in the DOM at the same time, so you must be careful to use unique <code>id</code> attributes so there will be only one of each in the DOM (and of course, be sure to pair them properly with <code>label</code> elements via the <code>for</code> attribute).</p>
- <h2>Auto-initialization of form elements</h2>
- <p>By default, jQuery Mobile will automatically enhance certain native form controls into rich touch-friendly components. This is handled internally by finding form elements by tag name and running a plugin method on them, so for instance, a <code>select</code> element will be found and initialized with the "selectmenu" plugin, while an <code>input</code> element with a <code>type="checkbox"</code> will be enhanced with the "checkboxradio" plugin. Once initialized, you can address these enhanced components programmatically through their jQuery UI widget API methods (see documentation on available methods here: <a href="plugin-eventsmethods.html">Form Plugin Methods</a>). </p>
-
- <h2>Preventing auto-initialization of form elements</h2>
- <p>If you'd prefer that a particular form control be left untouched by jQuery Mobile, simply give that element the attribute <code> data-role="none"</code>. For example:</p>
- <pre><code>
-&lt;label for=&quot;foo&quot;&gt;
-&lt;select name=&quot;foo&quot; id=&quot;foo&quot; <strong> data-role=&quot;none&quot;</strong>&gt;
- &lt;option value="a" &gt;A&lt;/option&gt;
- &lt;option value="b" &gt;B&lt;/option&gt;
- &lt;option value="c" &gt;C&lt;/option&gt;
-&lt;/select&gt;
-</code></pre>
+ <h2>Hiding labels accessibly</h2>
+ <p>For the sake of accessibility, jQuery Mobile requires that all form elements be paired with a meaningful <code>label</code>. To hide labels in a way that leaves them visible to assistive technologies—for example, when letting an element’s <code>placeholder</code> attribute serve as a label—apply the helper class <code>ui-hidden-accessible</code> to the label itself:</p>
+<code>
+<pre>
+&lt;label for="username" <strong>class="ui-hidden-accessible"</strong>>Username:&lt;/label&gt;
+&lt;input type="text" name="username" id="username" value="" placeholder="Username"/&gt;
+</pre>
+</code>
+ <p>To hide labels within a field container and adjust the layout accordingly, add the class <code>ui-hide-label</code> to the field container as in the following:</p>
- <p>Or, if you'd like to prevent auto-initialization without adding attributes to your markup, you can customize the selector that is used for preventing auto-initialization by setting the page plugin's <code>keepNative</code> option (which defaults to <code>[data-role="none"]</code>. Be sure to configure this option inside an event handler bound to the <code>mobileinit</code> event, so that it applies to the first page as well as subsequent pages that are loaded.</p>
- <pre><code>
-$(document).bind('mobileinit',function(){
- <strong>$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";</strong>
-});
- </pre></code>
+<code>
+<pre>
+&lt;div data-role="fieldcontain" <strong>class="ui-hide-label"</strong>&gt;
+ &lt;label for="username">Username:&lt;/label&gt;
+ &lt;input type="text" name="username" id="username" value="" placeholder="Username"/&gt;
+&lt;/div&gt;
+</pre>
+</code>
-<p>One special case is that of selects. The above sample will prevent any and all augmentation from taking place on select elements in the page if <code>select</code> is included. If you wish to retain the native performance, look/feel of the menu itself and benefit from the visual augmentation of the select button by jQuery Mobile you can set $.mobile.nativeSelectMenu to true in a <code>mobileinit</code> callback as a global setting or use <code>data-native="true"</code> on a case by case basis.</p>
+ <p>Both of the above examples will render as:</p>
+ <div data-role="fieldcontain" class="ui-hide-label">
+ <label for="username">Username:</label>
+ <input type="text" name="username" id="username" value="" placeholder="Username" />
+ </div>
- <h2>Dynamic form layout</h2>
+ <p>While the label will no longer be visible, it will be available to assisitive technologies such as screen readers.</p>
- <p>In jQuery Mobile, all form elements are designed to be a flexible width so they will comfortably fit the width of any mobile device. One optimization built into the framework is that we present labels and form elements differently based on screen width. </p>
- <p>If a page is fairly narrow (~480px), the labels are styled as block-level elements so they will stack on top of the form element to save horizontal space.</p>
- <p>On wider screens, the labels and form elements are styled to be on the same line in a 2-column layout to take advantage of the screen real estate.</p>
+ <h2>Auto-initialization of form elements</h2>
+ <p>By default, jQuery Mobile will automatically enhance certain native form controls into rich touch-friendly components. This is handled internally by finding form elements by tag name and running a plugin method on them, so for instance, a <code>select</code> element will be found and initialized with the "selectmenu" plugin, while an <code>input</code> element with a <code>type="checkbox"</code> will be enhanced with the "checkboxradio" plugin. Once initialized, you can address these enhanced components programmatically through their jQuery UI widget API methods (see documentation on available methods here: <a href="plugin-eventsmethods.html">Form Plugin Methods</a>). </p>
- <h2>Field containers</h2>
+ <h2>Initializing groups of dynamically-injected form elements</h2>
+ <p>If you should generate new markup client-side or load in content via AJAX and inject it into a page, you can trigger the <code>create</code> event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (see below).</p>
- <p>To improve the styling to labels and form elements on wider screens, we recommend wrapping a <code>div</code> or <code>fieldset </code>with the <code> data-role="fieldcontain"</code> attribute around each label/form element. The framework will add a thin vertical bottom border on this container to act as a field separator and visually align the label and form elements for quick scanning.</p>
+ <p>For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the create event to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:</p>
-<pre><code>
-&lt;div data-role=&quot;fieldcontain&quot;&gt;
- ...label/input code goes here...
-&lt;/div&gt;
-</code></pre>
+ <code>
+ $( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
+ </code>
- <h2>Refreshing form elements</h2>
+ <h2>Initializing individual form elements</h2>
- <p>Every form control -- where applicable -- has a refresh method. Here are some examples:</p>
-
-<p>Checkboxes:</p>
+ <p>Every form control -- where applicable -- has a refresh method. Here are some examples:</p>
+ <p>Checkboxes:</p>
<code>
$("input[type='checkbox']").attr("checked",true).checkboxradio("refresh");
@@ -110,10 +109,49 @@ <h2>Refreshing form elements</h2>
<code><pre>
var myswitch = $("select#bar");
myswitch[0].selectedIndex = 1;
-myswitch .slider("refresh");
+myswitch.slider("refresh");
</pre></code>
-<p>We're considering adding a refresh method to an entire form to let the framework refresh all the child elements as a future enhancement.</p>
+ <h2>Preventing auto-initialization of form elements</h2>
+ <p>If you'd prefer that a particular form control be left untouched by jQuery Mobile, simply give that element the attribute <code> data-role="none"</code>. For example:</p>
+ <pre><code>
+&lt;label for=&quot;foo&quot;&gt;
+&lt;select name=&quot;foo&quot; id=&quot;foo&quot; <strong> data-role=&quot;none&quot;</strong>&gt;
+ &lt;option value="a" &gt;A&lt;/option&gt;
+ &lt;option value="b" &gt;B&lt;/option&gt;
+ &lt;option value="c" &gt;C&lt;/option&gt;
+&lt;/select&gt;
+</code></pre>
+
+
+ <p>Or, if you'd like to prevent auto-initialization without adding attributes to your markup, you can customize the selector that is used for preventing auto-initialization by setting the page plugin's <code>keepNative</code> option (which defaults to <code>[data-role="none"]</code>. Be sure to configure this option inside an event handler bound to the <code>mobileinit</code> event, so that it applies to the first page as well as subsequent pages that are loaded.</p>
+ <pre><code>
+$(document).bind('mobileinit',function(){
+ <strong>$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";</strong>
+});
+ </pre></code>
+
+<p>One special case is that of selects. The above sample will prevent any and all augmentation from taking place on select elements in the page if <code>select</code> is included. If you wish to retain the native performance, look/feel of the menu itself and benefit from the visual augmentation of the select button by jQuery Mobile you can set $.mobile.nativeSelectMenu to true in a <code>mobileinit</code> callback as a global setting or use <code>data-native="true"</code> on a case by case basis.</p>
+
+ <h2>Field containers</h2>
+ <p>To improve the styling to labels and form elements on wider screens, we recommend wrapping a <code>div</code> or <code>fieldset </code>with the <code> data-role="fieldcontain"</code> attribute around each label/form element. This framework aligns the input and associated label side-by-side, and breaks to stacked block-level elements below ~480px. The framework will also add a thin bottom border to act as a field seperator.</p>
+
+ <p>For example:</p>
+<pre><code>
+&lt;div data-role=&quot;fieldcontain&quot;&gt;
+ &lt;label for="name">Text Input:&lt;/label&gt;
+ &lt;input type="text" name="name" id="name" value="" /&gt;
+&lt;/div&gt;
+</code></pre>
+
+ <p>Will render as:</p>
+
+ <div data-role="fieldcontain">
+ <label for="name">Text Input:</label>
+ <input type="text" name="name" id="name" value="" />
+ </div>
+
+ <p>For additional examples, see the <a href="forms-all.html">form elements gallery</a></p>
</div><!--/content-primary -->
@@ -119,3 +119,7 @@
/* non-js content hiding */
.ui-nojs { position: absolute; left: -9999px; }
+
+/* accessible content hiding */
+.ui-hide-label label,
+.ui-hidden-accessible { position: absolute !important; left: -9999px; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
@@ -20,5 +20,8 @@ textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear;
.ui-field-contain textarea.ui-input-text,
.ui-field-contain .ui-input-search { width: 60%; display: inline-block; }
.ui-field-contain .ui-input-search { width: 50%; }
+ .ui-hide-label input.ui-input-text,
+ .ui-hide-label textarea.ui-input-text,
+ .ui-hide-label .ui-input-search { padding: .4em 1.5%; width: 97%; }
.ui-input-search input.ui-input-text { width: 98%; /*echos rule from above*/ }
}

0 comments on commit a6892a6

Please sign in to comment.