Showing posts with label HTML5. Show all posts
Showing posts with label HTML5. Show all posts

Tuesday, November 6, 2018

A Journey of One Thousand Miles: Different styles and uses of progress indicators

One feature, common to nearly every process (and especially most processes in ecommerce), is something that indicates progress - a map, if you will, that shows your current location relative to the destination. Even our Instant Pot has a display that indicates when pressure builds and releases. But, just as every process is different, there should be different techniques that indicate the process and the current state.

One of the most common uses of progress indicators is in multi-page forms - that's certainly where I've had the most exposure to them. In general, they're intended to reduce cognitive load in a process, and they can either succeed or fail, often with significant results.

In the Web Accessibility Initiative section for multi-page forms, several different methods for identifying progress are put forward. The methods used to indicate progress for multi-page forms can be briefly described as (a) landmark content, (b) a progressbar, and (c) a step-by-step indicator - and I'll take each of them in turn to discuss how they might be used and whether or not they can, or should, apply to other types of progress.

Landmark Content

The use of landmark content to identify progress is almost always a good method, especially when - as the first approach identified by the WAI - updating the title element is used. As a general rule, assistive technology will announce changes to the page title. The other approach in the landmark content method, updating the main heading - i.e. the h1 element - is also a good approach as many users navigate using headings and it is, or at least should be, more visible than the page title. Rather than use one of these approaches, use both.

Of course, there are disadvantages to using this method. Neither approach - updating the page title or updating the main heading - is likely to be sufficient if the user has scrolled far enough. Updates are likely to be noticed only by users who have the main heading in their field of vision or are using assistive technology that announces changes. Also, both approaches in this method update content, so not all accessibility is improved - the user still must either read, or have assistive technology that will read, the updated content.

A Progressbar

A progressbar generated using a progress element with a value of 1 and a max of 3, as rendered by Chrome
Progressbar
(from a progress element, rendered in Chrome)
HTML5 offers a progress element that takes a max attribute and a value attribute to draw a visual representation. The progress element takes content, which must be updated, as in <progress max="7" value="1">Step 1 of 7</progress>. However, in some platforms, a progress bar is animated in a way that would violate the Web Content Authoring Guidelines Success Criterion 2.2.2, an A-level criterion.

Like several of the additions in HTML5, the progress element is not very accessible, so it's still recommended a better widget - one that uses the progressbar role with aria-valuemin, aria-valuemax, and aria-valuenow - be used, but be advised that automatic updates to the value in a progressbar role are not well-defined.

The progressbar, whether implemented using the HTML5 progress element or a widget that uses the progressbar role, may be sufficient if the progress reflected is proportional, such as a file transfer showing the number of bytes transferred. The interface is not well-suited to processes where one or more steps is larger, or takes more time, than others.

A Step-by-step Indicator

An ordered list as a step-by-step indicator
Step-by-step Indicator
The third method - a step-by-step indicator - can help users orient themselves in multiple ways. First, the user should be able to clearly see how much progress they've made, whether the progress within each segment is proportional or not. Second, the content should reflect not only steps already completed but the current step, and not-started, or upcoming, steps. In this method, there are three common approaches we can use, and each will apply to different cases.

Fixed-Journey Indicator

The basic step-by-step indicator presented for multi-page forms by the WAI is an ordered list, with list items that have visually hidden content to indicate which item is completed or current. This is likely sufficient, if the progress is a consecutive series of unidirectional steps under the control of the user - although the WAI example should be updated to reflect capabilities available in the ARIA states and properties.

Breadcrumbs

If, progress is bidirectional or the user may complete steps in a non-consecutive manner, the interface should be a navigational one which allows the user to choose the step they'd like to complete. This step-by-step indicator becomes more complex as it not only needs to include completed, current, and not-started states but also accessible navigation between the steps. This sort of navigational, step-by-step indicator is often called a breadcrumb because it's more than just a progress indicator.

This type of progress indicator should especially be used for multi-page forms if those forms cause legal commitments or financial transactions to occur or update user-provided data that has been stored to help meet WCAG Success Criterion 3.3.4 as it aids in the review, confirmation, and correction of information.

Status Indicator

The third type of step-by-step indicator is a status indicator. The status indicator is still, semantically, an ordered list, but a status may switch in a non-consecutive manner and the status is likely to be outside the control of the user. An example of this might be a payment transaction that moves from pending to authorizing to completed or a document retrieval that moves from requesting to receiving to received to loaded. In either of these cases, an intermediate step may be skipped, e.g., the payment may appear to move from pending to completed or the document may move from receiving to loaded.

This type of progress indicator is perhaps the most complex, because the user interface is not really a progress indicator but a status indicator (hence the name). The upcoming statuses need not be announced because their inclusion is likely to reduce cognitive accessibility - the user can do nothing to either prevent or encourage the move to that state. Further, announcing which of the items in the list is current lacks the context that the visual interface has, so identifying completed and current items is a little more complex.

It is also important to note that because this indicator is auto-updating and representing something outside the control of the user, it is critical that it only be used for those activities that are essential. If the interface is used for a part of an activity that is non-essential, the auto-update feature without the ability to pause, stop, or hide the update will violate WCAG Success Criterion 2.2.2, just as the HTML5 progress element would.

Conclusion

Any of the four different types of progress indicators - a progressbar, a fixed-journey indicator, breadcrumbs, or a status indicator - can be sufficient to describe process. While they have areas of overlap, each has a specific interface that leads to a design pattern and accessibility features.

In the very near future, I will be launching a gitbook called Think A11y that will be covering components like this, including HTML, CSS, and JavaScript, in an effort to put my accessibility resources in one location. This blog will still cover accessibility issues from time to time, but hopefully this new approach will make my electronic life a little easier to manage and share. In the meantime...

Happy coding.

Saturday, May 26, 2018

Finding Your Way

One of the common challenges when writing interfaces is describing processes that have multiple steps in a way that is both understandable and accessible. Adding different functionality and different devices further complicates this. If we were Hänsel or Grethel, we would just leave a trail of pebbles or breadcrumbs.

Alas, we often find that even though we are not Hänsel or Grethel, navigation within a process is still often a problem and poorly written HTML or CSS can significantly contribute to the several common accessibility concerns and usability concerns surrounding the progress/breadcrumbs component as well. This post offers a pattern that is accessible and mobile friendly without being a burden.

Again, the HTML and CSS needed to provide a usable breadcrumbs component is relatively simple, but it can pose an even greater problem if it is not written correctly. It should also be noted that in addition to the pattern described here, it is very important that the page title and the primary heading should be modified to indicate the update progress.

