If you’ve ever needed to allow a user to select one from a range of options on a webpage, you’ll know that the radio input type lets you do this.


But what if you want to customize the appearance and instead of showing regular radio buttons you want clickable buttons like this?


Well, thanks to a very helpful StackOverflow answer I was able to work out how to create this style of radio buttons.

First of all, you start off by hiding the actual circular radio buttons themselves – we’ll just be styling the labels. We can select them by using input[type="radio"]

.radio-toolbar input[type="radio"] {

Next, we set the labels up to look how we want them by default when unselected:

.radio-toolbar label {
    padding: 10px 20px;
    border: 2px solid #444;
    border-radius: 4px;    

Now we have to style the selected one differently. This is where the real CSS magic happens – we need to use the :checked selector and the “adjacent sibling” selector (+ sign). So this CSS rule applies to any label that immediately follows a checked radio button.

.radio-toolbar input[type="radio"]:checked + label { 
    border-color: #4c4;

Finally, I wanted a hover effect so that as you hovered the mouse over the other options they changed appearance. This can be achieved with the :hover selector.

.radio-toolbar label:hover {
  background-color: #dfd;

Here’s a complete example:

A few weeks ago I posted a list of my favourite videos from NDC Sydney 2016. Well, I’ve continued to watch sessions as they’ve been uploaded, and there’s a lot of excellent material there, so I thought I’d share another list of recommendations.

The Rise of Serverless

It seems every year at least one new architectural buzzword is coined, and a new style of programming emerges that promises to be the one true way to build systems that will solve all your problems.

In recent years we've had CQRS, Microservices, Containers, Actor Model, and now "Serverless" is the next big thing, complete with its own books, conferences, and even a Martin Fowler bliki entry.

I've been following this with a lot of interest, particularly since I've been playing with Azure Functions, which is Microsoft's offering in the serverless space.

The concept of serverless architectures has attracted a lot of excited interest (and hype) as well as some ridicule (and cynicism), so here's my take on it.

Naming Things is Hard

Let's start with the name "serverless", which is patently ridiculous! Serverless would be more appropriate name for the first programs I ever wrote as a child on my dad's BBC micro which wasn't connected to a server or network of any kind.

The irony is that if you have a serverless architecture there are probably many more servers involved than if you had created a traditional monolithic backend!

What is Serverless?

But gripes about the name aside, what does "serverless" actually mean? The way I see it, serverless is a style of architecting applications where you avoid using traditional backend servers, such as virtual machines running web servers, databases or background tasks.

Relying on Third Party Services

Instead, yourely wherever possible on third party services who can offer core pieces of functionality and manage the servers for you. So for example, you might use Auth0 for your authentication, SendGrid for your email, Stripe for payment processing, SQL Azure or Firebase for your data, and so on.

Now so far, you're probably thinking, that's just Paas (or Baas - Backend as a service ) right? Many cloud deployed systems are already incorporating services like these anyway anyway. Well, third party services can only get you so far. At some point you need to write a bunch of your own code.

And this is where traditionally you might create some web APIs, maybe an ASP.NET MVC app hosted on IIS, or a Windows service listening on queues and running on a Virtual Machine.

Deploying Individual Functions

But serverless encourages us to deploy our code in the smallest units possible - at the function level. This is what Azure Functions (and rival offerings such as AWS Lambda) offer. They allow you to deploy a single function that is listening on a web endpoint, or processing messages from a queue, or running on a schedule. Each function has an “event” that it is waiting for to trigger it.

With this style, all the boilerplate is abstracted away for you. You don't need to set up the OWIN pipeline and logging. You don't need to write the code that connects to the queue and polls for messages. You just write the bit of code that responds to the event you are interested in.

And you don't need to know or care about what server your function is hosted on, or even how many servers there are. That's all taken care of you by the platform. (Hence the name "serverless" which makes a bit more sense viewed in this light)

So in some ways, serverless could be called a "nanoservices" architecture - taking microservices to the extreme where each one is essentially a single function. It's taking the "Single Responsibility Principle" to the next level where your unit of deployment is just a single function.

The fact that the server is abstracted away means your functions need to be stateless, since you don't know which server will handle the next event.

Eliminating Layers

Many serverless advocates also recommend reaching directly from the client into third party servicesrather than stepping through intermediate layers. This one is a bit more controversial, especially if you are letting the client connect to the database, and it requires rich database security model where users can be granted permissions on a granular level. But done right, this idea has potential to greatly simplify the flow of data through your system with performance, cost and maintainability benefits.

The Benefits of Serverless

So, that's a bit about what serverless is (and I encourage you to watch this talk if you want a bit more depth). But what is this style of architecture good for? Why would we want to use it?

Well, first of all, it's great for speed of movement. Combining third party services with something like Azure Functions or AWS Lambda allows you to move rapidly and prototype quickly. Functions are trivially easy to create, and within minutes you can have a back end set up as a proof of concept.

The next benefit is not having to manage servers. You're not provisioning the hardware, installing and patching the OS. You're not even installing, configuring and patching application frameworks like .NET and IIS. Instead you just need to hand it your code and its up and running instantly. And deploying your code is trivially easy, often as simple as pushing to a Git remote.

Another big benefit is the cost model. Azure Functions and AWS Lambda both offer apay only when you're running model. So if you have a web endpoint that never gets called you pay nothing! Contrast that with Iaas or even Paas offerings where you're paying a monthly fee to host your webserver whether it handles any HTTP requests or not. AWS Lambda even offer you a generous free allowance of compute each month.

Scale is the next benefit. You don't need to specify scaling conditions; the platform takes care of that for you. If the events you are responding to (whether that be HTTP requests or queue messages) are coming in thick and fast, then Azure Functions can distribute your function to hundreds of machines to keep up with the load. And once demand dries up, it scales back down again transparently.

You also get to reap the benefits that microservices offer, such as greater freedom to be technology agnostic. I can create a mix of functions in C#, Python and F# if I want. They're small enough that I can throw one away and rewrite it in an afternoon if it is causing issues.

It also makes it effortless to adhere to the single responsibility principle. How often do you see an extra endpoint stitched onto an ASP.NET web API project that it doesn't really belong in simply because that saves us from deploying a separate web app? Similarly with queues. You often see several unrelated queue listeners batched together purely for cost saving reasons or ease of deployment. With Azure Functions those concerns go away, and it is no trouble at all to create a brand new function for every event you need to handle, each one completely decoupled from the others and scalable independently.

Finally, serverless architectures are not an all or nothing proposition. You could take a monolithic architecture with an Iaas backend, and quite easily move certain capabilities out into Azure functions to benefit from serverless in the places where it makes the most sense. I'm currently experimenting with this approach in some of my own cloud deployed projects.

What’s the Catch?

So serverless sounds great! Are there any downsides? Of course there are! Every new paradigm solves a bunch of the old problems, but introduces a few new ones in their place. And there are two main drawbacks that come to mind for me.

First, there is the complexity in the interactions between pieces. Yes, each function is small and simple on its own. But lots of small simple bits connected together in complicated ways can result in a system that is hard to understand. At the very least you'd need some good diagrams to visualize the way different messages and events propagate through the system.

And second, even though it's "serverless", there still are servers. And they can go down. Last week Azure had two serious outages. And third party services like Auth0 and SendGrid are bound to have their own issues from time to time. So although you won't have to remote desktop into servers yourself and troubleshoot them, for each service you rely on, you'll need to know how to get at their logs and service status, and possibly design a fallback mode of operation so your system can carry on anyway.

So serverless is of course not a silver bullet. But it does have a lot going for it. And it's inspiring a lot of creative innovation which is great to see.

Anyway, I'd love to read in the comments what you all think. Is it a fad that will be forgotten in a year or two? Or is it the next big thing? Are you doing this already? How’s it working out?

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.


I get quite a lot of questions about how to render audio waveforms with NAudio and although there are a few examples of doing exactly this in the NAudio demo projects, I didn’t have a demo that takes an audio file and creates a PNG of the waveform. This can be especially useful if you are wanting to create server-side waveforms in a web application.

So I’ve decided to open source a little utility I created a while ago for doing just that. You give it the path of the file, and it uses NAudio’s AudioFileReader class to read out the samples so it can support a wide range of input formats. Then there are lots of customization options for how the peaks are generated and what the waveform will look like.

Customization options include:

  • Supports several peak calculation strategies (max, average, sampled, RMS, decibels)
  • Supports different colours or gradients for the top and bottom half
  • Supports different sizes for top and bottom half
  • Overall image size and background can be customized
  • Transparent backgrounds
  • Support for SoundCloud style bars
  • Several built-in rendering styles

Test Harness App

It comes with a built-in test harness app makes it easy to experiment with the various rendering options and save the results as a PNG.

Test Harness UI

Example Waveforms

Basic solid colour waveform

Basic solid color


Gradient vertical bars (old SoundCloud style)

Gradient vertical bars


Blocks (SoundCloud style)



Orange Blocks


Transparent Backgrounds

Transparent Background


Transparent Background

You can check out all the source code on GitHub

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.