03 Dec 2017, 10:10

Creating Gradient Borders with CSS

Products have seen a resurgence of gradients in the past year or so. I too wanted to cash in on the PowerPoint circa 2003 aesthetic and as such I took to work on finding how I could add some gradients to the button outlines on my blog. Unfortunately I really struggled to find any decent guides on the matter, but after a little bit of digging and understanding the solution was fairly straightforward. Recently I’ve been trying to write shorter blog posts more often about little things I’ve learned, so I thought I’d share that with you folks today!

So from my research, the canonical way to do gradient borders in modern browsers appears to be as such:


    .someButton {
        border-image: linear-gradient(to left, #743ad5 0%, #d53a9d 100%);
        border-image-slice: 1;
        border-width: 2px;
    }
   

This is the gradient I am currently using for the navigation buttons on the left. Here border-image allows a developer to pass in a image URL or a gradient (perhaps unintuitively). You can find it’s full details on MDN here. In our case we are interested in a gradient so we can use linear-gradient or alternatively a radial-gradient if you’re looking for that sort of effect. You can use a direction argument to specify a given direction for the gradient, for example in our case above to left or bottom right might be another example.

A nice little website for generating gradients is https://www.css-gradient.com/, where you can play around with different properties to get your desired result. A note however, you shouldn’t need a prefix any more for gradients so you can ignore that!

border-image-slice is the second CSS property we need to fill to get this working. As I was, you might be asking what on earth does this do? If you’re anything like me, it can be quite hard to wrap your head around. As an exact definition: “The border-image-slice CSS property divides the image specified by border-image-source in nine regions: the four corners, the four edges and the middle” (MDN). The property has less meaning in the gradient context as it specifies offsets for the image in question to position it for the border in question. border-image-slice can take up to four sets of arguments, each with different behaviours depending on the number of arguments provided. The arguments here can either be a percentage or a number, with the default value for the property being 100%. For our use case, we will be providing it a value of 1. If you want to get a clearer picture, consider seeing the docs for the property.

Finally, good old border-width will provide a given width for our border in question. You can adjust it as you see fit to get the desired effect. Here’s some little gradient buttons I made for inspiration!



.buttonOne {
    border-image: linear-gradient(to right, #b861c6 0%,#ffc7c7 100%);
    border-image-slice: 1;
    border-width: 3px;
}

.buttonTwo {
    border-image: linear-gradient(to left, #61c69d 0%, #2d72bc 100%);
    border-image-slice: 1;
    border-width: 3px;
}

.buttonTwo {
    border-image: linear-gradient(to left, #61c69d 0%, #2d72bc 100%);
    border-image-slice: 1;
    border-width: 3px;
}

Which after applying the class to your button in question would look a little something like this in your browser:

Hopefully that’s been a fairly painless guide to generating your own gradient borders in CSS. Have fun!

11 Nov 2017, 15:00

Replicating JavaScripts setTimeout and setInterval in Go

In JavaScript we have two inbuilt functions for doing some work at some given point in the future. Firstly setTimeout; this allows us to run a function after a given period of time in milliseconds. We also have setInterval which allows us to run a function every x milliseconds until the interval is cancelled with clearInterval. You can find a solid overview of timers in JavaScript on MDN here.

For those unfamiliar with the two functions, let’s see how they look (in ES5):


    var timeout = 1000; // 1 second

    setTimeout(function(){
        console.log("This will happen after " + timeout + "milliseconds");
    });

    var interval = 500; // 0.5 seconds

    var anInterval = setInterval(function(){
        console.log("This will happen after " + timeout + "seconds");
    });

Recently I have been wanting to achieve the same thing in Go on a small side project I am working on. As such I thought I would share my findings with you all!

Replicating setInterval

setInterval is arguably the more complicated of the two functions to implement. The basic premise is we setup a new ticker from Go’s time package. The NewTicker function creates a channel which we can select over (see here for an overview of the select feature in Go), which passes a signal to the channel every x milliseconds, calling the arbitrary passed in function. We also select over the clear channel. This can in turn clear the interval when we pass a boolean value to it.


    func setInterval(someFunc func(), milliseconds int, async bool) chan bool {

        // How often to fire the passed in function 
        // in milliseconds
        interval := time.Duration(milliseconds) * time.Millisecond

        // Setup the ticket and the channel to signal
        // the ending of the interval
        ticker := time.NewTicker(interval)
        clear := make(chan bool)

        // Put the selection in a go routine
        // so that the for loop is none blocking
        go func() {
            for {

                select {
                case <-ticker.C:
                    if async {
                        // This won't block
                        go someFunc()
                    } else {
                        // This will block
                        someFunc()
                    }
                case <-clear:
                    ticker.Stop()
                    return
                }

            }
        }()

        // We return the channel so we can pass in 
        // a value to it to clear the interval
        return clear

    }

    func main() {

        // A counter for the number of times we print
        printed := 0
        
        // We call set interval to print Hello World forever
        // every 1 second
        interval := setInterval(func() {
            fmt.Println("Hello World")
            printed++
        }, 1000, false)
        
        // If we wanted to we had a long running task (i.e. network call)
        // we could pass in true as the last argument to run the function
        // as a goroutine

        // Some artificial work here to wait till we've printed
        // 5 times
        for {
            if printed == 5 {
                // Stop the ticket, ending the interval go routine
                stop <- true
                return
            }
        }

    }

Replicating setTimeout

Replicating JavaScripts setTimeout is slightly more straight forward. We can leverage the time package’s AfterFunc function which fires off goroutine that will run a function after a given period of time. We could do this using code like this:


    func setTimeout(someFunc func(), milliseconds int) {

        timeout := time.Duration(milliseconds) * time.Millisecond

        // This spawns a goroutine and therefore does not block
        time.AfterFunc(timeout, someFunc)

    }

    func main() {

        printed := false
        print := func() {
            fmt.Println("This will print after x milliseconds")
            printed = true
        }

        // Make the timeout print after 5 seconds
        setTimeout(print, 5000)

        fmt.Println("This will print straight away")
        
        // Wait until it's printed our function string
        // before we close the program
        for {
            if printed {
                return
            }
        }
        
    }

Hopefully this has given some insight on how we might achieve similar functionality in Go to JavaScripts setInterval and setTimeout functionality. If you see a potential problem, or have ideas about a better solution I would love to hear them!

23 Aug 2017, 19:28

Low Hanging PWA Fruit: Manifest Files and Service Worker Precache

It would be a fair assessment to state that Progressive Web Apps (often abbreviated to PWA) are a popular buzzword in the web development and JavaScript communities at the moment. We have also seen further excitement recently, generated by Apple’s move to start supporting development for PWA features within Safari.

Many great posts and documentation exist around explaining the full case for PWAs and how they benefit users. For a solid introduction to Progressive Web Apps check out Google’s page on the matter. In addition, if you’re looking for something tangible there’s also lots of great examples of PWAs that you can explore in more detail at pwa.rocks.

Perhaps now more than ever it’s time to start exploring how you can start looking into aligning your app or site with PWA functionality. This post will be more practical than theoretical, but to give some context I will list out some of the core concepts of what makes a PWA for those of you unfamiliar:

  • Pages are responsive: The app’s content fits in a sensible way on a tablets, mobiles etc
  • Site is served over HTTPS: assets and resources are served using encryption over the wire
  • The entry page loads offline for users
  • The app uses a manifest.json file to allow adding the app to a users homescreen
  • Load times are reasonable even on slower connections like 3G
  • Each page has its own unique URL
  • The site works across modern browsers

Here we will just focus in on two of these concepts and how to integrate them, namely adding a manifest.json file and adding a Service Worker. Subsequently, we can also use the Service Worker to allow the initial page to work offline by using a precache.

Adding a Manifest File

A manifest file provides a few additional weapons to the web app arsenal for developers. The file itself is fairly plain; a JSON file that contains configuration and metadata for various aspects of the application.

However what the manifest file allows for is a whole host of interesting benefits for those looking to give a more ‘app like’ experience:

  • Allowing users to add a web app to their home screen
  • Giving that home screen button a unique name and icon
  • Giving a splash screen to the app when the user loads it
  • Being able to add a theme colour for the web app
  • Define if the app should load ‘standalone’ or in a web browser

Now we’ve gone through why you would add a manifest.json file, let’s take a look at an example config:


{
  "name": "SomeCoolApp",
  "short_name": "SomeCoolApp",
  "start_url": ".",
  "display": "standalone",
  "background_color": "#111111",
  "description": "An app for doing cool things",
   "icons": [{
    "src": "images/manifest/48.png",
    "sizes": "48x48",
    "type": "image/png"
  }, {
    "src": "images/manifest/72.png",
    "sizes": "72x72",
    "type": "image/png"
  }, {
    "src": "images/manifest/96.png",
    "sizes": "96x96",
    "type": "image/png"
  }, {
    "src": "images/manifest/144.png",
    "sizes": "144x144",
    "type": "image/png"
  }, {
    "src": "images/manifest/168.png",
    "sizes": "168x168",
    "type": "image/png"
  }, {
    "src": "images/manifest/homescreen192.png",
    "sizes": "192x192",
    "type": "image/png"
  }],
  "related_applications": [{
    "platform": "web"
  }, {
    "platform": "play",
    "url": "https://play.google.com/store/apps/details?id=SomeCoolApp"
  }]
}

You can see that we provide a name and short_name which give a name and an abbreviated name for the app when space is a premium. start_url expresses where the kick off URL for the application when the user starts the app. For example, it could be their profile page or the home page.

As mentioned, we can decide if the app should load in a web browser or have a more native experience. This is realised through the display property. We can provide standalone to give a more native feel as it hides away browser features like the URL bar (this may be a negative feature depending on your feelings!). There are other options for this such as fullscreen which hides OS UI features, and also minimal-ui which take a middle ground on the matter.

The background_color property allows for us to express a colour that will occur before the app has fully loaded into its container. icons provide a way to give icons for our applications at different device sizes. For a full list of options check out MDN’s page on the matter.

You could write the manifest file manually (see Google’s instructions here). However, if you want a more streamlined experience you could use a generator instead. One generator I found user-friendly and straight forward is the app-manifest app on Firebase, which you can use to generate a zip file which can be unloaded into your web app directory.

Lastly we can include it in our home page’s HTML as so:

<link rel="manifest" href="/manifest.json">

Adding a Service Worker

The Service Worker is a slightly more complex concept than the manifest file. In essence Service Workers are web workers that allow code to run outside of the web page context within the browser. The Service Worker also in some ways acts as a network proxy, allowing the developer to change the behaviour of network requests (i.e. to read from a cache rather than a remote resource). In principle, these two concepts allow for a host of new opportunities for web apps, including push notifications, offline interactivity and background sync (sending server requests upon resumption of connectivity).

Before we dive in any deeper, it’s important to note that Service Workers require HTTPS to operate, so you will need to have that setup on your site before continuing (checkout Let’s Encrypt if you’re in need of an SSL certificate).

Although we could dig in deep into the Service Worker internals and life cycle, I would rather focus on getting us up and running with a Service Worker. Others have done a great job explaining Service Workers in depth, for example see the Google primer on Service Worker or check out Phil Nash’s great introductory video here. Instead we will focus on one example Service Worker template that allows us to get a registered Service Worker into our page quickly.

An easy to leverage Service Worker template is provided by sw-precache. Using a precache allows you to serve resources from the Service Worker cache, rather than having to wait for it to come over the wire which improves the performance of the app. It also allows us to get resources whilst offline. sw-precache itself is a tool that allows for the automatic code generation of a Service Worker for caching assets that we would normally receive over the network (images, css etc). As sw-precache requires a preprocessing step to generate the Service Worker we need to leverage a task runner. Here we can use gulp, a JavaScript task runner to create a task to generate the list of resources we want to precache. Here’s some example code with comments:


    // Register the service-worker task with Gulp
    gulp.task('service-worker', function(callback) {

        // Get hold of the sw-precache module
        var swPrecache = require('sw-precache');
        var rootDir = '../public/';
        var serviceWorkerName = "precache"; 
        var fileName = `${rootDir}${serviceWorkerName}.js`;

        // Write the precache Service Worker
        swPrecache.write(fileName, {

            // An array of file paths to precache (we use globbing)
            staticFileGlobs: [
                rootDir + 'index.html',
                rootDir + 'templates/.{html}',
                rootDir + 'js/**/*.{js}',
                rootDir + 'css/**/*.{css}',
                rootDir + 'fonts/**/*.{svg,eot,ttf,woff,woff2}',
                rootDir + 'icons/**/*.{svg}',
                rootDir + 'images/**/*.{png,jpg}',
            ],
            // We remove the prefix and can replace it with another
            // Here `../public/` becomes `/` for example
            stripPrexix: rootDir,
            replacePrefix: "/"

        }, callback);

    });

Running gulp service-worker will generate our Service Worker precache file called precache.js. We can now register this into our app using the code expressed below:

    // Check to make sure the Service Worker feature exists
    if ("serviceWorker" in navigator) {
        // On page load, call the Service Worker registration
        window.addEventListener('load', registerSW);
    }

    // The actual registration code
    var registerSW = function() {

        // The location of our generated pre-cache Service Worker
        var swPath = "/precache.js";
        navigator.serviceWorker.register(swPath)
            .then(registrationSuccess, registrationFailed);

    }

    var registrationFailed = function(error) {
        // Do something if there is an error
    }

    var registrationSuccess = function(registration) {
        // Do something if everything is successful
    }

Once the Service Worker is registered the user will make use of the cache when making network requests for cached assets.

Conclusion

Here we have shown how you could add a manifest and a Service Worker to your web app without complicating your application code too much. If you already have gulp in your build process integrating sw-precache shouldn’t be too much extra effort to get up and running. Similarly using the manifest.json app shown above we can simply generate a working manifest file for our application.

Hopefully, this article has begun to pave the way for further PWA features in your applications. Support is gradually getting there so the reasons to avoid the potential benefits are decreasing. If you are interested in auditing your app to see how much it adheres to Google’s PWA checklist, check out a Chrome extension called Lighthouse. Lighthouse will score your app depending on how well it compares a set of pre-defined criteria.