Blog


Apr

How to annoy all moose a little less (by building accessible websites)


A moose putting its tongue out

I have a close relationship to moose. Of all the good things this has brought me in life, one that really stands out is that it gave me my current job as a designer here at Elabs. This makes me thankful to moose, and I want to give something back.

As a designer who writes code, I make choices daily that impact how well a moose can percieve and navigate our web applications. A lot of the time, I make it very hard for them. I could do better.

I'm by no means an expert on moose accessibility, but recently I've been eating the brains of smarter people to gain their knowledge. I would like to share a few tips on how to make life a tiny bit easier for moose that surf the web.

As a coincidental bonus, these tips should improve accessibility even more for humans (and their different function variations).

I'll focus on some very basic things that many of us still get wrong, but is easy to get right.

Remember the semantics

A link is not a button. An <a> with href should link to another resource, while a <button> performs an action in the current view (such as submitting a form or opening a modal window). Buttons come with built in behavior that links don't have, like being activated by pressing space. Want something more discreet than a button for a minor action? Style it like a link.

Mind your headings. Be carfeul when you're building your heading structure, to make sure you're not skipping levels. Headers are the backbone of the document and a common way of navigating it with a screen reader. Don't pick heading level based on style or font size. If you want the look of a <h3> where a <h2> should be, try styling it with <h2 class="h3"> or similar. Also, Harry Roberts argues that your logo is an image, not a <h1>.

Placeholders are not labels. We hear this all the time, but still get this wrong sometimes. Many site search inputs still use placeholder text as their label (or nothing at all, and solely relies on the "Search" button to convey its function). If you need a compact search form, hide the label in a way that doesn't hide it from screen readers, like this .visually-hidden class does.

Is it content? Serve it to everyone.

Provide text alternatives. Until Google finishes their automatic image captioning algorithms, we're stuck with writing alt texts ourselves, whenever we use an image that qualifies as content (as opposed to styling). It's especially important when the image is a link, since screen readers will read out the link URL as title if no alt is present for the image.

Links should be self explanatory. Using "Click here" or "Read more" as link text makes the destination a mystery if you're navigating a page by jumping through its links, which is often what screen reader users do. Ambiguous links is the third most problematic item on the web (after CAPTCHAs and Flash) according to a WebAIM Screen Reader User Survey.

Color alone can't be trusted. Don't rely on just color to convey meaning, make sure there are labels or other visual clues to complement. Keep it in mind when styling states of interactive elements, such as :focus states of inputs or :hover states of links. Around 8% of human males and 100% of female and male moose have a color vision deficiency. What if it was your moose?

Apples of different colors to illustrate color vision deficiency types

Types of color vision deficiency (dichromacy)

Stay legible

Zooming should not break anything. Being able to zoom a page is important for individuals with poor vision (like... every moose), or just anyone tired of tiny text. Make sure your site doesn't break when zooming. Use relative units for font sizes and margins/paddings. Font sizes set in px zooms well in many browsers today, but not at all in IE (not even in IE 11 – it's by design). Remember there's a difference between zooming an entire page, with images and everything, and increasing the browser's font size. The latter is common if you're finding the web site's default font size hard to read.

Check your contrast. It's not just for elderly people. Sometimes we forget about low quality monitors, sun glare, tiny handheld screens, or a combination of them. Use Lea Verou's contrast ratio tool, the Sketch color contrast plugin, or ask your friendly neighborhood moose to have a look.

Key value

Some people and most cats hate mice. Try to make all parts of your website keyboard accessible. Tab through it and make sure there is a :focus state for every :hover state. Be extra careful with any custom widgets, especially modal windows.

Keyboard with apples as keys

Äpple Bluetooth Keyboard (the number one input device among moose)

Going further

These tips were absolute basics, they should be a part of every project. Still I cheat and I get lazy, and I know I'm not alone. These things are not that hard, they're just tweaks to your workflow.

Once you've managed to annoy moose and people a little less, go the next mile and learn how to do some real difference:

Dec

Has Microsoft become altruistic or is cooperation simply better than competition?


