Showing posts with label interface design. Show all posts
Showing posts with label interface design. 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.

Sunday, October 21, 2018

Open Sesame: A better password experience

password inputs with strength indicator from weak to strong
Password inputs are ubiquitous, but they're often poorly designed. Not because they're not announced or lack security features to prevent someone looking over your shoulder and discerning your password. Instead, it's the user experience that's poorly designed.

In order to be as secure as possible, we're encouraged to have strong passwords, but each site's idea of what makes a password strong varies and often users are left to guess what the requirements are until after they've tried to enter a password and it has failed the hidden validation rules. In many cases the only clue users have is a strength indicator that slides from weak to strong.

To improve the user's experience, I'm going to suggest you add a list of the hidden validation rules, something like the following.



  • At least one lowercase letter is required
  • At least one uppercase letter is required
  • At least one number is required
  • At least one special character from the following list is required: !, @, #, $, %, ^, &, or *

Additionally, it is going to be tempting to make these hidden validation rules present only during onboarding, when the user is creating an account. This practice will lead to unnecessary frustration when users try to login but cannot remember their password. The addition of the list of rules to the interface gives additional clues that can trigger a remembered password, so add the validation rules description list any time a user needs to input a password.

Additionally, when using this approach, one might consider hiding these rules behind an accordion or tooltip that is only displayed by some user action; however, I would recommend against that approach as it reduces the accessibility this practice improves.

Another word about accessibility here, and this is best explained through markup. As you will notice in the markup below, which creates the list, uses the aria-describedby attribute to tie the validation rules to the input.


HTML

<label for="password">Password</label> <input aria-describedby="required-features" id="password" type="password" /> <ul id="required-features">   <li class="missing">At least one lowercase letter is required</li>   <li class="missing">At least one uppercase letter is required</li>   <li class="missing">At least one number is required</li>   <li class="missing">At least one special character from the following list is required: !, @, #, $, %, ^, &amp;, or *</li> </ul>

At this point it may be tempting to include an icon - something like <li><i class="missing"></i>At least one lowercase letter is required<li> - however, you should not do this, because it causes a fragmentation issue, which is when the accessible name of an item is generated by the first element rather than appending all elements together. Instead, use the listing as is and use a CSS pseudoelement ::before to generate content, otherwise you're likely to hear "warning sign" repeated for each item in the list and the remainder of the text will not be announced. There are ways around this, of course, but it's generally best to keep to the simplest method.


In the near future, this pattern will be exposed in the roking react repo with automatic updates to the list as the validation tests pass. As with other components in the repo, accessibility issues will be resolved to provide the best possible user interface for everyone. Of course, you're encouraged to develop using this pattern in a way that meets your needs, even without using the roking react repo.

Happy coding.

Sunday, September 9, 2018

The Poor Babel Fish: The importance of clear communication and how to measure it

Meanwhile, the poor Babel fish, by effectively removing all barriers to communication between different races and cultures, has caused more and bloodier wars than anything else in the history of creation. ~ The Hitchhiker's Guide to the Galaxy
With all due respect to Mr. Adams, it wasn't the fault of the Babel fish, or the increased communication between different races and cultures that caused more and bloodier wars. In fact, we know that communicating clearly with each other is generally a good thing - as long as we have good intentions.

One of the few things those of us involved in building human/computer interfaces know for certain is that the cognitive load of the interface matters. The greater the cognitive load, the longer it takes someone to complete a process or read content on the web page. The longer it takes someone to complete a process, the less likely they are to complete the process. Larger e-commerce companies with large datasets, like PayPal and eBay, know how likely a person is to complete the checkout process given how long it takes them.

Cognitive load is also one of the most often overlooked elements of accessibility. We seldom spend time thinking about how difficult, or easy, it is to identify relevant items on a page and whether or not the content hierarchy is perceivable. We also seldom pay attention to how easy, or difficult, content is to read, which is yet another component of cognitive load.

Part of the avoidance of evaluating this last piece - how "readable" content is - is due to the fact that it's generally very difficult to assess "readability". In US English there are two formulas that can be used for evaluation: the Flesch Reading-Ease Score (FRES) and the Flesch-Kincaid Grade Level Formula. These two evaluative tools provide comparable scores for English language in other regions and have been pretty widely used; however, they do not apply to other languages.