When first building our progress bar or breadcrumbs, we must make the determination if our it represents unidirectional progress or if we might be able to restart the process. If the flow is unidirectional, you might consider using the progress element to demonstrate progress; however, be aware that the progress element is dependent on the OS in use, and the ability to modify the display is limited.

If we are providing the ability to move backward in the process - i.e., the process is not unidirectional - that means the breadcrumbs or progress bar has a navigational element, and it should be identified as such. The good news is that much of the code is unchanged. To demonstrate the difference in the code, both versions are provided below.

Image showing breadcrumbs with the current step highlighted, in both mobile and desktop.
Breadcrumbs Snapshot
The code below, is complete, with the exception that in the demonstration there is a style rule to center the content, and it produces the breadcrumbs show in the Breadcrumbs Snapshot.



HTML (without navigation)

<div class="breadcrumbs">   <ol >     <li>       <span data-step="#1" role="text">         <span class="description">Personal Information</span>       </span>     </li>     <li aria-current="step">       <span data-step="#2" role="text">         <span class="description">Financial Information</span>       </span>     </li>     <li>       <span data-step="#3" role="text">         <span class="description">Review Information</span>       </span>     </li>     <li>       <span data-step="#4" role="text">         <span class="description">Thank You</span>       </span>     </li>   </ol> </div>



HTML (with navigation)

<nav aria-label="Breadcrumb" class="breadcrumb">   <ol>     <li>       <a href="signup/1">       <span data-step="#1" role="text">         <span class="description">Personal Information</span>       </span>       </a>     </li>     <li aria-current="step">       <a href="signup/2">       <span data-step="#2" role="text">         <span class="description">Financial Information</span>       </span>       </a>     </li>     <li>       <a href="signup/3">       <span data-step="#3" role="text">         <span class="description">Review Information</span>       </span>       </a>     </li>     <li>       <a href="thankyou">       <span data-step="#4" role="text">         <span class="description">Thank You</span>       </span>       </a>     </li>   </ol> </nav>

A few items to note - one is the inclusion of the aria-current attribute, which lets users of assistive technology know which step is current, and another is the inclusion of the role attribute, which fixes a 'feature' in some assistive technologies that sees child elements as distinct from their wrapping elements, resulting in a different value for the accessible name than what would commonly be expected. Otherwise, the code should be self-explanatory.

Next, we add some CSS



CSS

.breadcrumbs {   display: inline-block;   width: auto; } .breadcrumbs ol {   list-style-type: none;   margin: 0 auto;   overflow: visible;   padding: 0; } .breadcrumbs ol li {   float: left;   background: darkgray;   border: 0.1em solid darkgray;   color: white;   padding: 0.5rem;   position: relative;   margin-right: 1rem; } .breadcrumbs ol li::after {   background: darkgray;   content: '';   display: inline-block;   height: 0.5rem;   left: 100%;   margin: 0;   padding: 0;   position: absolute;   top: 0.7rem;   /* width = margin-right + (border-width * 2) */   width: 1.2em;   z-index: -1; } .breadcrumbs ol li:last-of-type {   margin-right: 0; } .breadcrumbs ol li:last-of-type::after {   display: none; } .breadcrumbs ol li a {   background: inherit;   color: inherit;   text-decoration: none; } .breadcrumbs ol li[aria-current] {   background: green;   border-color: green;   color: white; } .breadcrumbs ol li[aria-current] ~ li {   background: lightgray;   color: black; } @media (max-width: 20rem) {   .breadcrumbs ol li {     border-radius: 100%;   }   .breadcrumbs ol li [data-step]::before {     content: attr(data-step);   }   .breadcrumbs ol li a .description {     clip: rect(0, 0, 0, 0);     clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);   position: absolute;   } }

Here again, we need to comment about the code. First, the .breadcrumbs ol li rule is for past steps. This allows us to use the aria-current attribute as the selector for current steps and siblings of aria-current after the aria-current item - .breadcrumbs ol li[aria-current] ~ li - are those steps not yet completed. Another issue to note is that we are using the float property on list items. We might have used the display property to modify where items display, but in many assistive technologies, modification of the display property modifies the accessibility tree, rendering all our effort to construct an accurate tree moot.


Admittedly, this is a simple example; however, it should suffice to demonstrate how a progress bar or breadcrumbs might be built.

Happy coding.

Thursday, May 17, 2018

Hiding in Plain Sight: How to affect what you can't see in your analytics

What if I told you there is a way to improve your Google rank (placement) and significantly increase conversion and that you would not be able to discover how to do it by looking at your analytics? Would you do it? Would it matter what the delta was or would it matter what work was involved?

Several years ago, I worked on a project at PayPal with the sole purpose of improving conversion during checkout. A few "features" were added, but the majority of the project was running A/B tests for (minor) design and content changes for the existing product, so the amount of actual development work was minimal aside from refactoring existing code.

One might think such a project would yield as much as one hundred basis points, but realistically, since these were "minor" changes it should have yielded about half that...but the thing is, it was twice that amount. The most reasonable explanation we might have for this remarkable difference is that we were affecting users that were not even on our radar.

Years before that project, as a side project I took over the website for a non-profit. Before running any A/B tests or modifying design or content in any way, I refactored the code to use semantic HTML and CSS and their rank went from fifth to first overnight. Nearly all the research up to that point indicated that selection of keywords and inbound and outbound links were the primary source for SEO, but here again, something hidden had a significant impact.

In both of these projects, it was the use of solid, time-tested best practices of web development that yielded these results, in particular, Semantic HTML and CSS, unobtrusive JavaScript, and Progressive Enhancement. It was what is ordinarily hidden from users and even those in decision-making roles in technology that had the greatest impact.

Frankly, it seems like an outlandish claim, and had I not seen them firsthand, I would suspect such claims were the usual puffery in which engineers engage - sort of like boosting performance by switching turbochargers. After all, we're often told that the best tools are the newest tools and that time-to-market is the most important factor. Abundant anecdotal evidence demonstrates that neither of those beliefs are based in reality.

Again, here are the four principles behind these transformations.
  1. All HTML was Semantic HTML.
  2. All CSS was Semantic CSS.
  3. All JavaScript was unobtrusive.
  4. Sites were built using Progressive Enhancement.
I should point out that it's possible to use any of these principles alone, and using any of them will give you some of the benefits. The goal when using these practices were to create pages that are
  • fast,
  • flexible, enabling a user to complete the task in any user agent,
  • easily maintained