The market economy prides itself on its competitive nature. Through competition we’re promised better and cheaper products and services. I believe this to be true in countless cases. I also believe that we need to be better at considering both the benefits and the inefficiencies that the competitive model brings. As with any dogma it can do just as much harm as good unless constantly being evaluated from a case-to-case perspective.

Retrieved from http://www.teslamotors.com/models/photo-gallery

Consider for example what companies do to protect their investments in research and development. Companies are constantly suing each other over patents and spending billions on lobbying to make IP-laws stricter and more far-reaching. We buy this concept because we believe competition is more effective than cooperation. It’s been this way for so long that it’s hard to even imagine the alternative. Who knows what kind of cars we would have if all the car manufactures cooperated in their RnD. Maybe we would all have been driving the Tesla Model S ten years ago, maybe we would still be stuck in a Trabant, who knows?

Given this blog post being on a software development firm’s blog you’ve probably already figured out where this is going. Open Source is a large-scale, unconditional, more or less all-in choice of cooperation before competition, and it works! 59% of all web sites run on open source web servers. 95% of smart phones run on open source technology. 82% of users access the Internet using a web browser built on an open source foundation. With Microsoft’s recent release of the .NET framework as open source pretty much all major programming environments are now open source.

Retrieved from http://www.flickr.com/photos/gforsythe/8174197748/ Illustration by Giulia Forsythe

In my experience open source projects tend to be numerous and diverse, allowing the user to choose a project that suits their needs. Often times they have large and helpful communities, answering questions in time zones all around the globe. Open source products are often free, and thus available to more users. Simply giving more people access to others’ creations can spawn innovation that would be lost in a closed environment.

As a software consultant I know that trust is key. When there is lack of trust there is legal overhead, misinformation and static control structures that prevent agility. These projects tend to be more expensive and deliver inferior results. Open source requires a whole bunch of trust. Put yourself in Microsoft’s shoes. Would you find it easy to “give away” technology that you’ve spent billions developing? You’d need to put your trust in people you’ve never met, hoping you will get back as much as you’ve given.

Open source in the software industry might be the most obvious example of trusting others to do something great(er) together. But in fact our entire civilization requires us to trust in each other. Without trust currency would be hugely inconvenient, e-commerce would be impossible and we would have no taxes to pay for services such as law, defense and education.

I don’t believe every sector would benefit from unconditional cooperation but I’m certain that there are vast possibilities to create better, cheaper, fairer, and safer products and services if we start trusting each other more!

Which sectors do you think would benefit from replacing competition with cooperation? How can the software industry benefit from even more cooperation? Or have we gone too far? Use the comment section below!

Apr

Steve Jobs on what's important in the development of a product


You know, one of the things that really hurt Apple was after I left John Sculley got a very serious disease. It’s the disease of thinking that a really great idea is 90% of the work. And if you just tell all these other people “here’s this great idea,” then of course they can go off and make it happen.

And the problem with that is that there’s just a tremendous amount of craftsmanship in between a great idea and a great product. And as you evolve that great idea, it changes and grows. It never comes out like it starts because you learn a lot more as you get into the subtleties of it. And you also find there are tremendous tradeoffs that you have to make. There are just certain things you can’t make electrons do. There are certain things you can’t make plastic do. Or glass do. Or factories do. Or robots do.

Designing a product is keeping five thousand things in your brain and fitting them all together in new and different ways to get what you want. And every day you discover something new that is a new problem or a new opportunity to fit these things together a little differently.

And it’s that process that is the magic.

— Steve Jobs, Triumph of the Nerds

Via 37signals and CNN Fortune Tech

Mar

Handle secret credentials in Ruby On Rails


This blog post aims to lay out a simple and concrete strategy for handling sensitive data in your Ruby On Rails applications, and to explain the importance of such a strategy.

Never, ever check them into source control

Even if your project is closed source and your trusted colleagues are the only ones with access, you never know when a freelancer or consultant might be joining the project. Even if that never occurs, how do you keep track of all the locations where that repository is checked out? Who knows on how many hard drives your company's credit card transaction secret API key might be stored. What happens when someone with a weak login password forgets their laptop on the bus or at the airport?