The difficulty of assessing languages other than English presents unique challenges to assessing the accessibility of web pages with regard to internationalization. Because of my interest in both internationalization and accessibility, their convergence around another of my loves - language - makes this a very interesting topic for me...and, frankly, the main reason why I'm sharing this with you.

We tend to pay a lot of attention to the Flesch-Kincaid Grade Level Formula in the US, but that's not really a measure of accessibility, because it's not a measure of how easy or difficult it is to read, but a measure against a "typical" student's comprehension...and the whole idea of "typical" should be an anathema within the accessibility community. The Flesch Reading-Ease Score, on the other hand, is not a comparison of the content to other "typical" content, but a measure of the content itself, by analyzing the number of words and sentences and the number of syllables in the words used.

The number of syllables in word, in languages other than English, are not necessarily a measure of complexity, however. As a hypothetical example, if we compare the English (three syllable) phrase "take this drug" with the Spanish (nine syllable) phrase "tomar este medicamento", we get a FRES of 119.19 for English (which maps to roughly third grade, or an 8 year-old) and a FRES of -50.01 for Spanish, well beyond the reading ease of the Harvard Law Review. Even if we used the English phrase "take this medication", the FRES is still 34.59, a whopping 80 points greater than the Spanish phrase...or roughly the difference between fourth grade (US) and college graduate reading levels.

Granted, this is an extremely small, hypothetical example; however, there is simply no way to justify the difference between those two phrases. Even though many standards in the US specify readability requirements using the FRES, there must be a better way to calculate the readability, especially across languages.

If we look outside the US, and about ten years before the Flesch-Kincaid Grade Level Formula was developed, we find the Läsbarhetsindex. This formula is considerably easier to use than either Flesch-Kincaid readability tests - it's the number of words divided by the number of sentences plus the number of "long words" multiplied by one hundred and divided by the number of words. A "long word" in the Läsbarhetsindex is a word with more than 5 letters. The Läsbarhetsindex formula gives a score for "take this medication" of 36 and the score for "tomar este medicamento" is also 36.

While there is a general mapping of Läsbarhetsindex to educational levels in the author's native Sweden, such a mapping does not exist for other countries...which makes sense because every educational system is different. This, however, doesn't affect our use of this measure for accessibility, because as was mentioned before, for accessibility we need to evaluate the content, not necessarily compare the content to an educational level.

Although the definition of a "long word" may vary, depending on the language used, the remainder of the formula should work for measuring the readability of content for accessibility purposes.

To aid in your evaluation work, I've created a library that will soon be published via npm as roking-a11y. In the meantime - before it's published on npm - you can get the source in the roking-a11y repo on my GitHub profile.

I'm also looking into how else this can be used and extended. One of my plans is to perhaps modify the length of a "long word" based on a language code, and perhaps add guidance for specific score ranges. If you have ideas about how else this might be helpful, please leave a comment - I don't track issues or feature requests in GitHub. If you've done research in this area, I'd especially like to hear from you.

Happy coding.

Monday, July 23, 2018

One For All and All For One



All for one and one for all, united we stand divided we fall. Alexandre Dumas, The Three Musketeers 
I've been putting off attempting to write what I might call "What I've learned about accessibility in twenty years" for a while - partly because even though it's based on a presentation and therefore already written (in a sense), copying PowerPoint slides as images is not very satisfying. Mostly, though, it's because it's likely to be a really long post and those often tend to not perform well. Considering what I've seen in the industry recently though, it's maybe past the time I should have done it, either way, here it goes.

Before I seriously dive into this topic, I want to share a little information about myself. Over the past (almost) two decades I've worked with accessibility in both the public sector, where I was bound by Section 508 of the Rehabilitation Act (1973), and in the private sector, where I've worked with guidelines that are now published as the Web Content Accessibility Guidelines (or WCAG). Over that time I've not only built a significant amount of what we might call "product knowledge" about accessibility, but have built quite a bit of passion for the work as well. I'm going to attempt to share that passion and attempt to convince you to become what I call an "Acessibility Ally" (A11y*ally, A11y^2, or "Ally Squared") - someone who is actively supportive of a11y, or web accessibility.

What Is This Accessibility Stuff, Anyway?

