Remake of an Expending Bar Menus app with AngularJS

Hello! I’ve created a remake of the “Expanding Bar Menus” application (another interesting experiment from Codrops which gives the feeling of a single page application despite being static).

I’ve transplanted AngularJS features into any areas where it makes obvious sense for a Single Page Application:

  1. Added real views instead of static content
  2. Deep linked views with routes

The result is flawless and worth trying! Please use the link below to get your hands on the code and let me know what you think.

 

Download Source

 

Acknowledgements

This application had been originally created by the engineers at Codrops. I’ve only made AngularJS fit in. So, many thanks to the Codrops team who is a major driving force in front-end innovation (image credit: Codrops).

How to transform a sidebar into an accordion!

Introduction:

I love front-end engineering, especially when the solution (which is not obvious) requires some sort of cross-disciplinary expertise.

I recently stumbled upon the following challenge: Turning a sidebar into an accordion on small screens and restore its original state on large screens. Sounds exciting? Watch the video below and read on.

 

 

First, let’s visualise the end result:

What is expected of us? What will the final result look like?

  • On a large viewport: the sidebar should be normally displayed with all its content
  • On a small viewport: the sidebar becomes an accordion which is initially closed (obviously to save some space); the user will have to manually expand it to consume the content
  • If the viewport’s width changes from small to large: the accordion should be deactivated and restored back to the sidebar’s initial state

 

Then, let’s consider the development environment and technologies used:

I believe any viable engineering solution should first consider the development environment, so let’s list the technologies used while specifying their importance:

  1. Twitter Bootstrap: for its excellent accordion plugin and famous grid system
  2. AngularJS directive: which will encapsulate all the logic and attach it as a behaviour to the sidebar
  3. Window matchMedia: for handling a specific breakpoint within the JavaScript code

The use of CSS in this case study is negligible (just a simple class to hide content).

 

Our methodology for solving the problem:

The methodology I’ve developed over years of experience is the following:

  1. Don’t force anything (unless there is no other way)
  2. Avoid reinventing the wheel (has this somehow been done before?)
  3. Craft your solution around powerful leverages (there must be something out there that can make your job easier and faster)

That being said, here is how we will …

Avoid reinventing the wheel:

  1. Turning our sidebar into an accordion: we’ll use Twitter Bootstrap’s collapse plugin (no need to engineer an accordion)
  2. Watching for a specific breakpoint on the JavaScript side: We’ll use matchMedia function (no need to constantly track the slightest change of the viewport’s width)

Craft our solution around powerful leverages:

We will encapsulate our logic inside an AngularJS directive that we’ll use as a decorator to attach the desired behaviour to our sidebar. Here are the basic steps of the solution (found as methods inside the directive)

  1. Handling the breakpoint change: We’ll track a specific breakpoint (using matchMedia). Each time that point is reached, we’ll turn the sidebar into an accordion or vice versa
  2. Deactivate or activate the accordion: The accordion will only operate on small screens, so we need to manually turn it off when necessary
  3. Expand the accordion: When returning the accordion back to a sidebar, we must make sure it isn’t collapsed, so we need a way to manually expand it
  4. Collapse the accordion: The accordion must be initially collapsed, so we need a manual way to do it

And we’re done! After putting everything together, things should work perfectly like in this special pen; the full code can be found in our CodePen profile.

 

In conclusion:

We’ve just seen how to solve the engineering problem of turning a sidebar into an accordion on small screens and vice versa. We based our approach on the following paradigms:

  • Clearly stating the problem
  • Identifying the solution’s great steps
  • Leveraging solid and powerful preexisting components

I hope this article had been insightful. Don’t hesitate to share your thoughts with me, I’ll be glad to answer. Thank you!

 

Resources:

 

Making off-screen content accessible

Introduction:

An off-screen content is a content that isn’t currently displayed, yet still needs to be in the DOM (modal-windowdrawer panel, …). This type of UI pattern presents an interesting challenge for accessibility because of the tab order and assistive technology‘s content linearization (more on this bellow). Today, I would like to explore a possible solution for making our off-screen contents accessible to keyboard users and other assistive technology.

 