Also note that it's not always as simple as removing secrets after the fact, especially with version control. It's usually impossible to do this without drastically changing your entire project's history!

Do it right

For a long time, we've been using YAML files to store our application configuration. It's easy to manage and can be configured for different Rails environments. These YAML files could look like the following:

config/app.yml:

development: &defaults
  awesomeness_score: 3
  host: "localhost:3000"
  s3_bucket: "example-development-us"

production:
  <<: *defaults
  host: "example.com"
  s3_bucket: "example-production-us"

test:
  <<: *defaults

config/app_secret.yml.example:

  development: &defaults
  aws_access_key_id: ""
  aws_secret_access_key_id: ""

production:
  <<: *defaults

test:
  <<: *defaults

config/app_secret.yml:

development: &defaults
  aws_access_key_id: "ACTUAL-ID-WOULD-GO-HERE"
  aws_secret_access_key_id: "ACTUAL-SECRET-WOULD-GO-HERE"

production:
  <<: *defaults

test:
  <<: *defaults

Only the first two files would be checked in to source control, and the application's README would instruct developers to cp config/app_secret.yml.example config/app_secret.yml and fill in the gaps from the company keychain.

To make sure we never check in the secrets by mistake, we ignore the app_secret.yml file:

.gitignore:

# ...
/config/app_secret.yml

We then use the econfig gem written by Jonas Nicklas to easily merge them together:

Gemfile

# ...
gem "econfig", require: "econfig/rails"

config/application.rb

# ...
module YourApp
  extend Econfig::Shortcut
  # ...
end

Now we can access any configuration variable and secret credential:

YourApp.host # => "localhost:3000"
YourApp.aws_secret_access_key_id # => "ACTUAL-SECRET-WOULD-GO-HERE"

Deploy

When you deploy the application, you must manually manage the secrets on the server(s).

Capistrano

If you deploy with Capistrano, you'll want to place the app_secret.yml in your /shared folder. Once that's done, it can be copied to each release with symlink task:

deploy.rb

# ...
namespace :config do
  desc "Symlink application config files."
  task :symlink do
    run "ln -s {#{shared_path},#{release_path}}/config/app_secret.yml"  
  end
end

after "deploy", "config:symlink"

Heroku

If you're deploying your application where you don't have file access, such as Heroku, you're better off storing this kind of information in ENV. The econfig gem has built in support for this and a few other storage backends, but that's another blog post.

Conclusion

With this method, we now have a clear separation of sensitive and non-sensitive data. There's no risk of checking in any sensitive data, since we have only one place to put it all and it's hidden from source control. Data access within the application hasn't changed, and we no longer have to concern ourselves with how sensitive it is.

We can now be sure that giving access to a repository does not imply giving access to other systems.

Epilogue

If you have any feedback on how the blog post can be improved, or if you spot any errors, please let me know by posting a comment below!

Mar

How to write a bug report


This is a blog post I've wanted to write for a really long time. Every couple of days I get an issue reported to one of my open-source projects which looks something like this:

Capybara doesn't work

It's totally broken. I tried everything. Why doesn't it work? Please fix it for me!

Okay, maybe it's not quite that bad. As you might guess, such a bug report is completely useless, it's just a burden to everyone involved in the project to have to tackle this kind of stuff. Worse than that, the person who posted this isn't going to get the help they need, and their possibly very legitimate issue is not going to get fixed.

Every time I receive one of these I wish there were some kind of source I could point these people to, so they might learn how to contribute with insight to open-source projects, instead of being a burden. This is that source.

Closed source

This stuff only applies to open-source, free as in beer and speech projects. Closed source projects are a different game, though some of this advice may still be useful.

The holy grail of bug report templates

This is where you should start. I can't remember which project I first saw this template on, so unfortunately I can't give credit where it's due, suffice to say I didn't invent it and am not claiming credit for it.

Answer these three very simple questions:

  • What did you do?
  • What did you expect to happen?
  • What happened instead?

Just by answering these three questions, you're already doing better than most bug reports out there.