A lot of discussions about interface accessibility start with impairment. They talk about permanent, temporary, and situational impairment. They talk about visual, auditory, speech, and motor impairment (and sometimes throw in neurological and cognitive impairment as well). They'll give you the numbers...how in the US, across all ages,
  • approximately 8 percent of individuals report significant auditory impairment (about 4 percent are "functionally deaf" and about 4 percent are "hard of hearing", meaning they have difficulty hearing with assistance)
  • approximately 4 percent of individuals report low or no vision (which are not the only visual impairments)
  • approximately 8 percent of men (and nearly no women) report one of several conditions we refer to as "colorblindness"
  • nearly 7 percent of individuals experience a severe motor or dexterity difficulty
  • nearly 17 percent of individuals experience a neurological disorder
  • nearly 20 percent of individuals experience cognitive difficulties
They might even tell you how all those numbers are really First World numbers and when you go into emerging markets where reliable access to resources is more limited the numbers double. They'll talk about how, in general, those numbers are skewed by age and how about 10 percent of people under the age of 65 report impairment while more than 25 percent of people between the ages of 65 and 74 report impairment (and nearly 50 percent of those 75 and older report impairment).

I don't generally like to start there...though I guess I just did. Accessibility is not about the user's impairment - or at least it shouldn't be - it's about the obstacles we - the product managers, content writers, designers, and engineers - place in the path of people trying to live their lives. Talking about impairment in numbers like this also tends to give the impression that impairment is not "normal" when the data clearly shows otherwise. Even accounting for a degree of comorbidity, the numbers indicate that most people experience some sort of impairment in their daily lives.

The other approach that's often taken is diving directly into accessibility and what I call impairment categories and their respective "solution". The major problem here is a risk similar to what engineers typically refer to as "early optimization". The "solutions" for visual and auditory and even motor impairments are relatively easy from an engineering point of view, even though neurological and cognitive difficulties are far more significant in terms of numbers. Rather than focus on which impairment falls into the four categories that define accessibility - Perceivable, Operable, Understandable, and Robust - we have to, as I like to say, see the forest and the trees. While there is benefit in being familiar with the Success Criteria in each of the Guidelines within the WCAG, using that as a focus will miss a large portion of the experience.

One other reason I have chosen this broader understanding of accessibility is that accessibility in interfaces is holistic. Everything in the interface - everything in a web page and every web page in a process - must be accessible in order to meet the definition of accessible. For example, we can't claim a web page that meets visual guidelines but not auditory guidelines "accessible", and if the form on our page is accessible but the navigation is not then the page is not accessible.

Why is Accessibility Important?

When considering accessibility, I often recall an experience in interviewing a candidate for an engineer position and relate that story to those listening. This candidate, when asked about accessibility, responded something along the lines of "do you mean blind people - they can't see web pages anyway". I've also worked with designers and product managers who have complained about the amount of time spent building accessibility interfaces for such a "small" group of users or flat out said accessibility isn't a priority. I've worked with content writers who are convinced their writing is clear enough for their intended audience and anyone confused by it is not in their intended audience - what I call the Abercrombe and Fitch Content Model.

For those who consider accessibility important, there are a few different approaches we might typically take when trying to sway those who tend be less inclined to consider the importance of accessibility. In my experience, the least frequently made argument for the importance of accessibility is one of a moral imperative - making an interface accessible is the "right thing to do". While I agree, I won't argue that point here, simply because it's the least frequently made argument and this is going to be a post that bounds the too-long length as is.

The approach people most frequently take in attempting to convince others accessibility is important is the anti-litigation approach. Making sure their interface is accessible is promoted as a matter of organizational security - a form of self-protection. In this approach, the typical method is a focus on the Success Criteria of the WCAG Recommendation alongside automated testing to verify that they have achieved A or AA level compliance. The "anti-litigation" approach is a pathway to organizational failure.

Make no mistake, the risk of litigation is significant. In the US, litigation in Federal court has increased approximately 400 percent year-over-year between 2015 and 2017, and at the time of this writing appears to be growing at roughly the same rate in 2018. Even more significant, cases have held third parties accountable and have progressed even when remediation was in progress, indicating the court is at least sometimes willing to consider a wider scope than we might typically think of in relation to these cases. To make matters even more precarious, businesses operating internationally face a range of penalties and enforcement patterns. Nearly all countries have some degree of statutory regulation regarding accessibility, even if enforcement and penalties vary. Thankfully, the international landscape is not nearly as varied as it was, as nearly all regulations follow the WCAG or are a derivative of those guidelines.

