Collective #516

Inspirational Website of the Week: PICTURESTART An amazing design with a very creative navigation and spot on typography. Our pick this week. Get inspired Subgrid Learn all about the new subgrid value of CSS Grid in this MDN guide. Read it Our Sponsor Divi: The Powerful Read more

Styling An Angular Application With Bootstrap

dreamt up by webguru in Uncategorized | Comments Off on Styling An Angular Application With Bootstrap

Styling An Angular Application With Bootstrap

Styling An Angular Application With Bootstrap

Ahmed Bouchefra



In case you’ve already tried building a web application with Angular 7, it’s time to kick it up a notch. Let’s see how we can integrate Bootstrap CSS styles and JavaScript files with an Angular project generated using the Angular CLI, and how to use form controls and classes to create beautiful forms and how to style HTML tables using Table styles.

For the Angular part, we’ll be creating a simple client-side application for creating and listing contacts. Each contact has an ID, name, email, and description, and we’ll be using a simple data service that stores the contacts in a TypeScript array. You can use an advanced in-memory API instead. (Check out “A Complete Guide To Routing In Angular”.)

Note: You can get the source code of this tutorial from this GitHub repository and see the live example over here.

Requirements

Before we start creating the demo application, let’s see the requirements needed for this tutorial.

Basically, you will need the following:

  • Node.js and NPM installed (you can simply head on over to the official website and download the binaries for your system),
  • Familiarity with TypeScript,
  • Working experience of Angular,
  • Basic knowledge of CSS and HTML.

Installing Angular CLI

Let’s start by installing the latest version of Angular CLI. In your terminal, run the following command:

$ npm install -g @angular/cli

At the time writing, v7.0.3 of Angular CLI is installed. If you have the CLI already installed, you can make sure you have the latest version by using this command:

$ ng --version

Creating A Project

Once you have Angular CLI installed, let’s use it to generate an Angular 7 project by running the following command:

$ ng new angular-bootstrap-demo

The CLI will then ask you:

Would you like to add Angular routing?

Press Y. Next, it will ask you:

Which stylesheet format would you like to use?

Choose “CSS”.

Adding Bootstrap

After creating the project, you need to install Bootstrap 4 and integrate it with your Angular project.

First, navigate inside your project’s root folder:

$ cd angular-bootstrap-demo

Next, install Bootstrap 4 and jQuery from npm:

$ npm install --save bootstrap jquery

(In this case, bootstrap v4.2.1 and jquery v3.3.1 are installed.)

Finally, open the angular.json file and add the file paths of Bootstrap CSS and JS files as well as jQuery to the styles and scripts arrays under the build target:

"architect": {
  "build": {
    [...], 
    "styles": [
      "src/styles.css", 
        "node_modules/bootstrap/dist/css/bootstrap.min.css"
      ],
      "scripts": [
        "node_modules/jquery/dist/jquery.min.js",
        "node_modules/bootstrap/dist/js/bootstrap.min.js"
      ]
    },

Check out how to add Bootstrap to an Angular 6 project for options on how to integrate Bootstrap with Angular.

Adding A Data Service

After creating a project and adding Bootstrap 4, we’ll create an Angular service that will be used to provide some demo data to display in our application.

In your terminal, run the following command to generate a service:

$ ng generate service data

This will create two src/app/data.service.spec.ts and src/app/data.service.ts files.

Open src/app/data.service.ts and replace its contents with the following:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  contacts = [
    {id: 1, name: "Contact 001", description: "Contact 001 des", email: "c001@email.com"},
    {id: 2, name: "Contact 002", description: "Contact 002 des", email: "c002@email.com"},
    {id: 3, name: "Contact 003", description: "Contact 003 des", email: "c003@email.com"},
    {id: 4, name: "Contact 004", description: "Contact 004 des", email: "c004@email.com"}
  ];

  constructor() { }

  public getContacts():Array{
    return this.contacts;
  }
  public createContact(contact: {id, name, description, email}){
    this.contacts.push(contact);
  }
}

We add a contacts array with some demo contacts, a getContacts() method which returns the contacts and a createContact() which append a new contact to the contacts array.

Adding Components

After creating the data service, next we need to create some components for our application. In your terminal, run:

$ ng generate component home
$ ng generate component contact-create
$ ng generate component contact-list

Next, we’ll add these components to the routing module to enable navigation in our application. Open the src/app/app-routing.module.ts file and replace its contents with the following:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ContactListComponent } from './contact-list/contact-list.component';
import { ContactCreateComponent } from './contact-create/contact-create.component';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  {path:  "", pathMatch:  "full",redirectTo:  "home"},
  {path: "home", component: HomeComponent},
  {path: "contact-create", component: ContactCreateComponent},
  {path: "contact-list", component: ContactListComponent}  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

We use the redirectTo property of the router’s path to redirect users to the home page when they visit our application.

Next, let’s create the header and footer components:

$ ng generate component header
$ ng generate component footer

Open the src/app/header/header.component.html file and add the following code:

<nav class="navbar navbar-expand-md bg-dark navbar-dark fixed-top">
  <a class="navbar-brand" href="#">Angular Bootstrap Demo</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse"
    aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  
</nav>

A navigation bar will be created with Bootstrap 4, and we’ll use the routerLink directive to link to different components.

Use the .navbar, .navbar-expand{-sm|-md|-lg|-xl} and .navbar-dark classes to create Bootstrap navigation bars. (For more information about nav bars, check out Bootstrap’s documentation on “Navbar”.

Next, open the src/app/header/header.component.css file and add:


.nav-item{
    padding:2px;
    margin-left: 7px;
}

Next, open the src/app/footer/footer.component.html file and add:

<footer>
  <p  class="text-xs-center">© Copyright 2019. All rights reserved.</p>
</footer>

Open the src/app/footer/footer.component.css file and add:


footer {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    padding: 1rem;
    text-align: center;
}

Next, open the src/app/app.component.html file and replace its contents with the following:

<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>

We’re creating an application shell by using the header and footer components which means that they will be present on every page of our application. The only part that will be changed is what will be inserted in the router outlet (check out “The Application Shell” on the Angular website for more information).

Adding A Bootstrap Jumbotron

According to the Bootstrap docs:

“A Jumbotron is a lightweight, flexible component that can optionally extend the entire viewport to showcase key marketing messages on your site.”

Let’s add a Jumbotron component to our home page. Open the src/app/home/home.component.html file and add:

Angular Bootstrap Demo

This demo shows how to integrate Bootstrap 4 with Angular 7

View tutorial

The .jumbotron class is used to create a Bootstrap Jumbotron.

Adding A List Component: Using A Bootstrap Table

Now let’s create a component-to-list data from the data service and use a Bootstrap 4 table to display tabular data.

First, open the src/app/contact-list/contact-list.component.ts file and inject the data service then call the getContacts() method to get data when the component is initialized:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-contact-list',
  templateUrl: './contact-list.component.html',
  styleUrls: ['./contact-list.component.css']
})
export class ContactListComponent implements OnInit {

  contacts;
  selectedContact;
  
  constructor(public dataService: DataService) { }

  ngOnInit() {
    this.contacts = this.dataService.getContacts();    
  }
  public selectContact(contact){
    this.selectedContact = contact;
  }
}

We added two variables contactsand selectedContact which hold the set of contacts and the selected contact. And a selectContact() method which assigns the selected contact to the selectedContact variable.

Open the src/app/contact-list/contact-list.component.html file and add:

# Name Email Actions
{{ contact.id }} {{ contact.name }} {{ contact.email }}
# {{selectedContact.id}}

{{selectedContact.name}}

{{selectedContact.description}}

</div> </div>

We simply loop through the contacts array and display each contact details and a button to select a contact. If the contact is selected, a Bootstrap 4 Card with more information will be displayed.

This is the definition of a Card from Bootstrap 4 docs:

“A card is a flexible and extensible content container. It includes options for headers and footers, a wide variety of content, contextual background colors, and powerful display options. If you’re familiar with Bootstrap 3, cards replace our old panels, wells, and thumbnails. Similar functionality to those components is available as modifier classes for cards.”

We use the .table and .table-hover classes to create Bootstrap-styled tables, the .card, .card-block, .card-title and .card-text classes to create cards. (For more information, check out Tables and Cards.)

Adding A Create Component: Using Bootstrap Form Controls And Classes

Let’s now add a form to our contact-create component. First, we need to import the FormsModule in our main application module. Open the src/app/app.module.ts file, import FormsModule from @angular/forms, and add it to the imports array:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { FormsModule } from '@angular/forms';

/* ... */