If you encounter an error, any kind of error, make sure to include a stack trace. Those are immensely useful. Also be sure that the stack trace is complete, some frameworks such as Rails or test frameworks like RSpec and Cucumber tend to filter the stack trace. In RSpec and Cucumber, run your tests with -b to get a full stack trace. If you can't get a stack trace, make sure to expand upon the third question as much as possible.

A bug report isn't a question

If you're asking why something broke, if you're wondering what the cause of a particular behaviour is, you aren't actually writing a bug report, you're asking a question.

Asking questions is good, and I encourage you to reach out when you need help and have exhausted all other options. Asking questions on an issue tracker however is bad. Issues need to be closed, they need to be resolved; a question cannot really be resolved. It can be answered, but then that answer needs to be acknowledged and accepted and so on. There is a lot of process involved in closing each issue and it takes time away from the maintainers to focus on more important things.

Most open source project have a mailing list, use that for asking questions. If there isn't one, use StackOverflow or a more generic mailing list. If you've posted to one of these and you didn't get an answer in two weeks or so, investigate again and see if you can't find the answer yourself. If you can find it, make sure to answer your own question in the forum you asked it, so that others who have the same question in the future may find your answer through the almighty Google. If all of that's failed, that's when you're allowed to open an issue for a question.

When you send a bug report, you should be able to at least speculate at what the cause might be. Saying feature X broke doesn't help at all. Most open source projects of decent size are used by thousands of people, they have massive, comprehensive test suites. The most basic functionality in the project very likely isn't broken. So even if you have a legitimate issue, it likely happened under a specific set of circumstances. You need to pare away possible causes until you are left with the most minimal set of conditions needed to replicate the issue. Which brings us to:

Replication

While it isn't strictly necessary for a bug report, it's immensely helpful to have some way to replicate the issue. It's especially helpful to have an executable way of replicating an issue.

I generally dislike sample applications, such as Rails applications for this. There are too many possible areas where breakage could occur, and it takes too long for me to understand how all the pieces fit together. If you need a complete sample application, you likely don't understand the issue well enough yet to send a good bug report. Pare it down further until you truly understand what components cause the problem.

The absolute best way is of course to send a failing test case. You definitely don't need to actually fix the problem, though of course we appreciate it if you do. Understanding a code base can be troublesome, so it's cool if you don't want to spend the time to understand how best to resolve an issue. But if you do spend the time to write a test case, you reduce the time it takes the maintainers to solve your problem by an order of magnitude. Seriously.

A well formatted email

If you're sending a message to a mailing list, be aware that reading code or stack traces inline in an email message is quite painful. Either keep the code samples very short or link to a pastie/gist or something. Reading long code samples without syntax highlighting and possibly with automatically wrapped lines is quite painful.

Debugging

Debugging is a central part of software development. You cannot get by as a programmer without being good at debugging. Use the skills you use to solve problems in your applications when you encounter what you perceive as bugs in open source projects. Debugging really is a simple process:

  1. Isolate the cause
  2. Fix it

Where 99.8%¹ of the time is spent on point 1. If you don't do the first point, you are effectively asking someone else to do most of your work for you. For free.

Be polite

The people who write open-source projects do not owe you anything. They've invested a lot of time, which you get for free, but they are under no obligation to keep providing that time to you, or to provide more of their time just because you demand it.

The most common form of this I see are the emails I get to my personal email account from people asking for help. Asking me for help in a private forum such as email is asking for a handout. It's a form of begging. Please don't do it. I hate getting these emails, and I hate having to reply that I don't answer questions sent to me privately.

Some people believe that instead, you owe authors for the software they provide, but I don't really believe that either. I think the only thing you do owe them is to treat them with the same respect and politeness that you would extend to anyone else.

So no one owes each other anything really, and that's cool.

Don't be disappointed by the way, if it takes a while for your issue to get a response. It's cool if you ping the author after a couple of weeks if nothing has happened. Sometimes one can lose motivation, or become engrossed in something else.

Summary

Be polite. Be explicit. Be as knowledgeable about the causes of your issue as you can be. Answer these following questions:

  • What did you do?
  • What did you expect to happen?
  • What happened instead?

¹ totally made up number