So, why, when the threat of litigation both domestically and internationally is so significant, do I say focus on the Success Criteria is a pathway to failure? My experience has repeatedly shown that even if all Success Criteria are met, an interface may not be accessible - an issue I'll go into a little further when I talk about building and testing interfaces - and only truly accessible interfaces allow us to succeed.

What happens when your interface is not accessible - aside from the litigation already discussed? First, it's extremely unlikely that you'll know your interface has accessibility issues, because 9 of 10 individuals who experience an accessibility issue don't report it. Your analytics will not identify those failing to convert due to accessibility issues - they'll be mixed in with any others you're tracking. Second, those abandoned transactions will be costly in the extreme. In the UK, those abandoning transactions because of accessibility issues account for roughly £12 billion (GBP) annually - which is roughly 10 percent of the total market. Let me say that again because it deserves to be emphasized - those abandoning because of accessibility issues represent roughly 10 percent of the total market - not 10 percent of your market share - 10 percent of the total market.

Whether your idea of success is moral superiority, ubiquity, or piles of cash, the only sure way to that end is a pathway of accessibility.

How Do We Become an Accessibility Ally?

Hearing "it's the right thing to do" or "this is how we can get into more homes" or, sometimes the £12 billion (GBP) number - one of those often convinces people to become at least a little interested in creating accessible interfaces, even if they're not quite to the point of wanting to become an Accessibility Evangelist. The good news is that even something as simple as making creating accessible interface a priority can make you an Accessibility Ally.

The question then becomes how to we take that first step - how do we create accessible interfaces. The first rule you have to know about creating an accessible interface is that it takes the entire team. Accessibility exists at every level - the complexity of processes (one of the leading causes of abandonment), the content in the interface, the visual design and interactions, and how all of that is put together in code by the engineers - all of it impacts accessibility.

At this point, I should give fair warning that although I'll try to touch on all the layers of an interface, my strengths are in engineering, so the Building and Testing Interfaces section may seem weighted a little heavier, even though it should not be considered more important.

Designing for Accessibility

If we were building a house we wanted to be accessible, we recognize that we would have to start at the beginning, even before blueprints are drawn, making decisions about how many levels it will have, where it will be located, and how people will approach it. Once those high-level decisions are made, we might start drawing blueprints - laying out the rooms and making sure that doorways and passages have sufficient space. We would alter design elements like cabinet and counter height and perhaps flooring surfaces that pose fewer navigation difficulties. To remodel a house to make it accessible, while not impossible, is often very difficult...and the same concepts apply to building interfaces.

Most projects that strive to be fully accessible start with Information Architecture, or IA (you can find out more about IA at https://www.usability.gov/what-and-why/information-architecture.html). This is generally a good place to begin, unless what you're building is an interface for a process - like buying or selling something or signing up for something. In the case of a process interface, you've basically decided you're building a house with multiple levels and you have accessibility issues related to traversing those levels...to continue our simile, you have to decide if you're going to have an elevator or a device that traverses stairs...but your building will still need a foundation. Information Architecture is like the foundation of your building. Can you build a building without a foundation? Sure. A lot of pioneers built log cabins by laying the first course of logs directly on the ground...but - and this is a very big but - those structures did not last. If you decide to go another route than good IA, the work further on will be more difficult, and much of it will have to be reworked, because IA affects a core aspect of the Accessibility Tree - the accessible name - the most critical piece of information assistive technology can have about an element of an interface.

Once your Information Architecture is complete, designing for accessibility is considerably less complex than most people imagine it to be. Sure there are some technical bits that designers have to keep in mind - like luminance contrast and how everything needs a label - but there are loads of good, reliable resources available...probably more so for design than for the engineering side of things. For example, there are several resources available from the Paciello Group and Deque, organizations who work with web accessibility almost exclusively, as well as both public and private organizations who have made accessibility a priority, like Government Digital Service, eBay, PayPal, and even A List Apart.

With the available resources you can succeed as an Accessibility Ally as long as you keep one thought at the fore of your mind - can someone use this interface the way they want rather than the way I want. What if they search a list of all the links on your site - does the text inside the anchor tell them what's on the other side? What if they're experienced users and want to jump past all the stuff you've crammed into the header but they're not using a scrollbar - is there something that tells them how to do that? Keep in mind that as a designer, you're designing the interface for everyone, not just those who can [insert action here] like you can.

Building and Testing Interfaces

When building accessible interfaces, there is a massive amount to learn about the Accessibility Tree and how and when to modify it as well as the different states a component might have. Much has been made of ARIA roles and states, but frankly, ARIA is one of the worst (or perhaps I might say most dangerous) tools an engineer can use.

We're going to briefly pause the technical stuff here for a short story from my childhood (a story I'll tie to ARIA, but not till the end).

