Category: web development

US Healthcare Websites are the Worst

How many healthcare websites were designed by someone who knows nothing about user interface design?

A: All of them

A mass of tiny links with no organization
Garbage Healthcare Insurance Website

Call to action? 🤣

Let’s say you wanted to log into the member portal. Where is it?

(I cropped the header off because this particular insurance company is not special in any way; they all suck more or less the same way)

Good luck, it is in the bottom of the screen. There’s no menu, no LARGE call to action. Nothing.

In fact there’s no menu at all.

The first time I tried to find it, I skimmed until I came to “Member Services” and clicked it. WRONG!

The link for the portal is below the member services link.

What can you do?

Nothing, absolutely nothing. Except learn from these idiots’ mistakes.

  1. Figure out what is the most-used function for your website.
    • For potential new customers,
      • a link to a plan summary that shows the difference between plans and their costs, and
      • links or buttons to enroll in a particular plan
    • For new customers, it is two or three things:
      • Getting an ID card,
      • Finding an in-network† doctor, and
      • possibly paying the first month’s premium (rare) forget it, no one is going to do this unless you’re on Obamacare which was burnt and put up on blocks by the GOP.
    • For existing customers it is two things:
      • Checking balances (deductibles),
      • Reviewing Explanation of Benefits (EOBs),
      • Locating a doctor, and
      • Printing a new ID card
  2. Make the most-used functions FRONT AND CENTER, with as few actions (mouse clicks, scrolls, typing) as possible.
  3. Make it so your site does all the heavy lifting, figuring out what to place in front of the user based upon their needs.

What they did

Here’s what they’ve determined their customers are most interested in

  • Deciding whether they are Medicare Advantage or Obamacare patients

Then as an afterthought, at the bottom,
away from everything else,
in small print:

  • Find a doctor – will be used while a person is trying to figure out where they can go
  • Enroll Now – will only be used once and never again
  • Member Services – what the hell does that even mean? Will customers use this often or not at all?
  • Agents – Never used by any customer
  • Agent Portal – Never used by any customer
  • Member Portal – probably used by customers, a lot
  • Provider Portal – Never used by any customer
  • Pay Now – used by a tiny, tiny fraction of customers that don’t have job-provided insurance. Will only be used once to set up auto payment, except for that even smaller fraction of people who don’t trust autopay (probably 5 people)

Out of that whole mess, 13% (or maybe 26%) will be used by customers several times, 13% will be used once, 38% will NEVER be used, 13% will be used by a tiny fraction of customers one time (and a minuscule number more than once).

Worst case, 13% will be used by customers and 87% will not be used, yet they are almost all treated as having the same importance (for options on the second and third lines–which happens to contain the more-important options–they are slightly worse)

A clown sitting in the trunk of a car

Don’t do this. Ever.

Unless you’re a clown.

More Information

Misunderstanding Cookies

In a recent column, Tracey Capen posits the reason so many sites are displaying the “This site uses cookies. Click ‘okay’ to continue” banner is because of Advertising—specifically because many people use ad-blockers so the advertisers want to still be able to track you.

 

Cookies in the EU

He almost accidentally mentions the actual reason for these banners: EU Regulations on privacy. Specifically, the regs state that websites must notify visitors before the site places cookies on the visitor’s browser, AND give them an option to opt out before that happens.

English: Tor Logo
(credit: Wikipedia)

So why do we in the non-EU part of the world see these banners? Because it is simply easier to display the banner to everyone, rather than by attempting to determine if the visitor is in the EU and displaying the banner IFF they are.

There are a myriad of ways to mask one’s location, such as using the TOR network, so the risks of failing to show the banner (and getting fined) versus just displaying it to everyone is a no-brainer.

But what about Advertisements?

Ads—and their ad-delivery network—use cookies in a variety of ways. Advertisers are charged by the networks for impressions (number of people to whom the network delivers the ad or CPM) and for the number of people who click on the ad (clickthroughs). The latter is more valuable to the advertiser and thus the networks charge more.

The ads aren’t directly loaded on the page without the network because there needs to be a system that counts the number of impressions, rotates multiple ads in the page location, and stops showing an ad when the ad’s CPM is exhausted. If an advertiser pays for 5,000 CPM, once 5,000,000 visitors visit the page, the next visitor will not see that ad.

When an adblocker runs it does at least one of two things: it blocks the ad code or (more likely) it blocks the ad delivery network code. What this means is the visitor’s browser doesn’t even request the code from the server; NOTHING from that server is requested. No code means the ad network can’t run and deliver the ads. Also, without a request, there is no cookie.

