Saturday, March 29, 2014

Using Browser-Sync with Yeoman Webapp

Using Browser-Sync with Yeoman Webapp

Anyone with a multi-device testing suite will know the pain of testing forms or simply navigating through a site one browser at a time. Enter grunt-browser-sync, a GruntJS task that handles things like:

  • Links: Clicking a link will update all browsers with the new URL
  • Scrolling: Scroll in one browser or device and watch as the rest follow your command
  • Forms: Enter text in to one form and, yup, all other device browsers follow suit!

Hooking it up

Here's how to get Browser Sync up and running with Yeoman's webapp generator. I assume you know how to get the basic webapp up and running, so I'll skip that part. If not, follow the awesome documentation at Yeoman.io.

First, let's install grunt-browser-sync:

$ npm install grunt-browser-sync --save-dev

Edit Gruntfile.js

Next we'll edit the Gruntfile.js that came with webapp. There are only two edits required to make this happen. The first is to add the browser_sync task options:

browser_sync: {
 files: {
  src : [
   '<%= yeoman.app %>/*.html',
   '.tmp/styles/{,*/}*.css',
   '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
   '<%= yeoman.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
  ],
 },
 options: {
  watchTask: true,
  ghostMode: {
   scroll: true,
   links: true,
   forms: true
  },
  server: {
   baseDir: '<%= yeoman.app %>'
  }
 }
}

This config is setup to watch all files that may change in the app, which is just a copy-paste from the livereload section. We've also set the 'watchTask' option to true in order for Browser Sync to work with the grunt-watch task, enabled ghost mode for scrolling, linking, etc, and have set the root directory to our app directory. Check the Browser Sync README for more options.

Add the Task

The last step is to add the task itself. The documentation instructs to place the browser_sync task before the watch task:

grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
        return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
        'clean:server',
        'concurrent:server',
        'autoprefixer',
        'connect:livereload',
        'browser_sync',
        'watch'
    ]);
});

First Boot

You should be able to fire up `grunt server` from here. Point all your devices to the URL Browser Sync has automagically figured out is your local URL and watch as pure magic happens right before your eyes.

View the full Gruntfile.js

Notes

One thing I found out about the form sync feature is each field needs to have an ID attribute. Of course you have that already for all your accessible form labels, right?

Writing Accessible "Read More" Links

Writing Accessible "Read More" Links

Have you ever come across a link that simply read, 'here', or 'read more'? While these are usually fine for sighted and/or mouse users, AT users may run in to trouble. These links, while using a screen reader, provide little to no context. What is being linked to is a complete mystery.
Here are a few tips to write better, more accessible 'read more' links:

Add Some Context

Try to avoid doing this:
<a href="#">Read more</a>
Do this instead:
<a href="#">Read more <span class="visuallyhidden">about cute, cuddly kittens.</span></a>
The visuallyhidden class you see here is from the HTML5 Boilerplate CSS. With this class applied content will be hidden from sighted users yet will remain accessible by screen readers. With this in place, a screen reader would announce, "Read more about cute, cuddly kittens." Context!

Use Proper Sentence Structure

It's important to use full sentence structure for content that will be read aloud by screen readers. This helps users hear and understand content in a natural sounding manner, ie., someone pausing to take a breath after a sentence. This counts for all visually hidden content, including alt text.
<img src="kitten.jpg" alt="A cute, cuddly kitten getting ready for a nap."/>
A cute, cuddly kitten getting ready for a nap.

Avoid Symbols in Content

Sometimes a design might have an arrow or visual symbol to help users understand that this is a clickable link. In these cases, avoid the temptation of quickly adding the entity within the content:
<a href="#">Read more →</a>
This is not ideal as screen readers will read aloud, "Read more right arrow". Instead, add a class to the link and use the pseudo class ::after to apply the arrow:
<a href="#" class="read-more-link">Read more <span class="visuallyhidden">about cuter, even more cuddlier kittens!</span></a>
And in the CSS:
.read-more-link:after {
    content: "\2192";
}
With this is place, the generated content will match the design and screen readers will be able to give full context, giving confidence to the user.