When I was a child - about 8 years old - my family and I visited a gift shop while on vacation in Appalachia. In this particular gift shop they sold something that my 8 year old mind thought was the greatest thing a kid could have - a bullwhip. I begged and pleaded, but my parents would not allow me to purchase this wondrous device that smelled of leather, power, and danger. I was very dismayed...until, as we were leaving, I saw a child about my age flicking one and listening to the distinctive crack...until he snapped it behind his back and stood up ramrod straight as a look of intense pain crossed his face.

ARIA roles and states are like that bullwhip. They look really cool. You're pretty sure you would look like a superhero with them coiled on your belt. They smell of power and danger and when other engineers see you use them, you're pretty sure they think you are a superhero. They're very enticing...until they crack across your back.

Luckily, ARIA roles and states are almost unnecessary. Yes, they can take your interface to the next level, but they are not for the inexperienced or those who lack caution. If you're creating interfaces designed for a browser, the best tool you have to build an accessible interface is Semantic HTML. Yes, it's possible to build an interface totally lacking accessibility in native HTML. Yes, it's possible to build an accessible interface in Semantic HTML and then destroy the accessibility with CSS. Yes, it's possible to build an accessible interface with JavaScript or to destroy an accessible interface with JavaScript. None of the languages we use in front-end engineering build accessibility or destroy accessibility on their own - that takes engineers. The languages themselves are strong enough...if you are new to accessibility, start somewhere other than the bullwhip.

The next topic most people jump to from here is how to test an interface to make sure it is accessible. This is another place where things can get tricky, because there are a number of different tools, they all serve a different purpose, and they may not do what they're expected to do. For instance, there are tools that measure things like luminance contrast, whether or not landmarks are present, or if any required elements or attributes are missing - validating according to the Success Criteria in the WCAG. In this realm, I prefer the aXe Chrome plug-in (by Deque). Nearly all these tools are equally good at what they do, but - and here's one of the places where it can go sideways - tools that validate according to the Success Criteria are a bit like spellcheckers - they can tell you if you spelled the word correctly, but they cannot tell you if you've selected the correct word.

Beyond Success Criteria validation, there are other tools available (or soon to be available) to help verify accessibility, the most common of which are screen readers. Of screen readers available, some are free and some are paid - VoiceOver on Mac and JAWS on Windows are the most popular in the US - JAWS is not free, but there is a demo version you can run for about 40 minutes at a time. NVDA (another Windows tool) and ChromeVox are free, but less popular. In addition to screen readers, in version 61 of Firefox the dev tools should include a tool that gives visibility into the Accessibility Tree (version 61 is the planned release, this version is not available at the time of this writing).

One thing to remember with any of these - just because it works one way for you doesn't mean it will work that way for everyone. Accessibility platforms are multiple tools that share an interface. Each tool is built differently - typically according to the senior engineer's interpretation of the specification. While the results are often very similar, they will not always be the same. For example, some platforms that include VoiceOver don't recognize a dynamically modified Accessibility Tree, meaning if you add an element to the DOM it won't be announced, or it may only be announced if certain steps are taken, and the exact same code running in JAWS will announce the content multiple times. Another thing to remember is that there is no way you will ever known all the edge cases - in the case VoiceOver not recognizing dynamically added elements mentioned previously, it took more effort than it should have to demonstrate conclusively to the stakeholders the issue was in a difference in the platform.

Finally, when you're trying to ensure your interface is accessible, you will have to manually test it - there is simply no other way - and it should be tested at least once every development cycle. Granted, not every user story will affect accessibility, but because have that holistic view of accessibility that acknowledges that accessibility exists at every level, we know that most stories will affect accessibility.