Even if somehow the site displayed the banner (“please accept our marketing/advertising cookie” Capen imagines them saying), the cookie can’t be added because there is no cookie. There is no ad network that loads. There is no ad to display.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

How to screw up estimates

A historic black-and-white photo of a train wreck, illustrating the importance of accurate project estimates.
(Photo credit: Wikipedia)

“I need a time and cost estimate to develop a fizzbuzz mobile app on all minor mobile platforms (Windows/Blackberry/Symbian), and I need that estimate in 15 minutes.”

Enhanced by Zemanta

 

Do it correctly: decoupling presentation from content

Box model in CSS

Box model in CSS (credit: Wikipedia)

I recently ran across the anti-pattern of what I see as a common problem amongst designers and developers: coupled presentation and content. I’ve found that decoupling the presentation from the content makes things much easier to write, maintain and expand.

Here’s a simple example:

HTML

<section>
    <div class="margin-top-10">Lorem Ipsum</div>
</section>

CSS

.margin-top-10 { margin-top: 10px };
.margin-top-20 { margin-top: 20px };
(etc)

Take a look at what is going on here: we’re adding a 10px margin to the top of the div. DON’T DO THIS. You want your class names to be contextual, not descriptive of the style.


Rule of thumb

To change the layout, you should only have to edit the CSS, not the HTML.

Here’s where our anti-pattern falls down and will cause grief.

  1. You decide to adjust the positioning of the section. You can:
    • Edit the CSS, changing the class’s margin value and breaking every other element that uses that class.
    • Edit the HTML create a new class, then edit its CSS class definition. If you have to experiment with different margin values, you’ll need a LOT of classes. “Will 14px work or 15px? What about .25em? Argh!”
  2. You can’t have too many attributes in each class, because they will have unintended consequences for the other elements that are using them. Add a red border to one class because you need a border for a specific element, now you have red borders on ALL the elements that share that class. So, you’ll have to have many single- (or few-) attribute values, and include all of the necessary ones on the required HTML elements.
  3. The violent psychopath maintenance programmer (who knows where you live) will kill you in your sleep. You have made her job insanely hard by turning this:
<div class="margin5 blueborder mediumwidth floatingleft" ...

into this

<div style="margin:5px;border:3px blue outset;float:left;width:75%" ...

for no good reason.

The Cure

Think about the element in terms of content or a functional space. What is it and what does it do? In our example above, let’s assume it is the lede section of an article. Then we would do:

HTML

<section>
    <div class="lede">Lorem Ipsum</div>
</section>

CSS

.lede { 
  margin-top: 10px;
  border-bottom: 2px #9fe2f9 outset;
  float: right;
  position: relative;
  width: ...
};

By decoupling the content (div) from the presentation (style-dependent class), we are free  to adjust the style of that element by making whatever changes to the CSS and leaving the HTML alone.

“But,” you shriek, “I have common elements for everything! Rounded corners! Gradients! (except IE…) Et cetera!”

 

For this, we will turn to our trusty companions Less and/or Sass in a future post.

SASS: Style w/ Attitude

SASS: Style w/ Attitude

Enhanced by Zemanta

Why Flash Intros are bad and you should feel bad for using them

Remember when flash introduction pages were all the rage? They were ‘cool’ from the web designer‘s standpoint, but utterly annoying and off-putting to the visitor. Fortunately, most people figured out that people visited their site for the content, not the snappy graphics (unless it was a gallery site), and certainly not for the mandatory intro pages.

Yet, some people still haven’t gotten the clue that the 80s called and they want their flash intros back.

xkcd: the seventies called

For those who remember with revulsion, here’s the old SkipIntro parody. The site is long gone, but it would be a shame to let it fade away!

SkipIntro

If you haven’t clicked on it, do it now! Relive the pain of the never-ending flash intro to the sound of weird Indian music and gunfire!

The OG SWF

For those who somehow can still play flash file (via a plugin or whatever), here is the original SWF:

Find Something You Like and Dissect It

Image representing Wikipedia as depicted in Cr...

Image via CrunchBase

I’m always on the lookout for a new technique or Better Mousetrap. I admit I don’t know all that much, so I’m happy to learn.

I was playing around with Wikify @ appointment.net (a nifty tool that goes through a block of text and ‘wikifies’ it–that is, links all the words it can find to relavant Wikipedia articles) when I noticed the behavior seemed rather…odd. I could see it go through the word list as it created links, and every time it linked up a word, every duplicate word was linked.

