<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/css" href="https://www.aaron-gustafson.com/c/feed.min.css" ?><feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:amg="https://www.aaron-gustafson.com.com/amg-dtd/"><title>Aaron Gustafson: Content tagged web design 101</title><subtitle>The latest 20 posts and links tagged web design 101.</subtitle><id>https://www.aaron-gustafson.com</id><link href="https://www.aaron-gustafson.com/feeds/web-design-101.xml" rel="self"/><link href="https://www.aaron-gustafson.com"/><author><name>Aaron Gustafson</name><uri>https://www.aaron-gustafson.com</uri></author><updated>2017-10-31T16:07:39Z</updated><entry><id>https://www.aaron-gustafson.com/notebook/web-form-conundrum-disabled-or-read-only/</id><title type="html"><![CDATA[✍🏻 Web Form Conundrum: `disabled` or `readonly`?]]></title><link href="https://www.aaron-gustafson.com/notebook/web-form-conundrum-disabled-or-read-only/" rel="alternate" type="text/html" /><published>2017-10-31T16:07:39Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>Web forms are complex beasts. There are a lot of field types to remember, each with dozens of attributes. It’s hard to know which is the right way to go, especially when presented with a choice between two seemingly similar options for disallowing a field to be edited: <code>disabled</code> and <code>readonly</code>.</p><p>TL;DR: If you really need it, which you probably don’t, <code>readonly</code> is what you want.</p><h2 id="the-use-case" tabindex="-1"><a class="header-anchor" href="#the-use-case" aria-hidden="true">#</a> The Use Case</h2><p>There are times when you want to expose a bit of data to the user but don’t want them to be able to edit it. For example, your system might not allow a user to edit their username after completing the registration process. In situations like this, you may want to present the username in the context of a profile editing interface without allowing them to edit it.</p><p>The best choice in that situation would be to avoid using a form field to display the username, full stop, but if you’re hamstrung and need to drop it in an <code>input</code> field, you want to make sure the user can’t edit it. That’s when you need to make a choice between <code>disabled</code> and <code>readonly</code>.</p><p>Both of these attributes are “empty” attributes, meaning they don’t require value assignment:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-1<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Disabled Username<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-1<span class="token punctuation">”</span></span><span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-1<span class="token punctuation">”</span></span><span class="token attr-name">disabled</span><span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>AaronGustafson<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-2<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Readonly Username<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-2<span class="token punctuation">”</span></span><span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>username-2<span class="token punctuation">”</span></span><span class="token attr-name">readonly</span><span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>AaronGustafson<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span></code></pre><p>As expected, both also prohibit editing directly in the browser.</p><h2 id="the-key-difference" tabindex="-1"><a class="header-anchor" href="#the-key-difference" aria-hidden="true">#</a> The Key Difference</h2><p>So why do we have two attributes that do the same thing? Unfortunately this is where developers often get confused: the user experience is the same, but the mechanics are quite different.</p><p>Fields marked as <code>readonly</code> are collected along with all of the normal field values in a form submission (<a href="https://www.w3.org/TR/html401/interact/forms.html#h-17.13.2">“successful controls” in the spec</a>). The only difference between a <code>readonly</code> field and a regular field is the user experience.</p><p>Fields marked as <code>disabled</code> are ignored when collecting values from the form. In a traditional form submission, the action page would never receive values for a <code>disabled</code> field, regardless of whether it has a <code>name</code> attribute. In JavaScript, this is a little trickier as generic DOM access via a form’s <code>elements</code> collection includes all form controls, including <code>disabled</code> fields (and buttons, <code>output</code> elements, etc.). In order to ensure consistency with the spec, it is incumbent upon the JavaScript developer to keep an eye out for <code>disabled</code> fields so they can throw away their values before processing the form.</p><figure id="fig-2017-10-31-01" class="media-container"><iframe class="codepen" height="250" style="width:100%;" scrolling="no" title="CodePen Embed" src="https://codepen.io/anon/embed/jaPYLr?height=250&theme-id=dark&default-tab=result" frameborder="0" loading="lazy" allowtransparency="true" allowfullscreen="true"><p><a href="https://codepen.io/aarongustafson/pen/jaPYLr" target="_blank" rel="noopener">See the Pen</a></p></iframe></figure><p>Thankfully, most library code I’ve found does this, so it’s not much of an issue if you are working with <a href="https://api.jquery.com/serialize/">jQuery’s <code>serialize()</code> method</a> or even <a href="https://www.npmjs.com/package/form-serialize">the <code>form-serialize</code> module for Node</a> (and React, etc.). Confusingly, the Node module enables developers to treat <code>disabled</code> fields as though they are <code>readonly</code>. Luckily, that’s not the default behavior.</p><h2 id="don%E2%80%99t-assume" tabindex="-1"><a class="header-anchor" href="#don%E2%80%99t-assume" aria-hidden="true">#</a> Don’t Assume</h2><p>In many of my forms-related talks, I’ve discussed the need for server side validation of info sent from the browser. Even if you have the most robust client-side validation logic in the world, that JavaScript (and your HTML, etc.) is all easily manipulated via common developer tools. If you don’t have equally robust checks running on the server side (be it via an API or simply a form-posting endpoint), you’re opening your system up for abuse.</p><p>It’s inconsequential to inspect a form field in the browser, remove the <code>readonly</code> or <code>disabled</code> attribute, and submit the form with a change to that field. If you, as the developer, truly don’t want the value of a particular key touched, don’t provide it in a field to begin with. Additionally, don’t accept any values submitted for it. You don’t need to throw an error to the user since it’s an improper use of the system, but you might consider logging it in case you see continued abuse by that user.</p><h2 id="i-have-forms-to-build%2C-which-do-i-choose%3F" tabindex="-1"><a class="header-anchor" href="#i-have-forms-to-build%2C-which-do-i-choose%3F" aria-hidden="true">#</a> I Have Forms to Build, Which Do I Choose?</h2><p><strong>I want to display data as information, but don’t want a user to update it.</strong></p><p>Don’t use a form field at all, display it as text.</p><p><strong>I want the data included with the form submission.</strong></p><p>Ideally, display the info as text (see above) and mix it into the form submission data on the server side. If that’s not possible, make it a <code>readonly</code> field an ensure there’s a validation check on the server side.</p><p><strong>I do not want the data included in the form submission.</strong></p><p>Display the info as text (see above).</p>]]></content><amg:summary><![CDATA[It’s hard to know which is the right way to go, especially when presented with a choice between two seemingly similar options for disallowing a field to be edited.]]></amg:summary><summary type="html"><![CDATA[<p>It’s hard to know which is the right way to go, especially when presented with a choice between two seemingly similar options for disallowing a field to be edited.</p>]]></summary><category term="forms" /><category term="web design 101" /><category term="HTML" /><category term="user experience" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/web-design-101-100-percent-tappable/</id><title type="html"><![CDATA[✍🏻 Web Design 101: 100% Tappable]]></title><link href="https://www.aaron-gustafson.com/notebook/web-design-101-100-percent-tappable/" rel="alternate" type="text/html" /><published>2015-08-17T18:46:35Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>I see this one all the time: something that looks like a button, but only a portion of it is tappable. Consider this example from a recent email I received (emails are notorious for this crap):</p><figure id="fig-2015-08-17-01" class="media-container"><p><img src="https://www.aaron-gustafson.com/i/posts/2015-08-17/01.png" alt=""></p><figcaption>A call to action from a recent email with the tiny tappable area highlighted within the much larger “button”.</figcaption></figure><p>This screenshot shows a very large call to action, which is good. Unfortunately, as the screenshot illustrates, the majority of the “button” is a table cell and the tappable link is just the text inside it.</p><p>The markup itself isn’t horrible; here’s a distillation of that row in the design:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>table</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tbody</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span><span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>…<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Shop Biotek Marine<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tbody</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>table</span><span class="token punctuation">&gt;</span></span></code></pre><p>The problem is that the 15px padding and overall button styles were put on the table cell rather than the link itself. Setting the link to have a <code>display</code> of “block” or “inline-block” would allow it to be given vertical padding (which is probably the issue the designer was struggling with here). Then the remainder of the styles could be migrated without adjusting the design at all.</p><figure id="fig-2015-08-17-02" class="media-container"><p><img src="https://www.aaron-gustafson.com/i/posts/2015-08-17/02.png" alt=""></p><figcaption>The same email with the padding shifted to the link, making more of the “button” tappable.</figcaption></figure><p>When you design something that looks interactive, <em>always make sure the whole thing is actually tappable</em>. It will go along way toward reducing user frustration.</p>]]></content><amg:twitter><![CDATA[When you design something that looks interactive, always make sure the whole thing is actually tappable.]]></amg:twitter><amg:summary><![CDATA[When you design something that looks interactive, always make sure the whole thing is actually tappable.]]></amg:summary><summary type="html"><![CDATA[<p>When you design something that looks interactive, always make sure the whole thing is actually tappable.</p>]]></summary><category term="web design 101" /><category term="web design" /><category term="user experience" /></entry></feed>