As with design, there are resources available, but good resources are more difficult to find because engineers are opinionated and usually feel like they understand specifications, even though what they understand is their interpretation of the specifications. If you want to become an accessibility expert, it can be done, but the process is neither quick nor easy. If you want to become an A11y^2, well that process is quicker and easier and mostly consists of keeping everything said in this section in mind. Understand accessibility holistically. Make "Semantic HTML" and "ARIA is a last resort" your mantras. Check your work with one of the WCAG verification tools (again, I prefer the aXe Chrome plug-in) and at least one screen reader. Check it manually, and check it frequently.

Being an Accessibility Ally

Being an Accessibility Ally is really not complicated. You don't need to be an accessibility expert (though you certainly can be one if you want)...you just need to see accessibility as a priority and the pathway to success. Being an Accessibility Ally means you're actively supportive of accessibility.

To be actively supportive, one needs to understand accessibility in a more holistic way than we've traditionally thought about it and we need to understand that not only does accessibility accumulate, its opposite accumulates as well. In other words, inaccessibility anywhere is a threat to accessibility everywhere.

To be actively supportive, we need to do more than act the part by designing and building things like stair-ramps with ramps too steep to safely navigate with a wheelchair or Norman doors. We need to make building interfaces that are perceivable, operable, understandable, and robust a priority...and we need to make that priority visible to others.

When we're actively supportive and people see our action, only then will we be the ally we all need...and we all need all the allies we can get.



For another take on age and web interfaces, you may want to take a look at "The Danger of an Adult-oriented Internet", a post in this blog from 2013 or A11y Squared, a post from 2017. 

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.

Tuesday, December 5, 2017

Print It!

Several years ago, Smashing Magazine did an article called 5 Powerful Tips and Tricks for Print Style Sheets, but we don't often remember print stylesheets today because, let's be honest, people don't generally print things anymore - at most, we save them to PDF on our device - but it is still an important part of the design of the interface.

Print stylesheets, however, can be pretty powerful, and there are a lot of times we still want a hardcopy of something we've worked on. In the financial services sector, we see this fairly often. People want a record of what they've signed up for - especially when it comes to paying interest. It doesn't really matter if the "hardcopy" is a PDF or a tree-killing version you can hold in your hands, we want it to look official.

There are a few things you'll want to keep in mind when printing, but generally, read the Smashing Magazine article I've linked above. One issue the Smashing Magazine article doesn't go into detail about is font size. Don't mess about with the font size. There are loads of posts about accessibility and font size and how to use rem or em rather than px on a web page - the same holds true for printed versions. You don't want someone getting the small print version when what they see on the screen is large print.

One thing that deserves a special callout - the Smashing Magazine article talks about expanding links and this is very important. In printed versions the user will not (generally) have the ability to hover over or follow a link, so make sure the appropriate links are followed by the URL in plain text. I'd suggest making certain the following is in your print stylesheet.



CSS

a:not([href^=javascript]):after {   content: " <" attr(href) "> "; } a[href="#"]:after {   content: "" !important; }


I'm going to go a little further here, because if you wish to exclude other links, let's say anything linked to "foo.com", for example, simply add those to the first rule, and use the in-string regular expression operator, like so...


CSS

a:not([href*=foo\.com]):not([href^=javascript]):after {   content: " <" attr(href) "> "; } a[href="#"]:after {   content: "" !imporant; }


...and you've included the link, enclosed in < and >, in your printed versions.

You'll notice, that on line one there are two differences in the attribute selector. First, I'm using a different regular expression selector, *= and second, I have a \ before the "." in "foo.com".

The selector *= matches a partial value in an attribute (you can learn more about regular expressions in attribute selectors at https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), so take care that you have the most complete partial possible - in my example, links to barfoo.com would also be excluded.

Additionally, the . is a special character in CSS syntax (as are ":" and "/"), which means it will need to be escaped in order to be seen as part of the value, just as "http://www.foo.com" would need to be escaped as "http\:\/\/www\.foo\.com".

That's all there is to it - powerful selectors and the function that returns an attribute can make your printed (and saved-to-PDF) documents better for your users.

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

Wednesday, May 31, 2017

Unnecessary Complexity: A case against ReactJs