Let’s take some example text (from the now-defunct Dilbert Mission Statement Generator) and run it through the site:

“We have committed to synergistically fashion high-quality products so that we may collaboratively provide access to inexpensive leadership skills in order to solve business problems“

Our mission is to continually leverage existing seven-habits-conforming catalysts for change as well as to competently leverage other’s error-free materials.

We globally leverage other’s professional meta-services as well as to conveniently integrate competitive solutions in order to solve business problems.

“It is our job to continually foster world-class infrastructures as well as to quickly create principle-centered sources to meet our customer‘s needs”

“Our challenge is to assertively network economically sound methods of empowerment so that we may continually negotiate performance based infrastructures“

For example, the additional instances of “leverage,” “problems,” and “business” were quickly linked, once the first one was completed. Poking around their code, I noticed all the action takes place in wikify.js. There are a few gems in there. For example, the function call to reduce an array to only unique values:

function array_unique( array ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      input by: duncan
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nate
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Michael Grier
  // %          note 1: the second argument, sort_flags is not implemented
    // *     example 1: array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
    // *     returns 1: ['Kevin','van','Zonneveld']
    // *     example 2: array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
    // *     returns 2: {'a': 'green', 0: 'red', 1: 'blue'}

    var key = '', tmp_arr1 = {}, tmp_arr2 = [];
    var val = '';
    tmp_arr1 = array;

    var __array_search = function (needle, haystack) {
        var fkey = '';
        for (fkey in haystack) {
            if ((haystack[fkey] + '') === (needle + '')) {
                return fkey;
            }
        }
        return false;
    };

    for (key in tmp_arr1) {
        val = tmp_arr1[key];
        if (false === __array_search(val, tmp_arr2)) {
            tmp_arr2[key] = val;
        }
        delete tmp_arr1[key];
    }
    return tmp_arr2;
}

Aha! See how that works?

Enhanced by Zemanta

The Importance of Not “Designing” your own Security

Recently, at a client, I had the opportunity to review their security implementation on their website. I realized that it is very important to never try to design one’s own security, because of the Dunning Kruger effect. In a nutshell, folks who don’t know very much about security think they know “enough,” and folks who are very knowledgable (e.g., Bruce Schneier) realize they don’t know all that much.

So what does this mean? It means simply this:

Broken bike lock
Not so secure now, is it?

If you design your own security system, you’re going to get it wrong.

Here are some examples of how to get things wrong.

Storing passwords in plaintext so you can send the person the password if they forget.

When (not if) someone breaks into your database, they instantly own every single account. They can log in, view your user’s details and change them. Since most people reuse the same password for multiple systems, the attacker can try those passwords on other popular services, such as Facebook, GMail, LinkedIn, Twitter, etc.

Relying on application-level security to protect your data.

This is dangerous because it is hard to ensure 100% coverage. EVERY access point—of many—to your data must be secure. Failing to cover one point leaves the system wide open. A better solution is to apply security at the data-store level. Typically, this is done using triggers and stored procedures. Your RDBMS doesn’t support those (or weakly supports them)? Find another RDBMS.

Using the same salt for every password in the system.

You don’t understand what salts are for and how to use them properly.

Requiring “complex” (a number, upper- and lower-case letters and symbols but not very long) passwords.

Nope. Ineffective.

Relying on Two-Factor Authentication.

For now it is working, somewhat, but crackers are rapidly finding ways to circumvent this technique.

Relying on a “security question” in case the person forgets his/her password.

Oh, you’ll love this. You’re creating a weak password as a backup to a (hopefully) strong password. Fail.

Assuming by keeping the details of your implementation secret, you will be secure.

This is dangerous because you think you’re secure. In fact, you are less secure. Kerckhoffs’s Principle is always a good starting point for security implementation: if an attacker could see all of my code and had a copy of my database, could she/he break into my system?

Getting it right

The first step is admitting that you don’t know what you’re doing.

Now go find someone who does: there are plenty of security libraries out there for every language. Find one that is mature and widely used and implement it. Keep up to date on the library’s mailing list so you will receive alerts, and update whenever there’s a new version.

Security is hard to do. It is extremely hard to do correctly. Don’t fall into the trap of thinking you can get it right without years and years of study and experience.

Related articles

Edit (30 Jan 2026) – Formatting, fixed links, added missing image