Latest blog posts

How to make responsive Likert scales in CSS (like Qualtrics)

At work I’ve been updating many forms to be responsive and work on mobile. This is not as exciting as it sounds - but like any boring but necessary task, there is fun to be had searching for an optimal solution. Psychology is just full of forms and surveys which contain Likert scales, so I came up with the below solution based on radio input elements, for future projects, and it works very nicely. I design with following criteria in mind:

  • Responsive, so horizontal for desktop / tablet, vertical for mobile.
  • Uniform element sizing - it’s important that buttons are not bigger for some than other, as that might introduce bias.
  • Accessible - should allow browser shortcuts and using clear design to indicate the various states of the scale’s buttons.
  • Should never resize to something crazy and unreadable.

Bonus features:

  • Input elements are inside label so no ‘id’ or ‘for’ attributes
  • Stays centered when on mobile but sticks to the left on desktop (but can be centered too, by using 'grid' instead of 'inline-grid').
  • Number of rows can be set by CSS variable, in style attribute.

I looked at both flexbox and grid solutions, I used this great guide to grid to experiment a lot as well as this article on container queries which led me to a near solution with flex: the so called Flexbox Holy Albatross. This was close to the final solution bar one issue: in the vertical arrangement, if the content of one box was bigger than the others, then it wouldn't adjust the sizes of all the boxes, leaving one bigger than the others. In the end I could see no way of getting this behaviour without specifying the number of columns somewhere in the css.

The other downside to this approach is that it relies on media queries, meaning that the scale won't behave as well in situations where it has variable widths. E.g. The media query I have specified works well in my full page setup but I had to add an extra media query for it's display on my front page.

The Flexbox Holy Albatross would eliminate this downside, but I would have to then fix row heights, which in my case is less achievable as the contents of the likert's are unknown, but the width of the container is.

Final setup:

It uses grid under the hood, and a single media query, which switches the orientation when the viewport width goes below 680px. It uses outline as well as background shade to indicate selection, which is important for colour vision deficiencies. I choose this way rather than say indicating selection with dark background and light colour because in binary choices it might not be clear which was selected. The inputs are hidden with opacity, which means that you can still use keyboard shortcuts to navigate the form, and switch them with arrow keys. It recreates the standard blue focus outline too (black when selected but not focusd, important for keyboard users.

It is basically everything you could ever want in a Likert scale.

Source code


<div class="likert">
    <label><input name="l" type="radio" value="1"/><span>I don’t like it at all</span></label>
    <label><input name="l" type="radio" value="2"/><span>I don’t like it</span></label>
    <label><input name="l" type="radio" value="3"/><span>I am indifferent</span></label>
    <label><input name="l" type="radio" value="4"/><span>I like it</span></label>
    <label><input name="l" type="radio" value="5"/><span>I like it a lot</span></label>


Not all likert scales have 5 elements, you can add a variable on the likert element's style attribute e.g. style="--likert-rows:6", to change the elements. I was unable to keep the likert buttons the same size using either grid or flex, whilst still not specifying the number of rows somewhere. It would be great in the future to do this with attr() - but I couldn't get it to work.

I was also tempted to put all the colours as variables in the main likert class, to make them easy to tweak and override as a batch - but it didn't feel necessary in the end, I kept it simple.

    .likert {
        --likert-rows: 5;
        display: inline-grid;
        max-width: 900px;
        grid-auto-rows: 1fr;
        gap: 1em;
        grid-template-columns: repeat(var(--likert-rows), minmax(0, 1fr));

    @media only screen and (max-width: 680px) {
        .likert {
            grid-template-columns: minmax(0, 400px);
            justify-content: center;

    .likert input {
        max-width: 250px;
        position: fixed;
        opacity: 0;
        pointer-events: none;

    .likert span {
        border-radius: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        padding: 20px;
        background: #dcdcdc;
        transition: background .2s ease-in-out;

    .likert input:checked + span {
        outline: black auto 1px;
        background: transparent;

    .likert input:focus + span {
        outline: -webkit-focus-ring-color auto 1px;

    .likert span:hover {
        background: #f1f1f1;
        outline: lightgrey auto 0.5px;

Presenting half finished projects for feedback

In my job, I tend to work as a sole developer, and quite often in a project there comes a stage where I need feedback on a specific feature, before the rest of the project is in a presentable state. When working on something tricky I will disable other functionality, add placeholders and special links to reach that feature (kind of like scaffolding in a building site), so I can try out different approaches. This could be something that getting locked down asap is important before investing time building the rest of the project. Often these are things which I cannot just rely on my own intuition about design to get right.

So typically after finding a solution I like, I would set up and share a development release, and ask for some feedback and a discussion.

However, sometimes when people see their whole project for the first time in this unfinished state it can be quite disappointing and confusing. This is the case even in early stages when there is plenty of time to go, and even with warning that it is unfinished. People want to see their idea in an embryonic state, but beautiful, not a jumbled ugly mess.

This problem is compounded because tidying up a design and visual considerations typically come later on. I think most people will imagine the project gets built like a puzzle with nicely finished parts just being wired up together, but the reality is more like building a Frankenstein monster where you start with bones, add the organs, muscles etc, and the skin and fancy outfit only comes at the end.

Initially I felt uncomfortable with the idea of 'hiding' the unfinished aspects, for some reason it seemed like it could be misleading. But the reality was that to the uninformed, half finished projects are just as misleading, or rather confusing, and it can even prevent proper attention being given to what's needed. So now, I treat projects like a building site, and so take stakeholders on much more carefully prepared, guided tours. Development releases now come later when there is actual testing to do, and early ideas are shared with wireframes, videos or shared screen tours . Here are some cute vintage work in progress animated gifs to lighten the appearance of unfinished areas of a project!

Home garden office - Self build - Part 1

We are having a baby soon! That and the likelihood that I will continue to need a room to work from home, we decided that it was worth looking at getting a garden office, if it can be done within a budget. Both pre-made off-the-shelf buildings, and custom built ones are quite pricey. If we are talking about something insulated with electrics, windows, doors all set up and built, the cheapest I have found is > £12000. Self build however I am managing to squeeze everything in at £4500, a huge saving. It's an undertaking I'm heading into somewhat blindly as I don't personally know anyone who has built anything like this - but I'm pretty optimistic now I've done my research. I have been inspired by similar projects here and here.

The plot

The plot of land has space for roughly 12 by 8 feet building. I will need to move some raised beds which are there and probably cut back a bit of the cedar tree that is overhanging the area. In the photo I have laid out tape measures to give a rough look at the size.

Back garden plot of land

Design stage

It’s taken a lot of time to research all of the sensible options, but I finally settled on some initial design decisions, together with rough costs:

  • Foundations: Ground screws = £900
  • Structure: SIPS ≈ £1300
  • Roof: EPMD (Rubber roof) = £235
  • Windows / Doors: Black PVC ≈ £1200
  • Cladding: Cedar ≈ £750

Extra costs I've factored in such as housewrap, tools etc should be < £200. These are not the absolute cheapest options (e.g. cedar cladding is not cheap) - but they seem to go well together in other buildings I’ve seen. I will be spending a good deal of time trying to see if I can save money on the cladding and windows on ebay...

I made a mockup of the building in sketch up, I'm not actually sure how useful this will be at the building stage, but it was helpful as an activity consolidating my thoughts on everything.

Sketchup design of office


Deciding on the foundations took the longest amount of research. The most expensive but most permanent and stable foundation, would be the concrete slab: First you dig a hole, fill it with hardcore and sand, compact it then lay a nice flat layer of concrete over the top, covering the entire area of the building. Another advantage of this is that it can double as the floor itself. A variation of this would be to tile the area with paving slabs. Both the above options require a lot of cement, and the expertise with it, but likely would produce the most professional results - the costs looked double or more for the others on first glance, so I ruled them out fairly on.

The cheapest and most DIY seemed to be pad or plinth foundations, which involves digging a number of holes, filling with hardcore and sand and mortaring cinderblocks to provide a level framework of blocks to lay the floor on. This seems to require a fair amount time and effort, but costs very little, and apart from some difficulty getting the blocks level, seemed straightforward. I found many youtube videos (e.g. demonstrating how to do it, however for my particular plot with clay and trees surrounding, I was a little worried that it might not be as permanent as I would like, however it was my fallback option. My plan was to seek further advice if I couldn’t use ground screws.

Ground-screws are massive screws that go into the ground and hold the building above the ground. They can be done diy (which would make them the cheapest option), but you’d have to be pretty sure you wouldn't hit any rock, I’m planning on going with a local company to install mine, apart from the electrics, it should be the only outside help I will received on site. After laying the ground-screws its best to cover the rest of the soil with weed membrane at the very least, to protect the underside of the building.


The other major decision came about when I learnt about SIPS. When I began the project I was imagining that I would be building everything from timber frames. This would involve a lot of precise cutting and measuring, filling with insulation etc - which I was fully prepared to do until I discovered SIPS. SIPS meaning structural insulated panels, are a kind of more like modern building lego. You buy a bunch of SIPS panels cut them and join them together and you have a building. Again, it costs more than the traditional way, but not by much. I estimated I will be spending £400 to gain probably 4 full days of work or more (not counting all the mistakes I am likely to make, and the extra time planning). The other major benefit of SIPS is that they are typically much better insulated than timber frame, the insulation spans the whole panel so there are no gaps where the beams would be.

Other design decisions

The rest came about from browsing for other sheds, and although I noticed some really nice rustic looking buildings with reclaimed wood, it looked like a lot more work to actually source the materials, and having no experience in designing with these materials (or any materials), I felt it would run the risk of just looking bad. Better to go with something I can copy more easily! There are many nice looking cheap cladding and roofing options, but I decided to go with the trend of having cedar cladding with black/grey fittings and rubber roof. I haven’t really looked too much into shed felt, as I like the look of it less than the EPMD. I think the difference in cost is minimal, but from what I’ve gathered it’s slightly more tricky to put the rubber roof on, but I think it looks pretty good with the PVC. I originally wanted wooden doors/windows, but I haven’t found any thus far that are near as cheap as the PVC.

Next steps...

Next is pulling the trigger, and ordering everything and building it! Baby is due in roughly one month, and my aim will be to begin building a month after that. I will be switching to a 4 day week after baby is born, meaning I should have a few spare afternoons per week to work on it.

My new semi-static website and blog

Inspired by this and this (both sourced from Adactio’s website who I sometimes play irish folk music with!) I spent some of my christmas holiday redoing my personal website and blog. It used to be a minimal effort wordpress 'jobby' with an off the shelf theme, and a number of plugins to do things that would take me 10 minutes to do in raw html. Whilst Wordpress is an incredible piece of software, I got annoyed by a number of things: the spam, the loading times, the visual clutter, constantly having to update, the vague sense of being bombarded by bots looking to hack the site and the incessant spam. So I decided to make my blog again without any frameworks. The benefits of not using are framework for me are:

  • It is much less likely that security flaws in the framework can be used to access my site. Attackers would have to target me specifically.
  • I have full knowledge and control over the whole site
  • I have no unused features adding complexity
  • I never have to update, things will never be obsolete, and I never have to look at documentation.

I wanted something that loads fast, not necessarily fully static - and I wanted a straightforward way of writing articles (and seeing how they look as they are written).
I call it semi-static because there is no database, or write changes on the live server, but it's not just pure html. I settled on the following guidelines:

  • Proper semantic HTML, with an aim to minimise nested elements
  • No js requirement for full access to site
  • No database
  • Accessibility
  • No frameworks (Compiled and mature PHP modules allowed)
  • No templating other than what PHP offers
  • Use of new CSS features that I hadn’t had much practice with
  • Homemade local/offline CMS with articles written in html or md
  • Continuous-ish integration

PHP is often maligned, and I have experienced frustration with the language, untyped with frameworks such as Drupal, passing around random keyed objects, and requiring this and that everywhere. But using PHP to create this site and blog was a joy! It’s almost like PHP got promoted to its level of incompetence, when really it is the perfect language for these projects. Here are the features I most appreciated during development:

  • Built in templating: I love PHP templating, I can have code and calculations throughout a file. I find mustache etc to look nicer, but super cumbersome in comparison. Eventually all those curly brackets start to look the same too and get lost…. Native PHP templating is so convenient.
  • Mature libraries: I wanted a yaml parser and functionality to resize images on the fly for my local CMS. Both libraries were easily installed and work perfectly.
  • Workflow: I make an edit to a PHP file and I see the output instantly (see my earlier post)
Minor discoveries:

A css trick:

I wanted section and article elements that spanned 100% of the page width (for the background colour), but had content that behaved as it it were centered with a max-width.

I used calc to replicate this behaviour to do padding:

:root {
    --article-padding: calc(10px + (50% - (min(1250px, 100vw) / 2)));

A chrome bug:

I encountered this bug in chrome where having transitions set, would cause them to fire on a page load.

This can be stopped by having an empty script tag at the bottom of the site - a bit dirty, but I didn’t want to spend all evening solving this issue, (or give in and use JS).

How does site work:

If you are interested! The site is semi-static, much of the blog content exists in pre-generated files, but the pages themselves are php templates, which I edit directly. I have public directory which contains index.php, and sub directories for each page/area of the site. The pages access header and footer templates. The blog and photos areas of the site, have sub-directories with generated .inc files for full articles and snippets. These pages when loading loop through loading the required .inc files.

The articles are markdown files, with metadata as YAML in the header. I have an update script which uses the markdown filetimes to update any changes to the article, and generate new snippet/article incs, plus the articles own page.

On the dev machine, I output JS which checks to see when the last file was accessed in the whole directory structure.
If an update is detected (e.g. after saving a file in the IDE) the update script is run, and the page is reloaded.
This means I have my markdown editor in one window, and the article in a browser in another window, and as I update the article, it appears on the browser as and when I save (see here).

I push the public folder live with rsync -ru - this could be called

from the update script itself to make live changes, if say my dev server is set up with a different project and I wanted to update my site during a work break :).
The public site does not contain any file_put_contents or anything which writes to or modifies the server - I am planning on adding something like comments at some point, but will cross that bridge when I come to it. I might separate it and use something like firebase, to avoid having to deal with publicly generated content on the live server.

I love this new setup and I was thinking about releasing it low-key - but the reality is that, if you would consider using it, you would probably sooner just want to make your own!

Too much wine during lockdown?

I think he's trying to tell me I am drinking a little too much. Well, it's Christmas and it's just been 2020, what does he expect!

My white and ginger cat with tail around wine glass