@NgModule({
  declarations: [
  /* ... */
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Next, open the src/app/contact-create/contact-create.component.ts file and replace its contents with the following:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-contact-create',
  templateUrl: './contact-create.component.html',
  styleUrls: ['./contact-create.component.css']
})
export class ContactCreateComponent implements OnInit {

  contact : {id, name, description, email} = {id: null, name: "", description: "", email: ""};
  
  constructor(public dataService: DataService) { }

  ngOnInit() {
  }
  
  createContact(){
    console.log(this.contact);
    this.dataService.createContact(this.contact);
    this.contact = {id: null, name: "", description: "", email: ""};

  }
}

Next, open the src/app/contact-create/contact-create.component.html file and add the following code:

Enter your contact’s ID Enter your contact’s name Enter your contact’s email Enter your contact’s description
</form> <button class="btn btn-primary" (click)="createContact()">Create contact</button> </div> </div> </div> </div>

We use the .form-group, .form-control classes to create a Bootstrap-styled form (check out “Forms” for more information).

We use the ngModel directive to bind the form fields to the components’ variable. For data binding to properly work, you need to give each form field a name.

Recommended reading: Managing Image Breakpoints With Angular by Tamas Piros

Running The Angular Application

At this step, let’s run the application and see if everything works as expected. Head over to your terminal, make sure you are in the root folder of your project then run the following command:

$ ng serve

A live-reload development server will be running from the http://localhost:4200 address. Open your web browser and navigate to that address. You should see the following interface:


Angular Bootstrap demo: Home page
(Large preview)

If you navigate to the Contacts page, you should see:


Angular Bootstrap Demo: Contacts Page
(Large preview)

If you navigate to the “Create contact” page, you should see:


Angular Bootstrap Demo: Create contact page
(Large preview)

Conclusion

In this tutorial, we’ve seen how to create a simple Angular application with a Bootstrap interface. You can find the complete source code on GitHub and see the live example here.

Smashing Editorial
(dm, il)

Source: Smashing Magazine, Styling An Angular Application With Bootstrap

Collective #493

dreamt up by webguru in Uncategorized | Comments Off on Collective #493



C493_leon

Leon

Leon is an open-source personal assistant who can live on your server.

Check it out












C493_meteorite

Meteorite

Like an assistant for your GitHub notifications, Meteorite helps you to focus on the most important issues and pull requests.

Check it out





C493_7

Get Ready for Priority Hints

Read about the new experimental feature known as Priority Hints now available through an Origin Trial in Chrome Beta which will allow you to tell the browser how resources should be prioritized.

Read it




C493_pong

Pong

Grégoire Divaret-Chauveau made a fun variation of Pong, where you are the ball.

Check it out



Collective #493 was written by Pedro Botelho and published on Codrops.


Source: Codrops, Collective #493

How A Screen Reader User Accesses The Web: A Smashing Video

dreamt up by webguru in Uncategorized | Comments Off on How A Screen Reader User Accesses The Web: A Smashing Video

How A Screen Reader User Accesses The Web: A Smashing Video

How A Screen Reader User Accesses The Web: A Smashing Video

Bruce Lawson



Two weeks ago, I had the pleasure of hosting a Smashing TV webinar with Léonie Watson on how a screen reader user accesses the web. In the talk, Léonie showed some big-name sites, such as BBC, sites nominated by Members (including my own!), Smashing Magazine itself, and the popular third-party service Typeform, because so many of us (including us at Smashing) just assume that the popular services have been checked for accessibility. Throughout, Léonie explained how the sites’ HTML was helping (or hindering) her use of the sites.

We felt that the webinar was so valuable that we would open it up so that it’s free for everybody to use. Hopefully, it will serve as a resource for the whole web development community to understand how — and why — semantic markup matters.

What We Learned

I was pleased that my personal site’s use of HTML5 landmark regions (main, nav, header, footer, etc) helped Léonie form a mental model of the structure of the page. Although I’ve always been scrupulous to avoid link text like “click here” because WCAG guidelines require “The purpose of each link can be determined from the link text alone”, it hadn’t occurred to me before that because I have hundreds of weekly “Reading List” articles, it’s impossible for a screen reader user to tell one from the other when navigating by headings. Since the webinar, I’ve made each new reading list’s heading unique by including its number in the heading (“Reading List 222”).

We also learned that being technically accessible is good, but even better is to be usably accessible. The Smashing Team learned that before Léonie can read her own article on our site, there’s loads of preamble (author bio, email sign-up form) that she can’t easily skip over. We’re correcting this at the moment. There’s also an issue with our quick summaries; Léonie gets no indication when the summary has finished and the article proper has begun. Sighted users get a dividing line, but what can we do for non-sighted users?

After the webinar, Léonie suggested using a semantic HTML element and a sprinkling of ARIA:

<section aria-label="Summary">
</section>

This is announced as “Summary region start” and “Summary region end”, and can be skipped over if desired.

Thank You!

We’d like to thank Léonie for giving the webinar, and also our magnificant Smashing Magazine members whose support allows us to commission such content, pay our contributors fairly, and reduce advertising on the site.

Shameless plug: if you enjoyed this webinar, why not consider becoming a Member yourself? There are around three webinars a month free, Smashing eBooks and discounts galore. It costs around two cups of coffee a month, and you can cancel anytime.

Smashing Editorial
(ra, il)

Source: Smashing Magazine, How A Screen Reader User Accesses The Web: A Smashing Video

Monthly Web Development Update 2/2019: Web Authentication And The Problem With UX

dreamt up by webguru in Uncategorized | Comments Off on Monthly Web Development Update 2/2019: Web Authentication And The Problem With UX

Monthly Web Development Update 2/2019: Web Authentication And The Problem With UX

Monthly Web Development Update 2/2019: Web Authentication And The Problem With UX

Anselm Hannemann



The only constant in life is change, they say. And it’s true, even if we think nothing changes at all. Whether you notice change or not is only a question of how you perceive and how you observe things. In the tech industry, it’s easy to see how fast things evolve — read a summary article like this one, and you’ll suddenly become aware of how much has happened in just one month. Since I took up meditation again, I gained a new perspective, and it helps me to deliberately appreciate such change and find personal value and gratefulness even in things that didn’t seem particularly positive at first.

Like this week, for example. I was reminded of a fact we usually forget: how the Internet is structured. If you browse the web, most traffic is directed through Amazon at some point, so if you block their servers, — or Google’s or Apple’s, or all of them —, there’s not much left of the Internet. I have used a Pi-Hole DNS blocker in my network for three years now, but never really appreciated it, until I learned about its real value this week — the security and privacy it provides considering our dependency on tech giants. Isn’t it remarkable how a big part of my perceived online security relies on one piece of open-source software that the authors spent so much time and efforts on to provide it for free in the end?

News

  • Firefox 65 was released. The new version dispatches events on disabled HTML elements and comes with support for the referrerpolicy attribute on script elements, CSS environment variables (the env() function), Intl.RelativeTimeFormat for JavaScript, and WebP images.
  • Safari Tech Preview 74 brings abortable fetch, support for U2F HID Authenticators on macOS, and new Web Authentication API features.
  • With Chrome 72, Chrome introduced the User Activation API. The new version also disallows popups on pageunload.
  • The Chrome 72 update for Android shipped the long-awaited Trusted Web Activity feature, which means we can now distribute PWAs in the Google Play Store.
  • Safari 12.1 release notes are up (iOS 12.2, macOS 10.14.4). What’s new? Dark mode for the web, intelligent tracking prevention, the push notification prompt for Safari on macOS now requires a user gesture, motion and orientation settings on iOS to enable DeviceMotionEvent and DeviceOrientationEvent (this means it’s disabled by default now). Also new are the Intersection Observer API, Web Share API, and the <datalist> element.

General

  • Max Böck shares his thoughts on why simplicity is the most valuable and important thing in projects.
  • Ian Littman on Twitter: “Moving 50% of servers to PHP 7 from PHP 5 would save $2.5 (edited to 2.0) billion in energy costs per year, and avoid billions of kilograms of CO2 emissions. Upgrade to PHP 7. Save the planet.”
  • How did you start to learn web development? I guess most of us relied on our browsers’ “view source” functionality and still do. But with JavaScript SPAs and more tooling that mangles, minifies and uglifies sources, we block this road of self-education for countless people out there. Let’s move to a more open approach and at least provide source maps on production servers so that people can access the actual sources via Developer Tools.

UI/UX


Sketch of a face with the terms see, say and do, hear, think and feel floating around it
To create stellar user experiences we need to see our users as humans. (Image credit)

HTML & SVG

  • Sara Soueidan wrote a 101 course on SVG filters to help you understand what they are and how to use them to create your own visual effects.

Accessibility

Privacy

  • Google is one of those companies which always find new, clever ways to expose user location data and sell it to third parties. Now Google wants to sell the exact location data of users to improve planning for urban planners, for example. Useful on the one hand, but still worrying for all users of Google products who might not be aware of what happens with their data.
  • I was wrong about Google and Facebook: there’s nothing wrong with them (so say we all),” says Aral Balkan. This piece explains how even the most honorable open-source projects struggle to make ethical choices and the fallacies of offering the best UX instead of promoting ethically correct solutions.

Web Performance

  • Jens Oliver Meiert shares his research on how the way you write HTML influences performance. Leaving out optional tags and quotes can make a difference, even though we’re able to use gzip or other techniques to optimize the document response in the browser.

JavaScript


Excerpt from the guide. It shows an illustration of a tiny woman who tries to prevent a giant wad of keys from tumbling over.
The Guide to Web Authentication is a handy introduction to securing sensitive information online. (Image credit)

CSS


Solar system built with CSS
Explore the solar system in Fabricius Seifert’s fantastic CSS experiment. (Image credit)

Work & Life

  • Paul Greenberg is in search of lost screen time and explores what our lives could look like and how much more time we’d have if we escaped the screens. There are some revealing numbers in the article: The average American spends $14,000 per decade on smartphones. That’s $70,000 over the course of an average working life. More than 29% of Americans would rather give up sex for three months than give up their smartphone for a single week. Or you could plant 150 trees and buy half an acre of land for the amount of money you’d spent on your smartphone and apps per year.
  • Are you a patient person? Regardless of if you are or not, the experiment that Jason Fried wants to try is certainly a challenge: Try to pick the longest line at the supermarket, cancel Amazon Prime so that delivery takes longer, and take the chance to wait whenever possible. Embrace slowness.
  • In Praise of Extreme Moderation” shares an interesting perspective on why the culture of over-committing, over-working, and over-delivering in all areas of life isn’t healthy, and how we can shift towards a more moderate, calmer path.

Going Beyond…

  • It must be free.” On services we obviously don’t need but want to have. My essay about the importance of seeing value in the things we really need and why less is more.
  • How can we make our lives better? By maintaining essential relationships, avoiding technology, and embracing values instead of lifehacks, says Eric Barker.
  • Watch this talk of Greta Thunberg, a sixteen-year-old woman who tells all the well-known and influential people out there that she doesn’t care about money and why we need to view climate change from a perspective like hers — her life is in danger and no money will be able to save it. We need more people like her who aren’t led by corporate or financial rules.
Smashing Editorial
(cm)

Source: Smashing Magazine, Monthly Web Development Update 2/2019: Web Authentication And The Problem With UX

Collective #492

dreamt up by webguru in Uncategorized | Comments Off on Collective #492







C492_bluetoothex

Bluetooth Anywhere

The folks at de Voorhoede made some experiments to see if it’s possible to control a device over Bluetooth, from a JavaScript app, on iOS and Android.

Read it







C492_instantpage

instant.page

Instant.page preloads a page right before a user clicks on it and thereby helps to make a page feel more “instant”.

Check it out


C492_Ludwig

Ludwig

Ludwig is a toolbox by Uber that allows to train and test deep learning models without the need to write code.

Check it out








C492_uppy

Uppy

In case you missed it: Uppy is a sleek, modular JavaScript file uploader that integrates seamlessly with any application.

Check it out




Collective #492 was written by Pedro Botelho and published on Codrops.


Source: Codrops, Collective #492

Managing Image Breakpoints With Angular

dreamt up by webguru in Uncategorized | Comments Off on Managing Image Breakpoints With Angular

Managing Image Breakpoints With Angular

Managing Image Breakpoints With Angular

Tamas Piros



As web developers, we are often required to create applications that are responsive as well as media-rich. Having such requirements in place means that we need to work with image breakpoints, as well as media queries since we want to provide the best experience to the end users. Adding to the list of requirements we may need to use a front-end framework such as Angular which is great for creating SPAs and other application types.

In this article, we’ll take a look at image breakpoints, their use-cases and throughout a hands-on example; we’ll implement them in an Angular application using Angular’s own BreakPoint Observer. While using this approach, we’ll also highlight why this popular framework helps us work with the aforementioned techniques in a seamless way.

Image Breakpoints And Responsive Images

In the era of responsive layouts (where we capture breakpoints based on the viewport size and based on the breakpoint we change the layout of the page), we also need to make sure that images can be displayed with the right dimensions — even after a layout change. Selecting the right image is quite challenging for modern responsive websites.

Let’s discuss two options that developers can utilize at the moment.

srcset

srcset lets us define a list of images that the browser switches between based on the rendered <img> size and the density of the display.

Let’s take a look at an example:

<img
  srcset="tuscany-sm.jpg 600w, tuscany-md.jpg 900w, tuscany-lg.jpg 1440w" sizes="100vw"
  src="tuscany.jpg" />

In the above, we specify 3 images, with the w indicating the pixel width for the image. When using the above with srcset we also need to specify the sizes attribute (this is required because the spec mandates that if we use srcset and w we must have a sizes attribute as well). What is the purpose of this attribute? Browsers need to pick which resource to load out of a source set before they layout the page (before they know how big the image will end up being). We can think of sizes as a hint to the browser that, after layout, the image will occupy 100% of the width of the viewport (that’s what vw refers to). The browser knows the actual viewport width (as well as the DPR of the image) at load-time, so it can do the math to figure out what size resource it needs and pick one out of the source set.

The <picture> and <source media=""> element combinations let us switch out image resources in response to media queries, like the ones at layout breakpoints.

Let’s take a look at an example of this as well:

<picture>
    <source media="(min-width: 1440px)" srcset="../assets/images/tuscany-lg.jpg">
    <source media="(min-width: 900px)" srcset="../assets/images/tuscany-md.jpg">
    <source media="(min-width: 600px)" srcset="../assets/images/tuscany-sm.jpg">
    <img src="../assets/images/tuscany-sm.jpg" />
  </picture>

Change the code above locally with an image of your choice that has a small, medium and large size. Notice how, by resizing the browser, you get a different image.

The key takeaway from all the above is that if we want to swap out images at specific breakpoints, we can use the <picture> element to put media queries right into the markup.

Note: If you’re interested in exploring the differences between <picture> and srcset + sizes, I recommend reading Eric Portis’ great article: srcset and sizes.

So far we have discussed how to use image breakpoints along with media queries in a pure HTML environment. Wouldn’t it be a lot better to have a convenient, almost semi-automated way of generating image breakpoints as well as the corresponding images for the breakpoints even without having to specify media queries at all? Luckily for us Angular has a built-in mechanism to help us out and we’ll also take a look at generating the appropriate images dynamically based on certain conditions by using a third-party service.

Angular Layout Module

Angular comes with a Layout Module which lives in the CDK (Component Dev Kit) toolset. The Angular CDK contains well-tested tools to aid with component development. One part of the CDK is the Layout Module which contains a BreakpointObserver. This helper gives access to media-query breakpoints, meaning that components (and their contents) can adapt to changes when the browser size (screen size) is changed intuitively.

Recommended reading: Layout Module

Now that we have the theory out of the way let’s get down to business and create an application that will implement responsive image breakpoints. In this first iteration, we’ll create the shell of the application via the Angular CLI: ng new bpo and select the necessary options.

To use the BreakpointObserver we also need to install the Angular’s CDK Layout Module, which we can do via npm: npm i @angular/cdk.

After the installation, we will be able to add the necessary import statements to any component that we wish:

// app.component.ts
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';

Using the BreakpointObserver we can subscribe to changes in the viewport width and Angular gives us convenient accessors which mean that we don’t need to use media queries at all! Let’s go ahead and try this out:

// app.component.ts
constructor(public breakpointObserver: BreakpointObserver) { }

ngOnInit() {
    this.breakpointObserver.observe([
      Breakpoints.XSmall,
      Breakpoints.Small,
      Breakpoints.Medium,
      Breakpoints.Large,
      Breakpoints.XLarge
    ]).subscribe(result => {
      if (result.breakpoints[Breakpoints.XSmall]) {
       // handle XSmall breakpoint
      }
      if (result.breakpoints[Breakpoints.Small]) {
       // handle Small breakpoint
      }
      if (result.breakpoints[Breakpoints.Medium]) {
      // handle Medium breakpoint
      }
      if (result.breakpoints[Breakpoints.Large]) {
        // handle Large breakpoint
      }
      if (result.breakpoints[Breakpoints.XLarge]) {
        // handle XLarge breakpoint
      }
    });
  }

As mentioned before the accessor properties above reflect media queries in the following way:

  • Breakpoints.XSmall: max-width = 599.99px
  • Breakpoints.Small: min-width = 600px and max-width = 959.99px
  • Breakpoints.Medium: min-width = 960px and max-width = 1279.99px
  • Breakpoints.Large: min-width = 1280px and max-width = 1919.99px
  • Breakpoints.XLarge: min-width = 1920px

We now have everything in place which means, we can start to generate the appropriate images.

Responsive Breakpoints For Images

We have a few options to generate responsive images:

  1. Responsive Image Breakpoints Generator
    Using this tool, we can upload any image, setup various options, e.g. the number of images that we wish to generate. After running the tool, we’ll have a visual representation about the generated images, and we can download them as a zip file along with some generated code which uses the previously mentioned <picture> element.
  2. Another solution would be to create a build step for our project to generate breakpoints via some packages available in the NPM repository, such as gulp-responsive or grunt-responsive-images. Both of these depend on additional libraries that we are required to install for our operating system. (Please check the appropriate repositories for additional information.)
  3. Yet another solution would be to use a service such as Cloudinary to store the images and serve them in a size and format that we need only by modifying the URL for the requested resource. This will be our approach since this gives us the most flexibility.

Recommended reading: Automating Art Direction With The Responsive Image Breakpoints Generator by Eric Portis

I have uploaded the original image to my Cloudinary account which means that I can access that image via the following URL:

https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg

This is the full-sized, raw, original and unchanged image that we’ll work with.

We can modify the URL of the image to generate a much smaller version. For example, if we want to have an image with a width of 600 pixels, we could update the Cloudinary URL* to be the following:

https://res.cloudinary.com/tamas-demo/image/upload/w_600/breakpoints-article/tuscany.jpg
 

* Note the w_600 added to the URL.

Hopefully, by this point, you see where all this is going. Based on the approach above, we can very quickly start to generate the right image for the right breakpoint.

Using Cloudinary means that we don’t need to create, store and manage multiple version of the same image — it is done for us by Cloudinary on-the-fly.

Let’s update our code:

<!-- app.component.html -->

Current breakpoint: {{ breakpoint }}

// app.component.ts
import { Component, OnInit } from '@angular/core';
// ...
export class AppComponent implements OnInit {
  imagePath;
  constructor(public breakpointObserver: BreakpointObserver) { }
  ngOnInit() {
    this.breakpointObserver.observe([ ...
  }
}

We can pick any number of breakpoints to observe from the list mentioned previously, and since we have an Observer we can subscribe to the changes and act on them:

this.breakpointObserver.observe([
  Breakpoints.XSmall,
  Breakpoints.Small,
  Breakpoints.Medium,
  Breakpoints.Large,
  Breakpoints.XLarge
]).subscribe(result => {
  if (result.breakpoints[Breakpoints.XSmall]) {
    // handle this case
  }
});

To handle the options for the different images in Cloudinary, we’ll utilize an approach that will be very easy to follow. For each case, we’ll create an options variable and update the final Cloudinary URL.

Add the following at the top of the component definition:

// app.component.ts
imagePath;
  breakpoint;
  cloudinaryOptions;
  baseURL = 'https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg';

And add the following as well to the first if statement:

// app.component.ts
let url = this.baseURL.split('/');
let insertIndex = url.indexOf('upload');
const options = 'c_thumb,g_auto,f_auto,q_auto,w_400';
url.splice(insertIndex + 1, 0, options);
this.imagePath = url.join('/');
this.breakpoint = Breakpoints.XSmall;

The result is going to be an updated Cloudinary URL:

https://res.cloudinary.com/tamas-demo/image/upload/c_thumb,g_auto,f_auto,q_auto,w_400/breakpoints-article/tuscany.jpg

What are the options that we are setting here?

  • c_thumb (generates a thumbnail of the image);
  • g_auto (focuses on the most interesting part; we see the cathedral in the thumbnail);
  • f_auto (serves the most appropriate format for a given browser, i.e. WebP for Chrome);
  • q_auto (reduces the quality — and therefore the overall size — of the image without impacting the visuals);
  • w_400 (sets the width of the image to 400px).

For the sake of curiosity, let’s compare the original image size with this newly generated image: 2.28 MBs vs 29.08 KBs!

We now have a straightforward job: we need to create different options for different breakpoints. I created a sample application on StackBlitz so you can test it out immediately (you can also see a preview here).

Conclusion

The variety of desktop and mobile devices and the amount of media used in today’s web has reached an outstanding number. As web developers, we must be at the forefront of creating web applications that work on any device and doesn’t impact the visual experience.

There are a good number of methods that make sure the right image is loaded to the right device (or even when resizing a device). In this article, we reviewed an approach that utilizes a built-in Angular feature called BreakPoint Observer which gives us a powerful interface for dealing with responsive images. Furthermore, we also had a look at a service that allows us to serve, transform and manage images in the cloud. Having such compelling tools at our hands, we can still create immersive visual web experiences, without losing visitors.

Smashing Editorial
(dm, il)

Source: Smashing Magazine, Managing Image Breakpoints With Angular

An Introduction To WebBluetooth

dreamt up by webguru in Uncategorized | Comments Off on An Introduction To WebBluetooth

An Introduction To WebBluetooth

An Introduction To WebBluetooth

Niels Leenheer



With Progressive Web Apps, the web has been ever more closely moving towards native apps. However, with the added benefits that are inherent to the web such as privacy and cross-platform compatibility.

The web has traditionally been fantastic about talking to servers on the network, and to servers on the Internet specifically. Now that the web is moving towards applications, we also need the same capabilities that native apps have.

The amount of new specifications and features that have been implemented in the last few years in browsers is staggering. We’ve got specifications for dealing with 3D such as WebGL and the upcoming WebGPU. We can stream and generate audio, watch videos and use the webcam as an input device. We can also run code at almost native speeds using WebAssembly. Moreover, despite initially being a network-only medium, the web has moved towards offline support with service workers.

That is great and all, but one area has been almost the exclusive domain for native apps: communicating with devices. That is a problem we’ve been trying to solve for a long time, and it is something that everybody has probably encountered at one point. The web is excellent for talking to servers, but not for talking to devices. Think about, for example, trying to set up a router in your network. Chances are you had to enter an IP address and use a web interface over a plain HTTP connection without any security whatsoever. That is just a poor experience and bad security. On top of that, how do you know what the right IP address is?

HTTP is also the first problem we run into when we try to create a Progressive Web App that tries to talk to a device. PWAs are HTTPS only, and local devices are always just HTTP. You need a certificate for HTTPS, and in order to get a certificate, you need a publicly available server with a domain name (I’m talking about devices on our local network that is out of reach).

So for many devices, you need native apps to set the devices up and use them because native apps are not bound to the limitations of the web platform and can offer a pleasant experience for its users. However, I do not want to download a 500 MB app to do that. Maybe the device you have is already a few years old, and the app was never updated to run on your new phone. Perhaps you want to use a desktop or laptop computer, and the manufacturer only built a mobile app. Also not an ideal experience.

WebBluetooth is a new specification that has been implemented in Chrome and Samsung Internet that allows us to communicate directly to Bluetooth Low Energy devices from the browser. Progressive Web Apps in combination with WebBluetooth offer the security and convenience of a web application with the power to directly talk to devices.

Bluetooth has a pretty bad name due to limited range, bad audio quality, and pairing problems. But, pretty much all those problems are a thing of the past. Bluetooth Low Energy is a modern specification that has little to do with the old Bluetooth specifications, apart from using the same frequency spectrum. More than 10 million devices ship with Bluetooth support every single day. That includes computers and phones, but also a variety of devices like heart rate and glucose monitors, IoT devices like light bulbs and toys like remote controllable cars and drones.

Recommended reading: Understanding API-Based Platforms: A Guide For Product Managers

The Boring Theoretical Part

Since Bluetooth itself is not a web technology, it uses some vocabulary that may seem unfamiliar to us. So let’s go over how Bluetooth works and some of the terminology.

Every Bluetooth device is either a ‘Central device’ or a ‘Peripheral’. Only central devices can initiate communication and can only talk to peripherals. An example of a central device would be a computer or a mobile phone.

A peripheral cannot initiate communication and can only talk to a central device. Furthermore, a peripheral can only talk to one central device at the same time. A peripheral cannot talk to another peripheral.


a phone in the middle, talking to multiple peripherals, such as a drone, a robot toy, a heart rate monitor and a lightbulb
A central device can talk to multiple peripherals. (Large preview)

A central device can talk to multiple peripherals at the same time and could relay messages if it wanted to. So a heart rate monitor could not talk to your lightbulbs, however, you could write a program that runs on a central device that receives your heart rate and turns the lights red if the heart rate gets above a certain threshold.

When we talk about WebBluetooth, we are talking about a specific part of the Bluetooth specification called Generic Attribute Profile, which has the very obvious abbreviation GATT. (Apparently, GAP was already taken.)

In the context of GATT, we are no longer talking about central devices and peripherals, but clients and servers. Your light bulbs are servers. That may seem counter-intuitive, but it actually makes sense if you think about it. The light bulb offers a service, i.e. light. Just like when the browser connects to a server on the Internet, your phone or computer is a client that connects to the GATT server in the light bulb.

Each server offers one or more services. Some of those services are officially part of the standard, but you can also define your own. In the case of the heart rate monitor, there is an official service defined in the specification. In case of the light bulb, there is not, and pretty much every manufacturer tries to re-invent the wheel. Every service has one or more characteristics. Each characteristic has a value that can be read or written. For now, it would be best to think of it as an array of objects, with each object having properties that have values.


the hierarchy of services and characteristics compared to more familiar constructs from JavaScript - a server is similar to an array of objects, a service to an object in that array, a characteristic to a property of that object and both have values
A simplified hierarchy of services and characteristics. (Large preview)

Unlike properties of objects, the services and characteristics are not identified by a string. Each service and characteristic has a unique UUID which can be 16 or 128 bits long. Officially, the 16 bit UUID is reserved for official standards, but pretty much nobody follows that rule.
Finally, every value is an array of bytes. There are no fancy data types in Bluetooth.

A Closer Look At A Bluetooth Light Bulb

So let’s look at an actual Bluetooth device: a Mipow Playbulb Sphere. You can use an app like BLE Scanner, or nRF Connect to connect to the device and see all the services and characteristics. In this case, I am using the BLE Scanner app for iOS.

The first thing you see when you connect to the light bulb is a list of services. There are some standardized ones like the device information service and the battery service. But there are also some custom services. I am particularly interested in the service with the 16 bit UUID of 0xff0f. If you open this service, you can see a long list of characteristics. I have no idea what most of these characteristics do, as they are only identified by a UUID and because they are unfortunately a part of a custom service; they are not standardized, and the manufacturer did not provide any documentation.

The first characteristic with the UUID of 0xfffc seems particularly interesting. It has a value of four bytes. If we change the value of these bytes from 0x00000000 to 0x00ff0000, the light bulb turns red. Changing it to 0x0000ff00 turns the light bulb green, and 0x000000ff blue. These are RGB colors and correspond exactly to the hex colors we use in HTML and CSS.

What does that first byte do? Well, if we change the value to 0xff000000, the lightbulb turns white. The lightbulb contains four different LEDs, and by changing the value of each of the four bytes, we can create every single color we want.

The WebBluetooth API

It is fantastic that we can use a native app to change the color of a light bulb, but how do we do this from the browser? It turns out that with the knowledge about Bluetooth and GATT we just learned, this is relatively simple thanks to the WebBluetooth API. It only takes a couple of lines of JavaScript to change the color of a light bulb.

Let’s go over the WebBluetooth API.

Connecting To A Device

The first thing we need to do is to connect from the browser to the device. We call the function navigator.bluetooth.requestDevice() and provide the function with a configuration object. That object contains information about which device we want to use and which services should be available to our API.

In the following example, we are filtering on the name of the device, as we only want to see devices that contain the prefix PLAYBULB in the name. We are also specifying 0xff0f as a service we want to use. Since the requestDevice() function returns a promise, we can await the result.

let device = await navigator.bluetooth.requestDevice({
    filters: [ 
        { namePrefix: 'PLAYBULB' } 
    ],
    optionalServices: [ 0xff0f ]
});

When we call this function, a window pops up with the list of devices that conform to the filters we’ve specified. Now we have to select the device we want to connect to manually. That is an essential step for security and privacy and gives control to the user. The user decides whether the web app is allowed to connect, and of course, to which device it is allowed to connect. The web app cannot get a list of devices or connect without the user manually selecting a device.


the Chrome browser with the window that the user needs to use to connect to a device, with the lightbulb visible in the list of devices
The user has to manually connect by selecting a device. (Large preview)

After we get access to the device, we can connect to the GATT server by calling the connect() function on the gatt property of the device and await the result.

let server = await device.gatt.connect();

Once we have the server, we can call getPrimaryService() on the server with the UUID of the service we want to use as a parameter and await the result.

let service = await server.getPrimaryService(0xff0f);

Then call getCharacteristic() on the service with the UUID of the characteristic as a parameter and again await the result.

We now have our characteristics which we can use to write and read data:

let characteristic = await service.getCharacteristic(0xfffc);

Writing Data

To write data, we can call the function writeValue() on the characteristic with the value we want to write as an ArrayBuffer, which is a storage method for binary data. The reason we cannot use a regular array is that regular arrays can contain data of various types and can even have empty holes.

Since we cannot create or modify an ArrayBuffer directly, we are using a ‘typed array’ instead. Every element of a typed array is always the same type, and it does not have any holes. In our case, we are going to use a Uint8Array, which is unsigned so it cannot contain any negative numbers; an integer, so it cannot contain fractions; and it is 8 bits and can contain only values from 0 to 255. In other words: an array of bytes.

characteristic.writeValue(
    new Uint8Array([ 0, r, g, b  ])
);

We already know how this particular light bulb works. We have to provide four bytes, one for each LED. Each byte has a value between 0 and 255, and in this case, we only want to use the red, green and blue LEDs, so we leave the white LED off, by using the value 0.

Reading Data

To read the current color of the light bulb, we can use the readValue() function and await the result.

let value = await characteristic.readValue();
    
let r = value.getUint8(1); 
let g = value.getUint8(2);
let b = value.getUint8(3);

The value we get back is a DataView of an ArrayBuffer, and it offers a way to get the data out of the ArrayBuffer. In our case, we can use the getUint8() function with an index as a parameter to pull out the individual bytes from the array.

Getting Notified Of Changes

Finally, there is also a way to get notified when the value of a device changes. That isn’t really useful for a lightbulb, but for our heart rate monitor we have constantly changing values, and we don’t want to poll the current value manually every single second.

characteristic.addEventListener(
    'characteristicvaluechanged', e => {
        let r = e.target.value.getUint8(1); 
        let g = e.target.value.getUint8(2);
        let b = e.target.value.getUint8(3);
    }
);

characteristic.startNotifications();

To get a callback whenever a value changes, we have to call the addEventListener() function on the characteristic with the parameter characteristicvaluechanged and a callback function.
Whenever the value changes, the callback function will be called with an event object as a parameter, and we can get the data from the value property of the target of the event. And, finally extract the individual bytes again from the DataView of the ArrayBuffer.

Because the bandwidth on the Bluetooth network is limited, we have to manually start this notification mechanism by calling startNotifications() on the characteristic. Otherwise, the network is going to be flooded by unnecessary data. Furthermore, because these devices typically use a battery, every single byte that we do not have to send will definitively improve the battery life of the device because the internal radio does not need to be turned on as often.

Conclusion

We’ve now gone over 90% of the WebBluetooth API. With just a few function calls and sending 4 bytes, you can create a web app that controls the colors of your light bulbs. If you add a few more lines, you can even control a toy car or fly a drone. With more and more Bluetooth devices making their way on to the market, the possibilities are endless.

Further Resources

Smashing Editorial
(dm, ra, il)

Source: Smashing Magazine, An Introduction To WebBluetooth

Webhosting Compared: Testing The Uptime Of 32 Hosts In 2018

dreamt up by webguru in Uncategorized | Comments Off on Webhosting Compared: Testing The Uptime Of 32 Hosts In 2018

Webhosting Compared: Testing The Uptime Of 32 Hosts In 2018

Webhosting Compared: Testing The Uptime Of 32 Hosts In 2018

John Stevens



(This is a sponsored article.) Many surveys have indicated that uptime is number one factor when choosing a web host and although most, if not all, web hosting services “promise” 99.99% uptime, it’s not the case with our case-study.

According to our latest research, the average uptime of 32 shared web hosting providers is 99.59%. That’s approximately 35 hours 32 minutes of downtime per year, per website.

And downtime even happens to online giants. A Dun & Bradstreet study found that nearly 60 percent of Fortune 500 companies experience a minimum of 1.6 hours of downtime every week.

As a rule of thumb, if you are experiencing an uptime of 99.90% or below, you should switch your web host. A good web host should provide you with an uptime of at least 99.94%.

To run this series of tests, we have signed up for all of the 32 web hosting providers as a regular user, using the cheapest plan available. After that, we set up a basic WordPress website and start monitoring them with Pingdom.com. (Tools like Pingdom or Appoptics let you regularly check if a website or app is available.) Our uptime check interval was set to 1 minute, which means all of the sites are scanned every minute to get the most accurate statistics.

Please note that many hosts don’t define uptime like that, so they will often refuse to pay out on the guarantee because they say it was “planned maintenance” etc.

Let’s take a closer look.

Web Hosting Provider Average Uptime ↓ Total Outages Total Downtime Per Year
1. MidPhase 99.991% 19 outages 45 minutes
2. Bluehost 99.991% 7 outages 52 minutes
3. DigitalOcean* 99.989% 11 outages 58 minutes
4. SiteGround* 99.988% 26 outages 73 minutes
5. Site5* 99.986% 16 outages 83 minutes
6. HostGator* 99.984% 19 outages 84 minutes
7. A Small Orange* 99.978% 52 outages 125 minutes
8. iPage 99.975% 72 outages 131 minutes
9. HostPapa 99.975% 39 outages 144 minutes
10. FastComet 99.973% 44 outages 146 minutes
11. LunarPages* 99.972% 20 outages 153 minutes
12. Hostinger* 99.971% 28 outages 154 minutes
13. WebHostingBuzz 99.969% 28 outages 163 minutes
14. GreenGeeks* 99.969% 11 outages 164 minutes
15. JustHost 99.968% 28 outages 165 minutes
16. GoDaddy 99.965% 47 outages 184 minutes
17. HostRocket 99.960% 31 outages 202 minutes
18. HostMonster 99.955% 40 outages 235 minutes
19. DreamHost* 99.953% 40 outages 239 minutes
20. Hosting24 99.951% 31 outages 264 minutes
21. WestHost* 99.948% 48 outages 271 minutes
22. WebHostingHub 99.948% 76 outages 278 minutes
23. inMotion Hosting 99.935% 90 outages 341 minutes
24. A2 Hosting 99.928% 64 outages 375 minute
25. HostMetro 99.852% 247 outages 763 minutes
26. MDD Hosting* 99.833% 76 outages 874 minutes
27. FatCow 99.829% 377 outages 899 minutes
28. NameCheap* 99.826% 453 outages 917 minutes
29. HostNine 99.723% 241 outages 1448 minutes
30. One.com 99.593% 419 outages 2132 minutes
31. WebHostingPad 97.588% 1,655 outages 9 days
32. Arvixe* 91.098% 20,051 outages 1 month

* These web hosting providers offer an uptime guarantee. If they’ve failed on promised uptime, you can ask for your money back.

If you’re into each month overviews with more detailed data, take a look at these pages below:

1. MidPhase.com

MidPhase 2018 statistics
No uptime guarantee:

Although MidPhase doesn’t mention any uptime guarantee on their website, they are the clear winner of this case-study hitting nearly 100% uptime in 2018.

2. Bluehost.com

Bluehost 2018 statistics
No uptime guarantee:

Similarly to MidPhase, Bluehost doesn’t offer any uptime guarantees either (just a network/server uptime agreement). However, their servers have been working very steadily, with the exception of one bigger outage (42 minutes).

3. DigitalOcean.com

Digital Ocean 2018 statistics
Uptime guarantee available:

DigitalOcean is a cheap cloud hosting that promises 99.99% uptime which they have greatly succeeded in our test. If you see uptime less than 99.99% using DigitalOcean, you can ask your money back.

4. SiteGround.com

SiteGround 2018 statistics
Uptime guarantee available:

SiteGround is a hosting provider with an excellent uptime score. They also offer uptime guarantee, providing you with one month of free service if uptime falls below 99.99% and an additional month if uptime falls below 99.90%.

5. Site5.com

Site5 2018 statistics
Uptime guarantee available:

99.98% is still decent uptime. What’s even better – Site5 comes with an uptime guarantee of 99.9% – anything below that is eligible for a % of credit back. They even offer 100% credit back when uptime falls below 99.5% on their fully managed VPS

6. HostGator.com

HostGator 2018 statistics
Uptime guarantee available:

HostGator comes with a decent uptime. On top of that, they even provide an uptime guarantee of 99.9% and you get credit back when it falls below. Just beware that it only applies for the actual server downtime excluding server maintenance.

7. ASmallOrange.com

A Small Orange 2018 statistics
Uptime guarantee available:

ASmallOrange offers an uptime guarantee of 99.9%. When it’s below that, you get a refund of one day of service per every 45-min downtime. Beware of the specific clauses. Just note the high number of outages we experienced in the test period.

8. iPage.com

iPage 2018 statistics
No uptime guarantee:

iPage does not offer an uptime guarantee. Luckily, considering their ranking in overall uptime, we’re pretty sure you wouldn’t need it anyway. One thing to be aware of is the high number of outages we experienced.

9. HostPapa.com

HostPapa 2018 statistics
No uptime guarantee:

Even though they mention under their Terms of Service using “reasonable efforts to maintain 99.9% of uptime”, HostPapa does not exactly provide an uptime guarantee.

10. FastComet.com

Fastcomet 2018 statistics
No uptime guarantee:

Even though their live chat agent said that they guarantee a 99% uptime, there is no official uptime guarantee on FastComet’s Terms of Service or refund/credit policy if it falls below what’s promised. The total amount of outages is somewhat concerning.

11. LunarPages.com

LunarPages 2018 statistics
Uptime guarantee available:

For every 15min of downtime, LunarPages credits client’s account with an equal of a full day of service. That guarantee excludes scheduled maintenance.

12. Hostinger.com

Hostinger 2018 statistics
Uptime guarantee available:

Hostinger’s above average uptime is backed up by their uptime guarantee of 99.9%. As in all cases, scheduled maintenance is excluded.

13. WebHostingBuzz.com

WebHostingBuzz 2018 statistics
No uptime guarantee:

WHB does not provide any uptime guarantee per se. Based on our experience, you most likely wouldn’t need one anyway.

14. GreenGeeks.com

GreenGeeks 2018 statistics
Uptime guarantee available:

GreenGeeks offers a 99.9% uptime guarantee. However, it only applies to their own servers and is not applicable for client errors.

15. JustHost.com

JustHost 2018 statistics
No uptime guarantee:

There’s no uptime guarantee on their website, whatsoever.

16. GoDaddy.com

GoDaddy 2018 statistics
No uptime guarantee:

Despite their big name, huge client-base and decent service, GoDaddy does not provide any uptime guarantee. You should also beware of their rather high number (compared to other top hosts) of outages.

17. HostRocket.com

HostRocket 2018 statistics
Limited uptime guarantee:

HostRocket has an official 99.5% uptime guarantee. Like others, it only applies for their own direct services.

18. HostMonster.com

18. HostMonster.com

HostMonster 2018 statistics
No uptime guarantee:

Even though you can find a statement claiming to strive for their best, there is no official uptime guarantee.

19. DreamHost.com

Dreamhost 2018 statistics
Uptime guarantee available:

Finally, there you have it – an official 100% uptime guarantee.” DreamHost guarantees 100% uptime. A failure to provide 100% uptime will result in customer compensation pursuant to guidelines established herein.”

20. Hosting24.com

Hosting24 2018 statistics
Limited uptime guarantee:

They offer a service uptime guarantee of 99.9%. It’s solely determined by them and you get 5% of your monthly hosting fee as credit back. It’s only usable to purchase further service of products from Hosting24.

21. WestHost.com

WestHost 2018 statistics
Uptime guarantee available:

At close investigation, we found a 99.9% service uptime guarantee. When outages happen which are directly related to WestHost, you get a credit of 5-100% of your monthly hosting fee depending on the total downtime.

22. WebHostingHub.com

WebHostingHub 2018 statistics
No uptime guarantee:

WHH claims on their front page to have a 99.9% uptime guarantee. Unfortunately, we did not find an official guarantee under their terms of service and other binding policies.

23. inMotionHosting.com

inMotion Hosting 2018 statistics
Limited uptime guarantee:

Uptime guarantee only applies to Business Pro accounts. Even though it’s a really sweet one (99.999%), there is no uptime guarantee for other hosting plans.

24. A2Hosting.com

A2 Hosting 2018 statistics
No uptime guarantee:

A2 comes with a 99.9% uptime commitment. Similarly to other hosting providers, when it comes to credit, there are clauses related to server maintenance and the outage being not-their-responsibility.

25. HostMetro.com

HostMetro 2018 statistics
Limited uptime guarantee:

When the total uptime in a year is less than 99%, you get a 1-month service for free.

26. MDDHosting.com

MDD Hosting 2018 statistics
Uptime guarantee available:

They have an official 1000% service uptime guarantee (it’s not as cool as it sounds).

“If your server has a physical downtime of more than 1 hour, you can request for 10 times (1000%) the actual amount of downtime. This means that if your server has a physical downtime of 1 hour, you will receive 10 hours of credit.”

27. FatCow.com

FatCow 2018 statistics
No uptime guarantee:

It doesn’t seem that uptime is one of the strengths of FatCow – despite our research, we did not find any uptime guarantee.

28. NameCheap.com

NameCheap 2018 statistics
Uptime guarantee available:

NameCheap offers one full day of service for every 1h that your server is down in a month. Beware that the first 45min are not applicable.

29. HostNine.com

HostNine 2018 statistics
No uptime guarantee:

An uninspiring total uptime is even further disappointing as there is no uptime guarantee under their ToS.

30. One.com

One.com 2018 statistics
No uptime guarantee:

A day without service is a serious issue by itself. Despite our serious efforts, we could not find any uptime guarantee either that would make you eligible for at least some credit.

31. WebHostingPad.com

WebHostingPad 2018 statistics
Limited uptime guarantee:

There is a 99% official uptime guarantee. However, it’s most likely that you wouldn’t really care about the few free days you get when the service performance is this bad.

32. Arvixe.com

Arvixe 2018 statistics
Uptime guarantee available:

Despite their bad performance (the worst ever, by far, anywhere…), Arvix actually does have an official uptime guarantee of 99.9%. But does it really matter to get a refund or some credit when your website has lost all its traffic because of its non-existent performance?

Smashing Editorial
(ms, ra, il)

Source: Smashing Magazine, Webhosting Compared: Testing The Uptime Of 32 Hosts In 2018

A/B Testing For Mobile-First Experiences

dreamt up by webguru in Uncategorized | Comments Off on A/B Testing For Mobile-First Experiences

A/B Testing For Mobile-First Experiences

A/B Testing For Mobile-First Experiences

Suzanne Scacca



Your client’s website is done. They’re thrilled with it. You and your team are satisfied with the results. And visitor reception looks good so far.

While I recognize that a lot of research, experimentation, analysis and review went into the creation of the website, is that all there is to building a winning website these days? I’d argue that the mobile-first web has added a layer of complexity that few are fully prepared for.

Which is why your work shouldn’t stop when you hit the “Publish” button.

If you’re not yet performing post-launch A/B testing for your website clients, that’s a big mistake. Although we have a massive amount of case studies and other research at our disposal that confirm how to design for conversion on desktop, the mobile experience is still relatively new. At least the mobile-first experience as we know it today.

The following guide includes tips for A/B testing for mobile websites and will get you thinking about conversion rate optimization in other ways than just “Buy This Now”.

A Brief Introduction To A/B Testing For Mobile

Once a website has gone live, Google Analytics and any conversion rate optimization (CRO) tools you hook up to the site will start feeding you data about your users. If you choose to do something with these valuable insights, you have two options:

  1. Identify obstacles in the experience and implement changes to the site to resolve them.
  2. Identify a single obstacle in the experience, hypothesize why it occurred and create an alternative version of the site to test the resolution.

The first option seems cut-and-dried. The data tells you there is an issue; you create a solution for it. But like I mentioned already, the chances of succeeding when shooting from the hip like that only work with tried and true desktop design techniques. Even then, it can still be risky if your audience doesn’t align with the average online user’s behavior.

The second option, on the other hand, allows designers to more safely implement changes to a mobile website. Until you have a clear picture of the mobile user’s journey through your website (which, realistically, could involve them jumping from a mobile device to desktop at some point), mobile A/B testing must be an essential part of your job as a web designer.

This is how A/B testing works:

  • Identify a part of the website that you believe needs a change. (This should be based on findings in your data or direct reports from users about problematic experiences.)
  • Hypothesize why there is friction and how you think it can be resolved.
  • Choose just one element to change.
  • Using A/B testing software, set up your test variables. You should pit the control (i.e. original version of the site) against a variation of the element.
  • Run the test against equal parts of mobile visitors.
  • Let the test run for two to four weeks.
  • Monitor results to make sure you’re generating sufficient data and take note of any anomalies along the way.
  • End the test and review the results.
  • If there’s a significant margin between the control and variation results, use your mobile A/B testing tool (like VWO) to implement the winner.

It’s okay if you find that the control is the winner. Take what you’ve learned and apply it to your A/B testing efforts going forward.

Recommended reading: How To Conduct Usability Studies With Participants With Disabilities

Tips For A/B Testing For Mobile-First Experiences

You’re here because you want to know how to increase conversions on the websites you build for clients. The tips below will force you to step outside typical conversion rate optimization planning and think outside the box as you test your theories.

Tip #1: Stop Thinking About Mobile vs. Desktop A/B Testing

With traditional A/B testing, you typically have verifiable proof of what works and what doesn’t. You tweak the wording on a call-to-action and more users click to buy the product. You change the color of the shirt in a photo and sales go up by 25%. You move the placement of the CTA to the bottom of the post and more readers subscribe.

In other words, you know that a change you made will directly impact the business’s bottom line.

However, when it comes to mobile, it’s not that easy.

Qubit published a report called The Influence of Mobile Discovery in 2018.


Qubit mobile halo effect
Qubit demonstrates growth in the mobile halo effect. (Source: Qubit) (Large preview)

The above image depicts the differences in the mobile halo effect from 2016 to 2017.

The mobile halo effect is a term Qubit uses to describe how the activity that takes place on mobile directly influences what happens on desktop. Qubit’s research of over 1.2 billion customer interactions with the web found:

Analyzing the cohort of users in our dataset who logged into their accounts on more than one type of device shows that mobile activity directly influences an average of 19% of computer revenue. In some sub-verticals, this influence is much higher, with Fashion seeing an average of 24%, while some retailers receive as many as 1 in 3 of their computer transactions as a result of mobile-browsing.

What’s more, this information only accounts for mobile users who logged into a website from multiple devices. Qubit suspects that people who simply discover a website through mobile also lead to this halo effect. This, in turn, drives up the value of desktop conversions because of how helpful mobile is during the discovery phase of the customer journey.

This is why you can’t just look at mobile-only results on a mobile-first A/B test.

Instead, conduct your tests in the following manner:

  • Run your test with mobile visitors.
  • Review the results from your A/B testing tool to see if you were able to remove the obstacle from the mobile experience.
  • Then, look at your Google Analytics results from the same time period. Even if mobile traffic continued to drop off at the same point, you may find that desktop traffic and engagement increased as a result.

In sum, don’t go into mobile A/B testing thinking that everything you do must result in a greater amount of sales, subscribers or members on mobile. Instead, focus on how to improve the experience as a whole so that it improves your overall conversion rate.

Tip #2: Start with the Header

Remember that there are four micro-moments (or motivations) that drive mobile users to a website:

  1. I want to know.
  2. I want to go.
  3. I want to do.
  4. I want to buy.

With such a clear purpose driving their journey to and hopefully through your mobile site, don’t force them to wait for what they’re asking for. In terms of design, this translates to shortening their pathway — either to conversion or to completing the mobile experience before moving to desktop.

When you begin mobile-first A/B testing, look at elements that provide an answer to the micro-moments that are most relevant to your website.

Is there a way to place them in the header of the website or within the first scroll or two of the home page? Or can you at least design a one-click shortcut in the navigation to take them to it?

Here are some ideas:

1. I want to know.

Websites with lots of content would do well to test whether or not rearranging the navigation and putting emphasis on relevant and timely categories helps with conversion.

BuzzFeed takes this theory a step further:


BuzzFeed mobile navigation
BuzzFeed doesn’t hide its mobile navigation. (Source: BuzzFeed) (Large preview)

In addition to customizing the navigation regularly, BuzzFeed has chosen to leave the main navigation out in the open on mobile, with a fun selection of emojis to draw attention to the timeliest of categories.

Another way to answer the “I want to know” search is by providing a point of contact in as streamlined a fashion as possible as SensesLab has done:


SensesLab contact shortcut
The SensesLab includes a recognizable “mailto” icon in the header. (Source: SensesLab) (Large preview)

The “Mail” icon in the top-right corner takes mobile visitors to the Contact page. However, this is no ordinary contact page. While an introduction to their point of contact and email address is given, it’s the contact form below that really shines:


SensesLab contact form
The SensesLab provides a super mobile-friendly contact form at the shortcut. (Source: SensesLab) (Large preview)

The entire form fits within an entire screen-grab on my iPhone above. There’s no wasting of time by providing instructions on how to fill out the form or anything like that. Users just need to click on the highlighted fields to personalize their responses.

Even better:


SensesLab contact form fields
The SensesLab uses user-friendly contact form fields. (Source: SensesLab) (Large preview)

SensesLab has anticipated their responses and provided pre-populated answers along with custom keyboards to shorten the amount of time anyone has to spend filling this out.

2. I want to go.

I think the solution to test for with this one is obvious. In other words:

Where in the header or above the fold do you place the reservation buttons?

Just don’t be afraid to think outside the box with this. For example, this is The Assemblage website:


The Assemblage 'Book Tour' button
The Assemblage includes a ‘Book a Tour’ icon on the mobile home page. (Source: The Assemblage) (Large preview)

The Assemblage is a coworking space located in New York City. While the mobile site could’ve easily prioritized conversions up top (i.e. “Get your membership now!”), it instead provides a shortcut that makes more sense.

With the focus on booking a tour, mobile visitors can easily claim a date and time. Then, worry about learning all about and seeing the workspace in person later.


The Assemblage books tours
The Assemblage prioritizes booking tours of the cowork space. (Source: The Assemblage) (Large preview)

Completing the booking process is incredibly easy on mobile, too.

There are other ways to think outside the box when it comes to designing and testing for “I want to go”. This next example combines two micro-moments and does so in a really unique way, in my opinion.

This is Visit California:


Visit California Map icon
Visit California uses a recognizable Map icon in its header. (Source: Visit California) (Large preview)

Among the well-chosen icons its placed in the header of the site, Visit California also includes a “Map” icon. After all, what is one of the main reasons why someone would visit this site?

“I want to go to California and need suggestions!”

Now, behind this map icon is not a reservation system, enabling users to book their trip to California. With a site promoting travel to such an expansive location, users are more likely to use this site to gather information to decide where to go. The Map icon, then, is their key to drilling down deeper into those answers:


Visit California regions
Visit California’s Map navigation options. (Source: Visit California) (Large preview)

This is a unique and visually stimulating way to get research topics and answers into the hands of people who want it.

3. I want to do.

This question is an interesting one to design and A/B test for.

On the one hand, you’d assume that “I want to do” would be answered by articles that provide a how-to for the desired task. When that’s the case, the abundantly sized search bar from Kitchn is a good idea to test for:


Kitchn mobile search
Kitchn uses a search bar that’s comparable in size to the header bar. (Source: Kitchn) (Large preview)

It’s clear what Kitchn users want to do when they get here: search for recipes. And with a magazine of Kitchn’s size, that could be a difficult task to accomplish by using the traditional navigation. Instead, this search bar that’s nearly comparable in size to the entire header bar provides a faster solution.

But then you have the other kind of “I want to do” situation to design for — the one where the visitor of your mobile site wants to go out in the real world and get something done. This is similar to the “I want to go” solution from The Assemblage.

ReShape is a fitness center in Poland:


ReShape home page
ReShape’s home page looks like your typical fitness center website. (Source: ReShape) (Large preview)

Once you open the navigation on this website, users encounter a number of options to learn about the fitness center and its services.


ReShape navigation calendar
ReShape includes a navigational shortcut for mobile customers. (Source: ReShape) (Large preview)

What’s nice about this, however, is that the website allows current customers to cut the line and schedule a class right away through the calendar icon. There’s no need to download and use a separate mobile app. It’s all right on the mobile website and it’s easy to do, too:


ReShape mobile scheduling
ReShape makes scheduling fitness classes through mobile a breeze. (Source: ReShape) (Large preview)

When the success of the website and business is contingent upon getting customers to actually do something, don’t bury it in the mobile experience.

4. I want to buy.

Lastly, there’s the “I want to buy” scenario you have to test for.

While the hypothesis for this kind of test is going to be easy enough to figure out — “I want to get more mobile customers to make a purchase” — it’s how you use your design to compel them to do so that’s going to be difficult. Because, again, you have to remember that mobile conversion isn’t simple.

One example I really like of this comes from The Bark, a magazine for dog owners.


The Bark hello bar
The Bark hello bar commands attention without being pushy. (Source: The Bark) (Large preview)

What’s nice about this design is that there are two actions competing against one another:

  1. The content of the website that allows visitors to peruse articles for free.
  2. The unobtrusive yet boldly designed sticky bar with an attractive offer to convert.

The Bark subscription
The Bark subscription page for mobile. (Source: The Bark) (Large preview)

As more and more we move away from pop-ups and with the sidebar having little to no place on mobile, we’re running out of options for ways to jump into the experience and say:

Hey! Buy this now!

You could place banners in-line with the content, but that may be too disruptive for your users. While I’d assume that a sticky bar that can easily be dismissed is the better way to compel mobile visitors to convert, this is why we have A/B testing. To let us know what exactly our specific audience will do when confronted with a Buy (Subscribe) CTA on mobile.

And if they don’t want to convert there, that’s fine. At least you’ve done your due diligence in testing alternative scenarios to see if you can improve your success rate.

Tip #3: Encourage Users to Save Instead

This last point is a good segue into what I’m going to talk about next:

There are just some websites that won’t convert well on mobile.

Although research on Generation Z as consumers is still relatively new, many suggest that they are going to be true multichannel shoppers. Most of their research will be done on mobile devices, but the preferred shopping experience will be from a computer or in person.

Whether or not that’s true for Gen Z, millennials or any other generation of consumer, I think it’s a smart idea to test for this hypothesis. Until your mobile conversion rates are consistently and significantly higher than desktop and in-person conversion, encouraging mobile users to “Save” their progress on your site might be the better design choice.

As you work on designing and redesigning websites this year, you might want to save yourself the trouble of committing solely to a conversion funnel. Instead, build in shortcuts to “Save” on the mobile experience like:

  • Sign up for an account.
  • Save products to your cart or wish list.
  • Save an article or feed for future reading.
  • Share your email address for future updates.
  • Sign up for a free demo and we’ll take care of the rest.

Then, when the site is live, test how the conversion rates are affected with or without them.

Here are some neat examples of websites that use “Save” features well on mobile.

This is Entrepreneur magazine:


Entrepreneur Save function
Entrepreneur has a “Save” content icon in its header. (Source: Entrepreneur) (Large preview)

See that icon in the header between the search magnifying glass and account settings? This is where Entrepreneur enables regular readers to save content for future consumption:


Entrepreneur Save folder
Entrepreneur’s well-organized “Save” folder for readers. (Source: Entrepreneur) (Large preview)

As you can see, readers can save all sorts of content under this Save feature, making it easy to return to Entrepreneur articles any time, any place and from any device.

Then, there’s the example of Zendesk:


Zendesk free demo button
Zendesk offers a free demo and trial right away. (Source: Zendesk) (Large preview)

For those of you designing websites for service providers and SaaS companies, this is an excellent way to help your users “Save” their progress. I know it might not look that way at first glance, but let me explain:

Zendesk isn’t wasting anyone’s time with an overlong description of what it does and why people need to purchase its help desk software. Instead, it’s clearly summarized what users can expect and then provides two appealing calls-to-action. Regardless of which option the mobile user chooses, Zendesk requires them to provide contact information.

So, let’s say a mobile user fills out the form to enter the demo. They get inside it, but then realize they’re short on time or just don’t want to interact with it on mobile. Fine. Zendesk now has their information and will be in touch soon to follow up about the experience. The mobile user can then re-enter the experience from their preferred device when the inevitable follow-up email reminds them to do so.

Tip #4: A/B Test Your Page and Post Length

Another suggestion I’m going to make for mobile-first A/B testing is content length.

I actually touched on the subject of brevity in my previous article, How Web Designers Can Contribute to Mobile-First Marketing. However, I didn’t talk about how you can use A/B testing to confirm whether or not that’s the right path for your website.

There are case studies and research reports galore that discuss the subject of ideal content length for both desktop and mobile. Some are emphatic that shorter is always better, which is why I think we’ve seen such a huge push for video over written content in past years.

But then there are some who suggest that length should be determined on a case-by-case basis.

Take the Neil Patel blog, for instance. If I had to guess, I’d say that his articles are between 2,000 and 5,000 words on average — even on mobile. Considering Patel is a multi-millionaire, I don’t suspect that his lengthy posts have hurt the success of his brand in the least bit.

So, again, this is why we need A/B testing — just to confirm our suspicions and put any fears we might have about the efficacy of a site’s design or content to rest.

Unless your client comes to you as a well-known brand and they’ve already proved they can produce successful 2K-word posts like Patel, you have to test this.

Talk to your writers and marketers and ask them to create two different versions of your content for the first month or two. This includes the home page, blog posts, product pages and any other key pages in the user’s journey. Run a test to see if the length of the page on mobile affects readability as well as conversions.

You can then use these results to refine the rest of the content on your site, making sure you’re providing mobile users with the ideal reading experience wherever they go.

Wrapping Up

The goal in mobile-first A/B testing is to inspire mobile visitors to keep moving through the experience. Even if the element you’ve chosen to test doesn’t directly lead to conversion, the improvements you make should eventually trickle down to that final step, no matter which device it takes place on.

Just don’t forget to study your desktop analytics while running mobile-first A/B tests. While test results might not show you what you were hoping to see, looking at the overall picture might.

Smashing Editorial
(ra, yk, il)

Source: Smashing Magazine, A/B Testing For Mobile-First Experiences

Collective #491

dreamt up by webguru in Uncategorized | Comments Off on Collective #491



C491_videopl

IVID

IVID is an interactive video player for modern browsers that is easy to setup and use.

Check it out












C491_boring

Make it Boring

Jeremy Wagner explains why “boring” can be preferable to “exciting” when it comes to front-end development.

Read it


C491_terminal

Qoa

Lightweight and without any external dependencies, qoa enables you to receive various types of user input through a set of intuitive, interactive and verbose command-line prompts.

Check it out


C491_thirdparty

Third Party Web

A summary of which third party scripts are most responsible for excessive JavaScript execution on the web.

Check it out








Collective #491 was written by Pedro Botelho and published on Codrops.


Source: Codrops, Collective #491