The primary goal in these projects was to get a page loaded in less than 4 seconds anywhere in the world. Because network reliability and speed are always unknowns outside the US, and even some places within the US, that benchmark meant the page had to load on an internal network in considerably less time. (It also meant I spent time writing a module that would allow me to simulate network rates and reliability that exist in the real world outside the US to more accurately gauge speed...but that's another story.)

The secondary goal was to build pages that would run in any user agent well enough to allow the user to accomplish the task in the shortest amount of time, in part because we know that the amount of time a process takes is inversely proportional to the likelihood of the user completing that process.

The simple truths that govern this secondary goal are that semantic HTML is easier for user agents other than browsers, like the bot(s) that rank your site, to understand; semantic CSS enables you to write fewer, better-performing rules; and unobtrusive JavaScript and Progressive Enhancement expand your audience into non-traditional user agents with the same codebase.

The Problem with Analytics

Examining the effect of these four principles is difficult, in part because of the way data collection for web analytics changed in the first decade of the 21st century. To simplify it, I'll use a mostly hypothetical example.

Let's say you're tracking user agents and see that seventy-three percent of your traffic is coming from Chrome, twenty-one percent is coming from Safari, and five percent is coming from Firefox - like the stats for this site report. Already, one percent is not reported, and if, as is the case for most analytics, your analytics package is using JavaScript to track that rather than the actual web server logs, there are even more users not tracked at all. It's unlikely that you will ever get insight into these users, which is why it has become so easy to dismiss the effect of certain principles, Progressive Enhancement being principle among them.

Progressive Enhancement

One percent is a small number, is it really enough to justify the amount of work Progressive Enhancement requires? On one hand, one percent likely is a small number - unless you're a company like PayPal, with more than 110 million active users - and on the other hand, that one percent represents a much larger number because it's the one percent we know exists. How many users fall into that not-the-popular-browsers group that typically hovers around "one percent", but aren't even measured because their browser isn't identified?

A government agency in the UK tracked visitors to government websites using actual web server logs to determine what percentage of visitors weren't being tracked by their JS analytics package and it was about two percent. Two percent. On government websites. Within a first-world country. For those government websites, that "one percent" is really three percent.

Retail websites are categorically different than government websites, so attempting to extrapolate user behavior in a government-assisted activity to private activity is a little like comparing apples and oranges. The user population in each group has different needs, desires, and expectations, and as a result, have different behavior. All we need consider is the desires and expectations around privacy between the two different categories to see there is a very clear difference in behavior. We can, however, easily support the case that the percentage of tracked users interacting with a government website is likely higher than those interacting with non-government websites. As a result, there is no way to determine what percentage of your actual traffic is untracked unless you are analyzing server logs rather than relying directly on analytics served by JavaScript. The principle of Progressive Enhancement, however, means even these untracked users are served, regardless of the user agent or its features.

Performance Matters

Since we are unlikely to gain insight into the untracked users, what does the data we collect about the tracked group tell us? The primary message we get from the data is that, performance is the most significant issue in web development - it's typically even more important than content. This is not something we've just learned - we've known it for decades. It's also not something that's unmeasured. Organizations frequently calculate the cost of each page or step in a process by calculating the abandonment rate and the drop off rate based on page load time or time-to-interactive, what Twitter used to call "time to first tweet". In a recent, rather finely-tuned test by etsy.com, we see a high correlation between the addition of a mere 160 kilobytes of page weight and a twelve percent drop off.

Semantic Code

Semantic CSS, writing CSS in a way that actually describes something about the code, and semantic HTML, writing HTML in a way that describes the content it contains, expands the robustness of the code (one of the measures of accessibility), is more maintainable, and reduces the amount of code delivered. Semantic code also performs better - there are fewer class and ID selectors to process and a cleaner, more compact Accessibility Tree is built.

Also, lighter pages load faster, and that's important because one of the lessons we've learned from gathering data about tracked users shows that nearly forty percent of users will abandon your site if it takes your page longer than three seconds to "load". If your HTML suffers from divitis and other non-semantic features, or if your CSS is bloated with non-semantic rules, it will take longer to load and parse, pushing the load time further out.

Even worse is the effect non-semantic HTML has on the Accessibility Tree. If your HTML is not semantic, you will have to add code to "fix" the Accessibility Tree, to make your code accessible. Unfortunately, as you add code the risk of harming accessibility even further raises more than the chance you will resolve issues. Here the problems become even more pronounced, because we run into a sub-group of "untracked" users within the tracked users - users who combine accessibility tools with their user agent.

Generally, we only identify site visitors using accessibility tools when they report an issue. There is no method available to determine if a user has engaged an accessibility tool. Conservative estimates generalize that for every accessibility issue registered, at least ten users have been blocked and are unable to complete their task. All industry experts agree about this premise - use of semantic HTML is the best way to minimize the accessibility risks.

A Hypothetical Example

Let's assume that you've looked at your target market and found that seventy-three percent use Chrome, twenty-one percent use Safari, and five percent use Firefox. Almost all - ninety-nine percent - of your users are using agents that have JavaScript enabled by default and you're not aware of "untracked" users. Based on this fantastic news, you've developed your site using ReactJs or Angular and you've tested it locally and the render time is pretty good - it only takes one or two seconds from the request until it's interactive from your development server.

Here's how that plays out in the real world. Your (average) page is really about eighty kilobytes of HTML, about ninety kilobytes of CSS, and almost two megabytes (or more) of JavaScript. If you've not used React's styled elements, your CSS is entirely separate, but nearly all of your eighty kilobytes of HTML is still embedded in the JavaScript. That JavaScript, which has to be entirely loaded before it can be parsed (to make sure there are no syntax errors) and rendered (or hydrated if you've used React's "server-side rendering") is on a CDN, so there's very little latency in the network, but on a 4G connection, mobile devices have a peak of about one-tenth the speed of your local network connection, which means at 100 percent reliability and speed, it's going to take about ten times as long to download the file(s) on a mobile device.

If we assume that you've really optimized and compressed and tweaked your code in production all the ways it's not optimized, compressed, and tweaked in development and your development network is not really that great, the difference between time to interactive on your development site for the more than two megabytes of code is about half of what it will be in production.

So your development version loads in about two seconds, which is pretty fast, and you're pretty confident. In production, your JavaScript resources load HTML into your page in four seconds (versus the two seconds in development) instead of two, but you decide that's still good. Of course, we know you've still lost forty percent of users. Unfortunately, what we now know is that's forty percent of tracked users.

Your beautifully designed site, which only renders for user agents with JavaScript enabled (rendering a "white screen of death" for at least three percent of visitors) unfortunately hasn't undergone an accessibility or usability review and was not written using semantic code. As a result of this oversight, your site has several color contrast issues, navigation is not identified, and your data collection form is not properly labeled - and some unknown portion of the roughly fifty percent of visitors who have made it to your page unscathed cannot complete the task. Here is where we see the final indignity - our analytics cannot tell us why that percentage does not convert, even if it tells us that they do not convert.

An Alternative Example

As an alternative, if your site were written with semantic code using Progressive Enhancement, the code would be lighter, loading in less than four seconds. Your analytics may not have changed, but by using Progressive Enhancement, no one gets a white screen of death, even those in the untracked category, which simply become a hidden bonus rather than a missed opportunity, because the technology fails gracefully.

The semantic code is, by its nature, accessible, and eliminating accessibility issues and offering an estimated ten-fold benefit that taps into an otherwise untracked market - a market that Barclays estimated in 2017 as worth twelve billion pounds, which is not a small number for any organization.

Conclusion

We know sites written with semantic code and unobtrusive JavaScript using Progressive Enhancement
  • perform faster
  • have greater accessibility
  • have greater stability
  • have greater durability
  • are more maintainable
The question is what are these qualities worth to you - do you continue on as usual or do you try to tap into what is hidden in your analytics. We tend to know a lot of information about what we know - it's what we don't know where the greatest promise rests.

Happy coding.

Wednesday, September 27, 2017

A Simpler Slider Toggle

A few years ago I wrote an article about what I called a "slider toggle". Because it was written so long ago, and user-agents change pretty frequently, I wanted to revisit it to see if I could make it easier. In the original post, I gave two different orientations - one horizontal and the other vertical - but both using a single "round button" style. I won't be doing that in this post. In this post all versions are horizontally oriented; however, there are two styles - one a round button and one a rectangular version (with rounded corners).

Again, in HTML terms, these are stylized checkboxes, and the overall approach has not changed. The primary changes are in the CSS used to generate the different looks. I've also included, in this post, an approach that has the button labels inside the button as part of the background. To make this post as easy to understand as possible, I've grouped the markup, images of rendered code, and a demo together, and placed the CSS at the end. The CSS handles all the different styles - both round button (which is the default style) and rectangular button and with external labels, internal labels, and no labels.

☝ Note that the label tag wraps the entire element. This is to increase the size of the target and make the toggle button behave in keeping with the skeuomorphic design. To compensate for the fragmentation possible on some platforms (with regard to accessibility), the label tags have been given a role of text.

It's also important to note that the code provided uses an HTML checkbox rather than a different element and the checkbox or switch role. The ARIA checkbox and switch roles are widget roles, which will likely be treated differently than native HTML. It is likely an interface using a widget role will be less discoverable than a native element with no ARIA role specified.


External labels

This example uses labels outside the switch and is the pattern used in my original post. As mentioned in the earlier post, because the non-visual interface is a checkbox, the visual-only labels whose meaning is only proximity-based are hidden from accessibility devices.

HTML

<label for="push-mode" role="text">   Push Notifications   <span class="switch-label" aria-hidden="true">Off</span>   <span class="switch">     <input id="push-mode" type="checkbox" value="on">     <span></span>   </span>   <span class="switch-label" aria-hidden="true">On</span> </label> <label for="airplane-mode" role="text">   Airplane Mode   <span class="switch-label" aria-hidden="true">Off</span>   <span class="switch slider">     <input id="airplane-mode" type="checkbox" value="on">     <span></span>   </span>   <span class="switch-label" aria-hidden="true">On</span> </label>


Internal labels

This example uses labels inside the switch. It is not recommended due to the variance in text length.

HTML

<label for="location-mode" role="text">   Location Services   <span class="switch">     <span class="switch-label" aria-hidden="true">on</span>     <input id="location-mode" type="checkbox" value="on">     <span class="switch-label" aria-hidden="true">off</span>     <span></span>   </span> </label> <label for="email-mode" role="text">   Electronic communication   <span class="switch slider">     <span class="switch-label" aria-hidden="true">ON</span>     <input id="email-mode" type="checkbox" value="on">     <span class="switch-label" aria-hidden="true">OFF</span>     <span class="slider"></span>   </span> </label>


Longer text length makes buttons appear less like buttons as can be seen in the 'other alerts' and 'bluetooth' examples.

HTML

<label for="alert-mode" role="text">          Other Alerts   <span class="switch">     <span class="switch-label" aria-hidden="true">apagado</span>     <input id="alert-mode" type="checkbox" value="on">     <span class="switch-label" aria-hidden="true">encendido</span>     <span></span>   </span> </label> <label for="bluetooth-mode" role="text">   Bluetooth   <span class="switch slider">     <span class="switch-label" aria-hidden="true">apagado</span>     <input id="bluetooth-mode" type="checkbox" value="on">     <span class="switch-label" aria-hidden="true">encendido</span>     <span class="slider"></span>   </span> </label>


Unlabeled

This example does not use interior or exterior labels. It is not recommended due to the increase in cognitive load caused by the lack of those labels.

HTML

<label for="busy-mode" role="text">   Busy   <span class="switch">     <input id="busy-mode" type="checkbox" value="on">     <span></span>   </span> </label> <label for="dnd-mode" role="text">   Do Not Disturb   <span class="switch slider">     <input id="dnd-mode" type="checkbox" value="on">     <span></span>   </span> </label>


CSS

The CSS for these items is relatively simple. The rule for the label element is left out as it does not affect the switch.

CSS

.switch-label {   font-size: 0.5em; } .switch:before {   content: '';   display: inline-block; } .switch .switch-label {   display: table-cell;   padding: 0 0.5em;   text-align: center;   vertical-align: middle;   width: 50%; } .swtich .switch-label:after {   content: '';   display: block;   margin-top: 100%; } .switch {   background-color: rgb(255, 255, 255);   border: 1px solid rgb(0, 0, 0);   border-radius: 0.7rem 0.7rem 0.7rem 0.7rem;   box-shadow: 0 0 0.1rem 0.1rem rgb(187, 187, 187) inset;   cursor: pointer;   display: inline-table;   min-height: 1.2em;   min-width: 2.3em;   position: relative; } .switch * {   -webkit-touch-callout: none;   -webkit-user-select: none;   -moz-user-select: none;   -ms-user-select: none;   user-select: none; } .switch input[type="checkbox"] {   position: absolute;   z-index: -1; } .switch > span:last-of-type, .switch.slider > span:last-of-type {   background-image: linear-gradient(to bottom, rgb(255, 255, 255) 0%, rgb(153, 153, 153) 100%);   border: 1px solid rgb(0, 0, 0);   border-radius: 0.7rem 0.7rem 0.7rem 0.7rem;   display: table-cell; /*inline-block*/;   min-height: 90%;   position: absolute;   top: 0;   width: 50%;   z-index: 2; } .switch > input[type="checkbox"]:not(:checked) ~ span:last-of-type {   left: 0; } .switch > input[type="checkbox"]:checked ~ span:last-of-type {   right: 0; } .switch > input[type="checkbox"]:focus ~ span:last-of-type {   border: 1px solid rgba(204, 204, 204, 0.8);   box-shadow: 0 0 5px rgb(102, 102, 102); } .switch.slider {   border-radius: 0.2rem;   box-shadow: 0 0 0.1rem 0.1rem rgb(187, 187, 187) inset; } .switch.slider > span:last-of-type {   background-image: linear-gradient(to bottom, rgb(255, 255, 255) 0%, rgb(153, 153, 153) 100%);   border: 1px solid rgb(0, 0, 0);   border-radius: 0.2rem; } .switch.slider > input[type="checkbox"]:focus ~ span:last-of-type, .switch.slider:hover > span:last-of-type {   border: 1px solid rgba(204, 204, 204, 0.8);   box-shadow: 0 0 5px rgb(102, 102, 102); }


Although this may require a few tweaks, such as changing the colors to match your design, this should be ready for you to test in your page.

Happy coding

Friday, January 20, 2017

Gather Ye Rosebuds: thoughts regarding collecting date values

One very common data types that we collect from users is a date value, whether it be a birthday or other anniversary or even something like a booking date for an event. Unfortunately, most of the date collection methods I've seen in the past two decades are sub par and the failure is even more pronounced when we consider the experience for those using assistive technology.

We've made some progress - we now, in HTML5, have a date type INPUT tag - but even there the experience is lacking. If we add in other considerations - like internationalization - we slide even further down this slippery slope, opting to do things like collect the date parts, i.e., month, day, and year, individually to make sure we have a valid date that's gathered in a manner that is somewhat familiar to the user.

Of course we have tools like datepicker, but unfortunately those are typically only partial solutions. Sure, they improve the interface for a number of users, but most still fall short, especially for those using screen readers...and that situation becomes even worse when they insert a calendar widget into a popup and focus is not managed well.

What's the solution?

Ideally, a tool that would automatically generate a visual calendar in the most common layout - a table with seven columns with each week in a row - and some common controls - like the ability to change the month and/or year using a next/previous button or a drop down list. The control should be in the flow of the document and it should include, at the very least, ARIA-* and role attributes so the experience doesn't suck if you're using a screen reader. Oh, and you should be able to navigate it easily using the keyboard, a mouse, or a touch-enabled device.

I don't really think that's asking too much. All it's really asking is that we, as UI engineers, consider how the experiences we are building are impacting people who are not like us. Maybe that's more along the lines of "everything and a kite" than "not too much", but I like to think we can do better than just OK. I'd like to think that when we talk about the MVP we're not really thinking about the MVE (Minimum Viable Effort - look for that in an upcoming post).

Now for a little good news. I've begun building such an interface. Since everyone seems to be hot after Angular these days, that's what I've used and I've built a prototype with a calendar directive. Granted, it's not 100% complete - there's still a little work to do to improve the accessibility and internationalization - but it's about 99 percent there. (You can see the prototype at http://prototypes.cathmhaol.com/ng-calendar/.)

The directive is not yet on my github, but it will be as soon as I've rounded a few of the rough corners, but you can easily download the source and the CSS (which includes a special trick that forces the table cells into squares) from the prototype if you're dying to get started building out a better date collector.

As always, happy coding.

20 February, 2017
The interface is complete and is available on GitHub at https://github.com/hrobertking/angular/tree/master/ng-calendar. A brief demonstration is below.

Friday, November 4, 2016

You've Got Mail: Easy, accessible notifications

Today it's just a quick post to talk about how to do those notifications we've come to know – and since they are relatively simple, this will be short and to the point. An image is provided to show a basic example of what I'm describing.

First, let's start with the markup.

Since you'll likely have a list of possible notifications – for example, alerts or messages – put them in an unordered list. Each list item will contain a count of items and a type of items as well as a link to the item viewer. This will give you markup something like the example below. Note that this markup is fully accessible as is; however, the accessibility may be improved by adding a label to the unordered list identifying it as a list of notifications.



HTML

<ul class="notifications">   <li role="status">     <a href="/alerts.htm">       <span class="count">4</span>       <span class="type">Alerts</span>     </a>   </li>   <li role="status">     <a href="/messages.htm">       <span class="count">100</span>       <span class="type">Messages</span>     </a>   </li> </ul>


If the notifications are a live region – if they're automatically updated while the page is displayed in the browser – be sure to add the role attribute and set it to status so that changes are announced when the content is updated. To show how that would work, the role attribute is included in the example. It is important to note that the markup be readable as is, regardless of where the message parts, i.e., the count and type, are displayed.

Next, you'll add the style rules.



CSS

ul.notifications { nbsp;nbsp;margin:0;   padding:0;   text-align:right;   font-family:Verdana; } ul.notifications > li {   display:inline-block;   overflow:auto;   margin-right:1em; } ul.notifications > li:last-of-type {   margin-right:0; } ul.notifications > li > a > span.count, ul.notifications > li > a > span.type {   display:block;   position:relative; } ul.notifications > li > a > span.count {   background-color:rgb(255, 255, 255);   border:1px solid rgb(0, 0, 0);   border-radius:2em;   float:right;   font-size:0.5em;   text-align:center;   line-height:2em;   padding:0.2em;   width:2em;   z-index:1; } ul.notifications > li > a > span.type {   float:left;   line-height:3em;   z-index:0; }

Here, you'll want to pay special attention to setting the overflow to auto on the list item (this will make the list item contain the floating items), and setting the border-radius to the same value as the line-height on the span with class count – 2em in the example. Setting the height, width, and border-radius all to the same value will give the circle effect. Using a value of 2em for height and width with a font-size of 0.5em will allow you to easily display 3 digits within the circle. Also, be sure to set the z-index on the count to 1 in order to force it to display over the type. It is especially important to set the z-index when the background is set, otherwise the overlap will likely not work as you intend.

You'll notice that in our example, the count span is floating to the right and the type span is floating to the left. This floating pattern makes the count float over the lowercase portion of the type, meaning less content is hidden when there is overlap. You may just as easily float the count span left and leave all remaining code the same in order to have the number displayed on the left side of the type text.

Once you've set the HTML and CSS, you're ready to add any JavaScript you wish, for example, to make the notification viewer display as a modal window or automatically refresh the number of items in the count element.

That's it - you have all the code you'll need to make easy, accessible notifications, so...

Happy coding.

Monday, April 4, 2016

An Even Better Credit Card

One of my most popular entries on this blog is the inline credit card entry form highlighted in A Better Credit Card.

While that overall design is efficient, it does not necessarily reduce the cognitive load of a page, and cognitive load is often a significant factor in conversion and general usability. After writing about using CSS transform to flip an image, I decided to revisit the card entry form to consider how it might be modified to reduce cognitive load. In the end, I decided to use a skeuomorphic pattern and build a prototype for card entry (which you can see in my prototype collection).

One word of warning before we begin: elements are positioned, shown, and hidden using CSS, but there is no way to modify the class attribute without using JavaScript. I am advising, therefore, that even though the markup can be used as-is, the CSS be initially applied using JavaScript. This step is not done in the prototype.

Here's how the prototype was built...

First, as I always do, I started with the markup. Since I'm using a skeuomorphic design pattern, my card entry form uses the card type, the account number, the customer's name, the CSC (or, as we say in the US, the CVV), and the expiration date and skips other inputs, like a starting date (does anyone even have a Switch or Solo card anymore?). Although it's not purely semantic, I did add a visual element for the mag stripe on the back of the card.

HTML
<form id="card_entry">   <div class="card" id="card">     <p class="magstripe" aria-hidden="true"> </p>     <fieldset class="card-type" id="card-type">       <legend>Card Type</legend>       <span class="card-icon">         <input id="amex" name="card_type" type="radio" value="amex">         <label class="card-type-label" for="amex">American Express</label>       </span>       <span class="card-icon">         <input id="visa" name="card_type" type="radio" value="visa">         <label class="card-type-label" for="visa">Visa</label>       </span>       <span class="card-icon">         <input id="mastercard" name="card_type" type="radio" value="mastercard">         <label class="card-type-label" for="mastercard">Mastercard</label>       </span>     </fieldset>     <p class="acct">       <label for="acct">Account number</label>       <input id="acct" name="acct" type="text" value="4123 4567 8901 2349">     </p>     <p class="name">       <label for="fn">Name on Card</label>       <input id="fn" name="fn" type="text" value="jane doe">     </p>     <fieldset class="expiry">       <legend>Good Thru</legend>       <p class="date">         <label for="expiry_mo">Expiration Month</label>         <input class="mo" id="expiry_mo" name="expiry_mo" type="text" value="12">         <span class="separator" aria-hidden="true">/</span>         <label for="expiry_yr">Expiration Year</label>         <input class="yr" id="expiry_yr" name="expiry_yr" type="text" value="25">       </p>     </fieldset>     <p class="security-line">       <span class="signature" aria-hidden="true">Your signature</span>       <label for="cvv">CVV</label>       <input class="cvv" id="cvv" name="cvv" type="text" value="123">     </p>   </div>   <button id="cardflip" aria-hidden="true" style="margin:1em;" type="button">?</button> </form>


Note
Although you will often need to collect an address along with card information, it will be to your advantage to create an address collection form component, because the format for each country is specific and creating a component - even a component for each country - will mean you won't have to repeat that work. Credit and debit cards, on the other hand, generally follow a single form regardless of country.

As you'll notice, the markup follows accessibility guidelines. Each INPUT has an associated label, there is a LEGEND tag for each FIELDSET element, and elements that are purely visual are hidden using aria-hidden. This is very important and is one of the ways we make sure the markup is semantic. To ensure the accessiblity features don't interrupt the visual representation, breaking our skeuomorphic pattern, I'm using absolute positioning with a clipped rectangle (which has proven to be the approach most recognized by assistive technology) to hide elements not visibly present on a physical card.

The meat in this dish is the CSS (rather than give a complete code listing here, I'm going to link to the stylesheet). The stylesheet not only positions the account number, name, CSC, and expiration date, it will either invert the card and display the CSC entry field (for any card not an American Express) or display the CSC entry field on the front of the card (for an American Express card).

CSS
.card {   background-size:cover;   background:rgba(100, 160, 200, 1) url("blank_card.jpg");   border-radius:10px;   border:1px solid rgba(170, 170, 170, 1);   font-family:monospace;   font-size:12px;   font-weight:800;   height:14em;   line-height:12px;   margin:0;   overflow:hidden;   padding:1em 0;   transition:transform 1s;   width:25.5em; } .card.invert {   background:rgba(100, 160, 200, 1);   -ms-transform:rotateX(0deg) rotateY(180deg);   -webkit-transform:rotateX(0deg) rotateY(180deg);   transform:rotateX(0deg) rotateY(180deg); }


By placing the transform rule on the card (CSS lines 17-22), the account number, name, and expiration date are all rotated as a single unit, leaving the matter of shifting the text-shadow and color to make the text appear inset rather than outset (since the name and account number are embossed on the card). All that remains after changing the text effect is hiding or revealing elements that are printed (not embossed), only appear on the front or back of the card - the expiration date label and magstripe, for example. Creating a 1 second transition effect for the transform (CSS line 14) animates the flip, reducing (or eliminating) the cognitive load associated with the interface change.

Note
To address the slight differences in Internet Explorer, there is an IE 9 stylesheet included in the prototype using a conditional comment and CSS rules (at the end of the card.css stylesheet) that look for IE 10 or IE 11 in the data-useragent attribute of the HTML. You can add the data-useragent to the HTML element by adding the following to your document head: <script>document.documentElement.setAttribute('data-useragent', navigator.userAgent);</script>


The prototype also includes some vanilla JavaScript that will change the class attribute of the card type input when the card type RADIO input is checked (using the onchange event) and will change the class attribute of the DIV card element to flip the card. Generally, if the user shifts focus to the CSC, we check to verify that we should invert the card (that the card is not an American Express). All other inputs are on the 'front' of the card so if focus moves to any other input, we remove the 'invert' class and show the front. The JavaScript provided as part of the prototype should not be used as anything other than a general guideline of how the interface should behave - it does not follow best practices because it is intended to be thrown away and is in its most basic, generally understandable form. Note: the JavaScript for this prototype will likely be modified in the future to enhance the prototype.

Note
The prototype also has a button that will flip the card so it's a little more mobile-friendly, specifically for devices that don't have a 'next field' button when entering data into forms. This button (HTML line 43) is separate from the card DIV but is placed close to the card so its meaning is a little clearer.


That's pretty much all there is to it - a skeuomorphic credit card entry form that will reduce cognitive load. There will be users who are more comfortable using it than the quicker inline form...but remember, you need to A/B test any changes to your user interface to figure out which is better for your users.

Happy coding.

Monday, February 22, 2016

A Modern Menu

I've been exploring a little, stretching my coding muscles again to see just how easy it would be to write an accessible navigation menu that slides out from the left on mobile but lies horizontally on a wide(r) screen. Now, let me begin by saying that writing one is easy...but writing a progressive, fully semantic version is not necessarily so. This post, however, will explain just that - how to write a progressively enhanced, fully semantic version that is accessible.

Rather than bore everyone with tedious code listings (yes, I'll have a few), I'm going to link to the proof-of-concept that will also have fully commented code, and here I'll give a general overview as well as a few things you'll want to notice along the way.

If this is your first foray into accessible coding, do yourself a favor and get the WAVE Evaluation Tool extension for Google Chrome, and if you're not already using the Mobile/Responsive Web Design Tester extension, get that as well.

As always, we first start with the markup and do the things we would normally do - add the lang attribute to the HTML tag, add a descriptive TITLE to the HEAD, and add a descriptive H1 to the BODY. Here's where I start my navigational menu code...inside the H1. In addition to using the H1 as a banner, I'm adding a 'button' that will toggle the navigation menu (note that this is only for mobile devices). Since this is only a visual interface for the menu, I'm not adding anything to it - no ARIA role labels. The 'button' span is empty, so without ARIA labels or role, accessibility technology will ignore it (as it should). After the H1, I'll add the actual menu...but more on that in a couple of paragraphs.

The user interface for mobile users, when the navigation menu is closed, will show a button that will display a hamburger symbol and when it's open it will display the x typically used on close buttons.

Note that I'm not actually using a BUTTON tag but a SPAN tag that acts like a button...and the primary reason for this is because the icon displayed inside the button is controlled using CSS and that's really impossible to do when you use a BUTTON tag. By attaching an event listener to the click event on the button SPAN, I add (or remove) opened to (or from) the H1 tag. The opened H1 and an adjacent sibling selector for the menu will control whether the menu is seen or not. If you want to use a different device to toggle the menu, feel free - and simply change the CSS so that the 'opened' class is attached to the menu. Since the content is not in the markup, I don't need any ARIA attributes like aria-hidden even though it's a control for the visual interface...and because the button in the H1 is only used on mobile, I wrap the styling in a media query using a mobile breakpoint.


HTML
<body>   <h1>     <span class="banner">Responsive Navigation Menu</span>     <span class="mobile-only button open close"></span>   </h1>   <div class="menu-overlay">


CSS
@media screen and (max-width:480px) {   h1 > .banner {     float:left;     height:1.65em;     line-height:1.65em;     width:80%;   }   h1 > .button {     border-radius:0.1em;     border:0.01em solid #ccc;     cursor:pointer;     display:inline-block;     font-size:1.25em;     font-weight:800;     height:1.1em;     padding:0.1em;     position:static;     width:1.1em;   }   h1 > .button.open.close::after {     content:"\2261";     cursor:pointer;     display:inline-block;     font-size:1.5em;     line-height:0.75em;     text-align:center;     width:0.75em;   }   h1.opened > .button.open.close::after {     content:"\00D7";   }

Now that we have the H1 set, I'm going to add the navigation menu to the page. I'm choosing to add the navigation menu before the content because (1) it's easier to style that way and (2) when the links are at the top it's easier for someone to jump to another location before all the other content is read - and they don't have to take extra steps, like using their AT to step through a bunch of landmarks.

HTML
  </h1>   <div class="menu-overlay">     <ul id="main-menu" role="navigation">       <li class="item">         <a href="?menu-item-1">Menu Item 1</a>         <span class="indicator"></span>       </li>       <li>         <a href="?menu-item-2">           Menu Item 2         </a>         <ul class="submenu">           <li class="item">             <a href="?menu-item-2.menu-item-A">               Menu Item A             </a>           </li>           <li class="item">             </a href="?menu-item-2.menu-item-B">               Menu Item B             </a>           </li>         </ul>         <span class="indicator"></span>       </li>     </ul>   </div>

There are a few things of note in the code. First, I've added a ARIA role (navigation) to the list. Rather than go into detail here about what a navigation role means, I'll instead point you to the W3 page about ARIA roles. Second, this example uses a sub-menu, which will become important when we talk about the CSS and the JavaScript. Additionally, I've identified LI items that contain menu items as items, which enables me to add LI tags that are used as separators. Each clickable item is wrapped in an anchor (A) tag, which allows me to leave sub-menu headers in tags that aren't automatically identified as clickable, e.g., SPAN. Finally, there is a SPAN tag with the class indicator regardless of whether or not there is a sub-menu. This enables a sub-menu visual indicator, which is not needed by accessibility technology, which will read the submenu because it's hidden using clip rather than a technique that would render the sub-menu invisible to AT.

CSS
ul[role="navigation"] > .item > .submenu {   background-color:#fff;   border-top:none;   border:1px solid #ccc;   box-sizing:border-box;   clip:rect(0, 0, 0, 0);   color:#333;   left:0;   list-style-type:none;   margin:0 -1px;   padding:0.5em;   position:absolute;   right:0;   transition:clip 1s;   z-index:3; }


There are a few things of note about the CSS. First, the style rules for the sub-menu will drop the sub-menu below the primary menu and make it appear as wide as the primary menu. Although this approach is not ideal, we're going to fix it using JavaScript - which will hit most users and those who don't have JavaScript running (or those who have a page with borked JavaScript) will still have access to the navigation menu. If you're coding for a mobile device and are using a toggle button, you might want to consider how users will get to the menu if their JavaScript is borked - you might even consider using a focus or hover pseudoclass.

Second, the initial value of the margin-left and margin-right is the border-width on the primary menu (ul[role="navigation"]) multiplied by -1. This extends the left and right border to the full width of the primary menu.

Third, by setting the position to absolute, we can change the left and right values and the menu will become more like a drop-down menu (remember that I said we'd fix the width of the menu with JavaScript just two paragraphs ago - well here it is, the initMenu function does it).

JavaScript
function initMenu(menu) {   var contained,       count,       index,       items,       mnu_item;   items = menu.getElementsByTagName('li');   count = items.length - 1;   while (count > -1) {     mnu_item = items.item(count);     contained = mnu_item.childNodes;     index = contained.length - 1;     while (index > -1) {       if ((/\bsubmenu\b/).test(contained.item(index).className)) {         contained.item(index).style.left = mnu_item.offsetLeft + 'px';         contained.item(index).style.margin = '0';         contained.item(index).style.right = 'auto';         break;       }       index -= 1;     }     count -= 1;   } }

Now, simply add a call to your JavaScript function to initialize the menu - something like initMenu(document.getElementById('main-menu')); - and you're done. The initMenu function will set the left position of the sub-menu UL to the left position of its LI container, will set the right value to auto (which shortens the width) and adjusts the margin so that everything lines up neatly.

So that's it. One last note - although I generally use a 'mobile first' approach (making the style sheet for mobile and then writing a media query for everything else) I didn't do it that way this time because the styles are different enough that they're difficult to re-use. In the proof of concept I've linked both stylesheets, but in your production code you might want to pursue an adaptive approach so only the mobile stylesheet is downloaded for mobile devices to minimize the payload - on the other hand, the stylesheets are pretty light as they are so it might not matter. Oh...and this is the proof of concept.

Happy coding.



Monday, February 8, 2016

A Question of Semantics

Aztec pyramidOver the past (nearly) 20 years, one of the webhead topics for which I have been an advocate is the creation of semantic code. In the beginning, it was "semantic markup" because markup was really all we had. A little while later we added stylesheets and several of us also began thinking in terms of semantic styles. Now we're seeing other features, such as animation, carry meaning and are beginning to think of them in "semantic" terms as well1. Each of these has been layered upon the other - a figurative Aztec pyramid. semantic and what does it mean to write semantically and why worry about whether or not our markup, or CSS, or any other level of code is semantic?

First, let's address what we mean by writing "semantic code".

Let's begin by saying that not all code is semantic. We spend significant time considering the content of a web site, a page, or an application and how it carries meaning, but the code that wraps the content can either carrying meaning or not. When I wrap content in a DIV or P tag, I know something more about the content than content that is simply terminated with a line break (BR tag). If I use HTML5 and wrap content in an ASIDE tag or ARTICLE tag, I know even more about the content than if I had wrapped them in a DIV or P tag.

As another example, if I wrap a number in a SUP tag the only thing I know about that number is how it should be displayed; however, if I wrap a number in a SPAN tag with a semantic class attribute - footnote, for example - I now know something more about that number. Similarly, when I add WAI-ARIA2 attributes, such as aria-describedby even aria-hidden I am describing the content even more fully3 just as surely if I use an EM or STRONG tag instead of an I or B tag.

To put it simply, semantic code includes not only content, but meta-communication about that content.

So, why worry about whether or not our markup, or CSS, or any other code is semantic? The simple answer is that the meta-communication in code is as important, and in similar ways, as tone and body language are in verbal communication. The importance of meta-communicating code is easily seen when assistive technologies, such as screen readers like JAWS or VoiceOver, are used. Simply consider the difference between a I (italics) tag and an EM (emphasis) tag or a B (bold) tag and a STRONG (strong emphasis) tag. One category is visually oriented, but the other is both visually and verbally oriented, leading to a not only richer, but more precise, experience...one with less cognitive load...and the lower the cognitive load, the better the user experience (which anyone who is "customer-focused" wants).

At this point you might be thinking "I see the importance of semantic markup and using ARIA semantics, but why bother with the rest". Consider this - what do you think your experience would be like if face-to-face communication were missing an element of meta-communication. Would you gather as much meaning? Would it be as complete? As a society, we generally don't think so, which is why we have all sorts of assistive technology intended to help us compensate for missing elements - each element is significant. This significance should be carried over into the coding world. I would posit that we ought to go so far as to say that when any element of the code does not qualify as semantic that the code as a whole is not semantic.

At this point we have only discussed general benefits of semantic code in relation to humans. I haven't even touched on the benefits of semantic code in relation to machines. By using semantic CSS, for example, browser plugins are able to interface more fully with other applications - like calendars - especially when the CSS is a microformat. This opens the door to creation of a number of symbiotic relationships between your code and existing applications, especially in mobile channels where we have merely scratched the surface.

Beyond what we typically think of as code, however, we must also make sure other features - like animation - are semantic (seriously, if you haven't read Motion with Meaning: Semantic Animation in Interface Design yet, go do it) or, at the very least, don't break our semantic model, just as we ought make certain those features in the user interface do not increase cognitive load. One of the methods people who design user interfaces have used for decades that helps maintain a semantic approach and also tends to reduce cognitive load is skeuomorphism4. One of the most common historic examples of this method is making a data input form mimic the paper version; however, there are numerous other examples - folder and file images for directories on a computer or an image of a envelope for mail or email are just two examples.

In a previous post I wrote about a different (credit/debit) card input form I had developed5. Although that post discussed, in more general terms, creating a form that validates a credit/debit card including determining the brand, it links to an input form that uses a minimalist style - and there are reasons to use a minimalist, semantic approach at times - and contains the JavaScript to perform the validation. One of the deficiencies in that prototype, however, is the lack of semantic animation (in the minimizing of the account number input). That deficiency is addressed in another prototype where I take a skeuomorphic approach and create a card input form that looks and behaves much like its real-world counterpart. Feel free to take a look at both prototypes and see which is a more complete, user-friendly experience. I'm confident you'll find the more complete the semantic approach, the better the experience. (Of course, a combination of the two - the technical validation of version 1 and the skeuomorphic design of version 2 - is probably closer to ideal.)

All the issues I've brought to the fore so far are focused on the customer (user) experience, as they should be. However, there are other sides to the use of a semantic approach - SEO advantages and your (hopefully) friendly interface engineer, for example. Although the SEO benefits of the use of semantic markup and styles are becoming less dramatic than they were in the past, they are still present, and that will likely not change. A document a machine can read and understand will always fare better than one that is less understandable. As for interface engineers - semantic code makes understanding what is likely to be a complex solution a little easier. Reducing the cognitive load for an interface engineer generally means more productivity and less frustration. More productivity and less frustration will generally result in better code, so getting into the practice of writing semantic code can become a self-reinforcing loop and make the world a better place. Best of all, it means more happy coding.

Reference Notes (please note that links open in a new window).
  1. Al Hazwani, Amin and Bernard, Tobias. Motion with Meaning: Semantic Animation in Interface Design. A List Apart. 19 January 2016. http://alistapart.com/article/motion-with-meaning-semantic-animation-in-interface-design (accessed 31 January 2016)
  2. The WAI-ARIA specification divides the accessibility semantics into roles, states, and properties. You can see that specification at https://www.w3.org/TR/wai-aria/usage.
  3. The WAI-ARIA semantics are very powerful, and getting their usage just right can be difficult, so if you're new to the whole "Accessible Rich Internet Applications" space, start with the W3C's ARIA Primer.
  4. Skeuomorphism is the practice of making virtual items - such as data input forms - resemble their real-world counterpart. (https://www.techopedia.com/definition/28955/skeuomorphism)
  5. King, Robert, 'A Better Credit Card', Getting Paid to Think [weblog]. 28 December 2012, http://gettingpaidtothink.blogspot.com/2013/02/a-better-credit-card.html.