I'll admit, even though the title of this post might imply otherwise, my experience with ReactJs is limited. Unlike a lot of UI engineers, I have been working primarily in pure HTML, CSS, and JavaScript since I began more than two decades ago. Oh, sure I've used popular JavaScript “libraries” in the past – like YUI – and I've written more than a few over the years for some pretty big companies. I've also used some pretty popular “frameworks” – like BackboneJs – and combined them with other JavaScript libraries (e.g., NodeJs, Express, and DustJs). Overall, though, even though I had no prima facie opinion of ReactJs, I've avoided it – in much the same way that I've avoided winning the lottery – but all that has changed with the current workscape as more and more companies adopt ReactJs.

I should mention that I'm generally not a fan of any websites or applications built without using Progressive Enhancement, but then if you've read much of my writing you already know that, so the subtitle – A case against ReactJs – is a little misleading as this isn't just a case against ReactJs but against a practice of which the use of ReactJs is just an example.

I also must point out that I'm not a fan of the WSOD that results from many JavaScript-driven pages. While that's more a general issue with client-side frameworks and how they're woven into a front-end architecture, it also applies to ReactJs. I'm also not a fan of loads of JavaScript that is dependency heavy, intercepts DOM events, encourages a development process that isn't progressive, or discourages graceful degradation.

So, why single out ReactJs when it's clearly not the only library to do this? Good question. It's popular. Massively popular. From the number of job descriptions including it as either a requirement or “nice-to-have”, it's pretty easy to see that without knowledge of or experience with this particular library (it's not a framework), it's becoming very difficult to even get past the CV screening phase.

Although ReactJs is not the only example of client-side libraries that dot the Interwebz landscape, as one of (arguably) the most popular libraries, it bears close examination. And although ReactJs isn't the only example of what's wrong with UI engineering – there are plenty of other examples – most of them boil down to the willingness of engineers to sacrifice the user experience in an effort to make their job easier.
The more layers are piled into increasingly complex systems, the more failure paths we introduce. We’ve learned that automation does not eliminate errors. Rather, it changes the nature of the errors that are made, and it makes possible new kinds of errors. Capt. Chesley B. “Sully” Sullenberger

I hear you, and yes, they do say that it's a poor craftsman that blames his tools, which means all this flak I'm directing toward ReactJs might be misplaced. Am I not just blaming a tool for poorly-written code? There are two distinct lines of response that I would take. First, saying that it's a poor craftsman that blames his tools does not imply that the tools used are unimportant. No craftsman would wield a dull blade that made rough cuts when fine cuts were the goal. Every craftsman knows that other famous tool-related expression that clearly says when the only tool you have is a hammer that everything looks like a nail. There is a tool appropriate to every job. Second, I would posit that libraries and frameworks – things like ReactJs – are not, in fact, tools.

If we look at the artisan analogy, the tools in that case are HTML, CSS, and JavaScript. Libraries like ReactJs, and even frameworks like AngularJs, are not really an artisan's tools – they're not the base ingredients that make up a dish, the closer analogy is that they're the prepared foods other artisans have made. As prepared foods, they make the kitchen's job easier, but at a cost, because they remain in the end product even after it's gone to market. They're the frozen, processed food of the Interwebz, encouraging people working in the kitchens to masquerade as Beard Award winners.

Taking this foodie analogy further, as each new processed food is typically built upon other processed foods, the list of ingredients (dependencies) grows longer as “more layers are piled into increasingly complex systems”. These increasingly complex systems (dishes) are not only more fragile but also fraught with other issues, such as increased payload size (which is an issue for anyone connecting over a data-limited network, like mobile) and performance issues as all downloaded code executes in the browser. In the end, users end up with a bloated mess, but at least the “engineers” got the code out in time. They are literally, as the saying goes, “getting shit done”...and just as we wouldn't call someone working in a kitchen combining prepared foods into what must only loosely be described as a “dish” a “chef”, we shouldn't call those who create the monstrosities only loosely termed a “user interface” an “engineer”.

We must, as a community, get back to building actual user interfaces. We must, as a community, stop the madness. We must, as a community, become engineers again. Get the HTML out of your JavaScript. Get the CSS out of your JavaScript. Build agnostic, slim interfaces that everyone can use. We must, as a community, because we are the only ones who can.