Drawer panel menu, example of an off-screen content.
The drawer panel is a good example of off-screen content. Initially hidden to user while still being present in the DOM, it is only revealled to users in response of an event (Image from https://tympanus.net/codrops/2013/08/13/multi-level-push-menu/)

 

A word on content linearization:

The web page is browsed in a linear manner by devices like screen readers or keyboards, this means that elements are presented one at the time. So an off-screen content present on the DOM which is not visible to sighted users but not properly hidden to assistive technology might disrupt the reading flow of users who depend on these technologies (please refer to Web AIM section on content Linearization).

 

For a proper accessible experience, “the state of an off-screen content in the DOM should constantly mirror the page visual appearance”. (Make sure an element hidden to sighted users is also hidden at DOM level)

 

Experiencing non-accessible off-screen content from keyboard users perspective and finding a solution!

The experience:

Supposing a modal window isn’t properly hidden and receive focus when being off-screen. Users can be under the impression that the focus is disappearing and reappearing as they tab through the page — this is clearly an undesirable effect.

Ideally, while engineering the experience, developers should prevent the modal window from gaining focus when off-screen, and only allow it to be focused when the user can interact with it.

The solution:

During development, it is important to tab through the site to make sure the tab order doesn’t disappear or jump out of a logical sequence. If this is the case, developers should ensure that off-screen contents are properly hidden by using display:none" or visibility:hidden", and then set it back to “display:block" or “visibility:visible" before showing it to the user (This technique is implemented on this website’s drawer-panel menu).

 

As a rule, try tabbing through your pages every so often just to make sure you haven’t accidentally messed up the tab order. It’s a good habit to adopt, and one that doesn’t require much effort.

– developers.google.com –

 

Conclusion:

An off-screen content is a great way to dynamically reveal information on the page. But to avoid disturbing assistive technologies processing flow, off-screen contents must be properly hidden and revealed using CSS “display” and “visibility” properties.

Do you have experience with making an off-screen content accessible or are you struggling with one? Please share your thoughts with us. Thank you.

 

Resources:

 

 

Good usage of Keyboard traps: Example with off-screen components

Introduction:

Concentrating the user’s focus on a tiny section of the page can be a challenging task, especially when such an endeavor deteriorates the experience. The “keyboard trap” is generally seen as a UI bug where “the keyboard focus is being locked on a component for no apparent reasons” (refer to W3C article on keyboard trap), this an undesirable situation.

The “keyboard trap” can be seen in a better light if we look at some of the accessibility issues it solves. For example, a screen overlay prevents mouse users from accessing everything beside the content placed on focus, but keyboard users still have full access to anything on the page. In order to emulate the overlay effect for keyboard users, we can use the “keyboard trap”. In the following lines, I’ll show you how. In the meantime, see the keyboard trap in action.

 

 

What works for mouse users, doesn’t necessarily works for other users:

Consider a modal window. Because of an overlay that stands between the page content and the modal, mouse users have no access to anything on the page but to what’s inside the modal, not keyboard users. Looking at a drawer panel or any off-screen component, we see the same problem occurring: any HTML component that might isolate part of the layout for mouse users doesn’t do the same for keyboard users.

But we need the experience to be as consistent as possible for all users. Therefore, the “keyboard trap” will accomplish for keyboard users what the overlay is already doing for mouse users, which is keeping users focused on the modal content by forcing the keyboard focus to loop only on all focusable elements of that modal.

 

The “keyboard trap” can be used to “prevent keyboard users from moving the focus inatvertantly outside of a component!”

 

The implementation logic of the keyboard trap:

Whether the user opens a modal window or a drawer panel, the principle is the same: we have to make sure keyboard focus stays inside the active component.

Trapping the focus inside a component (modal window, drawer panel, …) can be simplified in the following steps:

  1. We get a reference to all focusable elements of the component (especially the first and the last)
  2. We use a “keydown listener” to track any key pressed especially the “tab”
  3. If “TAB” and “SHIFT” keys are pressed (tabbing backward)
    1. and the first focusable element is the one on focus, we move the focus to the last focusable element of the component (this creates a loop)
  4. If only “TAB” key is pressed (tabbing forward)
    1. and the last focusable element is the one on focus, we move the focus to the first focusable element of the component (this also creates a loop)

The full code on how to create a keyboard trap is available on Codepen.

 

Conclusion:

To preserve accessibility, it is imperative that we keep the same functionalities available to all users. In this case blocking access to anything but an off-screen content should be done not only to mouse users, but keyboard or other users as well. And we’ve just seen how the “keyboard trap” is a great solution for this.  Do you have experience with keyboard traps? Please share your thoughts with us.

Thank you.

 

Resources:

Web Accessibility – part 1 : Overview

Introduction:

Getting all users to fully experience the web without anyone being left out is on today’s front-end developer’s agenda. We then call “accessible” any web application which provides the same equivalent experience to a wide variety of users. In this article, we’ll discuss the following:

  • What is accessibility?
  • What are the different types of web impairment?
  • What’s make an application accessible?

If these questions appeal to your curiosity, then let’s proceed shall we?

 

Accessibility guarantees a seamless experience for a widest possible range of web users.

 

What is Accessibility?

Accessibility can be defined as the process of insuring that a product can be fully used and experienced in a similar fashion by the widest possible range of users.

Developers are often assuming that everyone else is experiencing the interface the same way they do, which leads them to create an experience that is only enjoyable by a small range of people, leaving the rest of the audience with issues (content not properly visible, understandable or audible). Therefore, accessibility adapts the experience to any user’s specific condition or situaton (it doesn’t matter whether users are in possession of all their faculties or have poor vision, bad hearing, etc …).

Accessibility goes beyond disability:

Accessibility integrate many elements of user experience, which minimize confusion and errors in people transactions on the web (for instance purchasing the wrong product because of the badly positioned call to action button). Accessibility therefore guarantees a seamless experience for a widest possible range of web users.

 

Accessibility incorporates User Experience

 

Example of accessibility and User Experience:

The following figure represents an inaccessible form. The issues are:

  • The username and price detail texts are low in contrast (hard for low vision readers to capture)
  • Labels and filters are each at the opposite side of the form (hard for people to associate them or to zoom into the page)
Form with accessibility issues (courtesy of https://udacity.com, web accessibility course)
Form with accessibility issues (courtesy of https://udacity.com, web accessibility course)

 

Now, here is the same form made more accessible by the following changes:

  • Low contrast text has been made darker (username and price detail texts)
  • The design has been modified to have label right next to their target (checking the label now affects the checkbox’s state)
Form optimized for accessibility (courtesy of https://udacity.com, web accessibility course)
Form optimized for accessibility (courtesy of https://udacity.com, web accessibility course)

 

Accessibility guarantees a seamless experience for a widest possible range of web users.

 

Understanding the diversity of  web impairments:

Impaired web usage is commonly associated with blindness, which is far from being accurate. In reality, there is four types of impairments on the web:

  • Visual : People with low visual acuity, poor color vision or suffering from concussion
  • Motor : People with a disabled arm or some other kind of dexterity impairment (they’ll probably use a special keyboard navigation, an eye tracking or voice dictation software)
  • Hearing : People who don’t or can’t listen. In this case, the content that uses a sound should provide some kind of visual alternative (a messenger app could be using a flashing alert as well as sound notification)
  • Cognitive : People suffering from concussion, ADD, dyslexia or autism (they’ll need to zoom in the content). A minimal design is well suited in this case because it will minimize distraction or cognitive load

It is also important to note that impairments are associated with temporalities, therefore a broken arm or concussion are considered as temporary impairments, blindness in considered a permanent impairment and being for example in a position where you can’t listen because of loud noise in your seroundings is considered as a situational impairment.

 

There is four types of impairments of the web: Visual, motor, hearing and cognitive.

 

Checklists: What makes an application accessible:

Accessibility is so broad and the user-ship is so diverse that a road map is needed in other to fully grasp it. The WCAG (Web Content Accessibility Guidelines) is a set of guidelines and best practices which had been put together by the experts to define accessibility in a methodical way.

WCAG is organized around four core principles:

  • Perceivable: Making sure users can perceive the content (sight, hearing or maybe touch)
  • Operable: Making sure users can use UI components and navigate the content (for instance avoiding to conceal crucial information in a hover effect because users using keyboards or screen readers might be deprived of it)
  • Understandable: Making sure users can understand the concept or the interface (Is the interface consistent enough to avoid confusion?)
  • Robust: Making sure the application is robust enough to be consumed by a wide variety of user agents and ensuring it works with assistive technology.

 

Conclusion:

Today, we looked into the definition of accessibility, we showed an example of inacessibility/accessibility, we looked at the diversity of impairments and we finished by looking into what makes an application accessible.

Do you have experience with accessibility? Please feel free to share your thoutghs with me.

Thank you.

 

resources:

Native JavaScript promises – part3 : Error Handling & Chaining

Error Handling:

Error handling can be done via the catch() method or as the second parameter of the then() method. Consider these equivalent chunks of code:

//Option 1  
getJSON('../data/file.json') //error happening here
.then(function(data){
  updateView(data);
  return get(data.thisUrl); //or error happening here
})
.catch(function(error){ //

 

In some cases, then() can be interpreted as a catch():

getJSON('../data/file.json')
//There is no resolve function here, only a rejection function
.then(undefined, rejectFunction)
//In the eventuality that the promise resolves, 
//the following then() that has a resolve function will be used
.then(resolveFunction);

 

In all cases, as soon as a promise rejects, the JavaScript engine skips to the next reject function in the chain:

//Option 1  
getJSON('../data/file.json') //error happening here
.then(function(data){
  updateView(data);
  return get(data.thisUrl); //or error happening here
})
.catch(function(error){ //

 

Important note on error handling:

It is strongly recommended to use catch() instead of then() when trying to handle errors for two reasons:

  1. Code readability: catch() are easy to spot in the code, using then() for both resolving and rejecting can be confusing
  2. Execution order: The resolve and rejection functions will never both be called if they are part of the same then() while they both can be called if the rejection function is part of a catch()

 

Performing asynchronous actions:  series vs parallel

Most asynchronous operations are not isolated, one request can lead to many others. In the case of multiple asynchronous actions, they all get performed in a chain (one promise generating another promise). The performance will then differ depending on wether actions are performed in series or in parallel.

/**
 * Chaining promises:
 * Two file requests must be performed because one resource leads to the other.
 * We assume: 
 * createThumbnail(data) receives an object, generates a thumbnail and place it on stage
 * get(url) : returns a promises (produced from fetch() of the fetch API)
 * getJSON(url) : performs an XHR for a JSON and returns a promise that passes the parsed JSON response
*/
//On page load: 
  getJSON('../data/file1.json')//Make the 1st request
  //If 1st request successful, return a promise of the 2nd request
  .then(function(resource){  
    return getJSON( resource.results[0]);
  })
  //Handling errors on the 1st request
  .catch(function(){
    throw Error('Search Request Error');
  })
  //If 2nd request is successful, create thumbnail
  .then(createThumbnail)
  //Handling errors on the 2nd request
  .catch(function(error){
    console.log('error = ', error); 
  });
//On page load: 

 

Actions in series:

Actions in series occur one after another, which means that the next resource is also fetched after the current one resolves.

/**
 * Situation where two file requests must be performed in order to 
 * get the information necessary to display a thumbnail on stage.
*/
getJSON('../data/file.json')//1st request
.then(function(response) {  
  //generate a promise object that will be reused to generate a sequential request
  let sequence  = Promise.resolve();
  //For each url in the array ...
  //chain a new promise that will be resolved only after the preceeding one 
  response.results.forEach(function(url){
    sequence.then(function(){
      return getJSON(url);
    })
    .then(createPlanetThumb)
    .catch(function(error){
      throw Error('Search Request Error = ', error);
    });
  }); 
});
//https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

 

Actions in parallel:

Actions in parallel all occur simultaneously, which means that resources are fetched and probably resolve at the same time.

Actions in parallel using Array.prototype.map():

Promises can be resolved in parallel using the map() method of the Array object like in the following example (resolve order is not guaranteed):

/**
 * We use the map() on an array of url resources and generate 
 * a promise for each url resource of the array
 * (We assume errors are handled)
*/
getJSON('../data/file.json')//1st request
.then(function(resourse){  
  resourse.results.map(function(url){ 
    getJSON(url).then(createPlanetThumb);
  });
});

 

Actions in parallel using Promise.all():

Promises can also be resolved in parallel using Promise.all() method which will simultaneously resolve all promises provided in an iterative argument (or reject them all only one of them rejects).

/**
 * We use the map() on an array of url resources and generate 
 * a promise for each url resource of the array
 * createThumbnail(data) : received an object, generates a thumbnail and place it on stage
 * getJSON(url) : performs an XHR for a JSON and returns a promise that passes the parsed JSON 
*/
getJSON('../data/file.json')//request the array of urls
.then(function(response) { 
  //returns a promise that resolves all promises promises generated in the array
  return Promise.all(response.results.map(getJSON)); 
})
.then(function(arrayOfResources){
  //create a thumbnail for each object in the array
  arrayOfResources.forEach(function(res){
    createPlanetThumb(res);
  });
})
.catch(function(error){
  console.log(error);
});

 

Conclusion:

Today, we looked into error handling, promises chaining and we finished by studying two ways of  performing multiple asynchronous operations (series and parallel).

This concludes our three parts studies on Native JavaScript Promises. Thank you.

 

Native JavaScript promises – part2 : Effective use

Syntax

A promise can be seen as a constructor that wraps a “try-catch” around the asynchronous code. Here is the syntax of a basic promise (more syntax variation on MDN):

/**
 * Basic promise syntax with 3 states: pending, success and failure
*/
new Promise(function(resolve){
   console.log('Still in process (pending)');
   resolve();
}).then(function(){
   console.log('Resolved (success)');
}).catch(function(){ 
   console.log('An error happened (failure)');
   //Dealing with the error here!
}); 

 

Use case: Acting on the page before it fully loads

A promise can be used to “spy” on the document and create an action at a specific moment. Suppose we want something done on the page before sub resources are loaded (images, stylesheets, …), we can create a promise that resolves only when the page reaches a precise loading state and then call and action when that promise resolves.

/** 
 * Create a promise that resolves only when the document 'ready state' 
 * is not on "loading" and call an action when that promise resolves
 * We assume: 
 * doSomethingOnTheDOM() updates the DOM with whatever feedback we choose
*/ 
//Wrap an event listener for readystatechange in a Promise.
function ready() { 
  return new Promise(function(resolve){
    function checkState (){
      //Only resolves if document is not 'loading'
      if(document.readyState !== 'loading'){
        resolve(); 
      }
    }
    //Check ready state when 'readystatechange' event fires
    document.addEventListener('readystatechange', checkState);
    checkState();//also checks ready state immidiately
  });
};//ready()

//Update the DOM only when the promise resolves. 
ready().then(doSomethingOnTheDOM);

 

Fetch API, a real game changer:

The Fetch API makes the process of fetching resources a breeze by providing an elegant interface that encapsulates native JavaScript Promises and handle results and callbacks (checkout also David Walsh article).

In the following example, we won’t worry about writing the XHR request, nor  parsing the resulting resource ourselves.

//Outpout something on the DOM
//Uses fetch (fetch API) to make and XHR request and return a promise
function get(url) {
  return fetch(url); //fetch assumes the method is 'get'
}

//Performs an XHR request and returns a parsed JSON response.
function getJSON(url) { 
  return get(url).then(function(response){
    //Returns a promise that resolves with a JSON object.
    return response.json();
  });
}

//When document is ready ...
  getJSON('../data/file.json')
  .then(function(response){
    doSomethinOnTheDOM(response);
    return response; //can be reused for chaining
  });
//When document is ready ...

 

Conclusion:

We’ve just seen a basic syntax of Native JavaScript Promises and looked at one possible use case where a promise is used to target a precise loading stage of the page. We’ve finally looked at a simple use of the Fetch API.

Next time, we’ll look at native JavaScript promises’ chaining and error handling.

 

Native JavaScript promises – part1 : The concept

Many applications today are relying on network requests, threads, events or some kind of process that has an uncertain outcome. These types of operations which are called asynchronous are unpredictable and error prone. Promises are the recommended option for dealing with asynchronous operations because they are flexible, intuitive and make error handling easy.

Our goal in this first post, will be to explore the concept of native JavaScript promises and understand their use in modern web development.

 

A Promise represents a value which may be available now, or in the future, or never. The Promise object is used for asynchronous computations. – MDN –

 

Synchronous and Asynchronous operations:

Synchronous Operations: sequencial executions

The JavaScript threading model is synchronous, which means that the code runs in a single and unbroken timeline (one statement executes immediately after another one).

/**
 * Example of a synchronous code: One statement is executed
 * before the next one gets executed (guaranteed)  
*/
let soccer_player = "Samuel Eto'o"; //first executed
console.log("Player name is : ", soccer_player); //second executed (Samuel Eto'o)

 

Asynchronous Operation: uncertainty of outcome

Unlike synchronous code, asynchronous code is not guaranteed to execute in a single timeline. It is best to assume that the completion time of such operation is unknown.

/**
 * Example of an asynchronous code: Two files are requested 
 * and there is no way to know if "file1" will return before 
 * "file2" or if even any of them will return at all. 
*/
let file1 = get('file1.json'); //file1 is first requested
let file2 = get('file2.json'); //file2 is requested next
//File aren't yet available
console.log(file1); //undefined
console.log(file2); //undefined

 

Not knowing when a request ends is a serious issue for the proper running of an application and this is where Promises come to the rescue.

 

The promise: easy handling of asynchronous operations

 Definition: 

A promise is a try-catch wrapper around the code that will finish at an unpredictable time. It allows the programmer to instruct the application about how to deal with something that is expected to happen in the future without knowing exactly when.

Different states of promise:

A promise has four states which represent the possible outcomes of an asynchronous operation. The developer can then use these states to deal with the outcomes:

  1. Fulfilled (resolved): The operation was successful
  2. Rejected: The operation failed
  3. Pending: The operation is still in process
  4. Settled: The operation is done (either succeeded or failed)

What can we use promise for?

  • To turn incoming external data (JSON) into useful information in an app
  • To work with information from ajax requests (ajax is an asynchronous request)
  • To work with threading applications like messaging systems
  • To control an application’s flow (doing something when all resources of the page aren’t completely loaded)

 

Conclusion:

We’ve just seen that operations in JavaScript are not always synchronous (instructions executed in order in appearance), but can also be asynchronous (instructions executed in the future with an unpredictable timeline and outcome).  We have seen that promises deal well with asynchronous operations by wrapping them with a “try and catch” that allows the developer to prepare for the operation’s possible outcomes: “success”, “failure”, “in process” and “completion”.

Next time, we’ll look at the syntax and use cases of native JavaScript promises.

 

Sticky Footer with FlexBox

Introduction:

When a page has very little content or is seen on a very large monitor, chances are there might be not enough content to push the footer all the way to the bottom. This creates an often unpleasant empty space below the footer. Today, I would like to share my idea about creating a sticky footer with Flexbox (and make good use of the “flex-grow” property).

 

The flex-grow property specifies how much the item will grow relative to the rest of the flexible items inside the same container (w3schools).

 

The thought process:

We usually have three major components on the page, the header, main content, and footer. The process can be broken down in the following steps:

  1. We wrap these components with a flex container that occupies the entire layout’s height (min-height to 100vh)
  2. We place the flex container‘s children in a column (flex-direction tocolumn”)
  3. And finally, we set the main content to fill the page’s empty space (flex-grow to 1)

The final step will make the main content’s height grow and push the footer to the bottom, thus getting rid of that bottom empty space.

Here is some code sample:

 

.page-wrapper{
  display: flex;
  flex-direction: column; //place direct children in a column
  min-height: 100vh; //fill the entire layout
}

.main-content{
  flex-grow: 1; //grow to fill the layout empty space relative to the other components
}

 

Conclusion:

This wraps up today’s article. We talked about one possible way of creating a sticky footer with Flexbox and outlined the main steps of such a technique. The complete code and  live version are available for your reference, feel free to share your impressions with me about this article or any work you had to do in the past with sticky footers.

Thank you.