Skip to content


Visible password toggle with CSS and JS

Password fields usually mask their content, but is that really good UX?

UX challenges of password fields

  • User ‘loses their place’ forcing them to start entering the password again.
  • Password hard to type or complex, no visual guide to text being entered.
  • Difficulty in paste a password from elsewhere.
  • Difficult to visually check validity of password before submitting.
  • Hard to copy password elsewhere before submitting.

Technical solution

An increasingly common pattern is to allow the user to toggle the visibility of the password field content, which has a number of accessibility benefits.

Screenshot of form with regular password field
Regular password field.

Following progressive enhancement we can do this simply in JavaScript, however there are a few things to consider:


  1. Many users have password manager add-ons—such as LastPass—which may adapt the display of password fields, so we have to be careful when it comes to styling the field itself.
  2. Changing the field <input type="password" ...> to text in JavaScript is simple enough, but it may confuse password managers (even those built into a browser) and irritate users (because their password manager is now broken…).
  3. There’s a possibility that the browser could cache or save the state of the field in plain text, which would be a Bad Thing.
Screenshot of password field with its content being displayed.
Password field with content revealed.

Taking point 2, we can be a little smarter about how we handle form submits and ensure we only ever submit password fields, regardless of a toggled display state. This prevents point 3.

By placing the toggle outside of the password field, we can avoid most visual clashes with add-ons or password managers, covering point 1.

The are downsides to this solution: The user has to have JavaScript enable for start, which you cannot guarantee (but thanks to progressive enhancement, the form will still work). Secondly, it’s still possible for password managers to do strange things to the form fields which cannot be accounted for.

A CodePen demonstrating this technique can be found here.

Responsive modal dialogs

Screenshot of modal dialog masking content
Modal window with full-viewport mask

A super simple responsive modal window with minimal JavaScript.

  • Mobile friendly (mobile first, natch!), fills the viewport on mobiles
  • Keyboard navigable
  • Marked up for accessibility
  • Masks the content on desktop

Particular attention here on the accessible aspects of modal markup: aria-labeledby, aria-describedby and the toggling of aria-hidden on show/hide.

Basic modal markup with these aria properties:

<div class="modal"

Then matching elements inside the modal itself:

<h2 id="modal-label">
 My modal title
<p id="modal-description">Modal description</p>
Screenshot of modal dialog filling viewport
Fills viewport on smaller devices

A demo can be found on CodePen.

Using flex to change element display order

Here’s a dead simple trick for creating alternating boxes (flipping the order of element display) in CSS with display: flex. Each pair of boxes is wrapped in a div with flex applied. We can then select every odd wrapper and change the order of the content.

.inner:nth-child(odd) {
 .box--box1 {
   order: 1;
Screenshot of boxes before ordering
Before order
Screenshot of alternating boxes
After ordering

See the it in action at CodePen.

Scaling content with CSS vw units

Screenshot of desktop with content scaled
Desktop with scaled content

While experimenting with a new Pattern Library based workflow and I put together something to play with scaling content based on css vw units (viewport width) and full-page splashy design.

All it takes is…

font-size: 10vw;

…and the browser will calculate the size on the fly. There are 4 related properties, vh, vw, vmin, and vmax which can be used to scale most content base don the dimensions of the browser viewport. These units are percentage of viewport size, so 10vw == 10% of the viewport width.

  • vh = % of viewport height
  • vw = % of viewport width
  • vmin= whichever of vh or vw has the smaller size*
  • vmax= whichever of vh or vw has the larger size*

* As of Jan 2017, Microsoft Edge browser doesn’t support vmax, but you are safe to use vh/vw in all modern browsers

You can see the page in action here: or check out the source on GitHub here: spacegirl-patternlibrary.

Menu positioning

Screenshot of mobile first design
Mobile menu

This bare bones experiment also deliberately puts the navigation elements at the bottom of the page on mobile—in theory closer to the users thumb. This was sparked from a discussion at the studio this week over mobile menus. The ubiquitous hamburger menu feels increasingly unwieldy UX as we become more attached to our mobile devices, especially phones. The thumb reach from the bottom of an iPhone 7 Plus to the top right corner (traditionally where the burger menu resides) is a stretch for me. A struggle for folks with smaller hands, which could results in phone-fumble annoyance. There are solutions—more app-like behaviour (think iOS apps, icon bars), tile menus, InstaGram style slide-in/out menus to name a few—but there’s the risk of user confusion. People are used to burger menus, even if they don’t have the most elegant UX. Food for thought (hmm, burgers).


Mobile-first responsive tables with CSS

Here’s a rehash of an experiment I did a while back with responsive tables. The goal is to make style a table ‘truly’ mobile first, while maintaining semantic HTML.


The initial demo was using min-width to handle the breakpoint which resulted in overly complicated CSS. This second demo reworks the CSS to use a max-width based breakpoint instead. It allows the table to naturally return to a table-like layout after the breakpoint is hit.

Screenshot of mobile first table
Mobile first (max-width)
Screenshot of desktop table (using max-width)

Updated demo (CodePen):


Original demo

Starting with mobile, we unwrap the HTML, turning each of the table elements into blocks that we can easily position.

We use the a data-attribute on <th> cells in the table body as hidden content for smaller screens (the default view as we’re mobile-first).

Screenshot of mobile-first table
Mobile first

On desktop, we use a breakpoint to give the table HTML elements back their proper display property values and hide our hidden content (data-attribute) titles. Our friends here are:

display: table-header-group;
display: table-row-group
display: table-row;
display: table-cell;
Screenshot of desktop table
Desktop table

A CodePen can be found here (resize your browser to see the responsiveness).

Custom checkboxes with CSS

Along similar lines to this post on radio controls in forms, we can simply style checkboxes by using :after or :before pseudo-elements on the controls label.


 <input type="checkbox" class="form__checkbox" id="checkbox1" />
 <label for="checkbox1" class="my-label">Checkbox 1</label>


 &:checked + .my-label:before {
   // the on styling for the box, using a url for a tick
   content: url( ... );

.my-label {
 &:before {
  // The 'unchecked' styling for the box
Screenshot of unchecked checkbox demo
Unchecked checkboxes
Screenshot of checked checkbox demo
Checked checkbox

See it in action with this CodePen demo.

Custom radio buttons with CSS

Using a combination of :after and :before selectors on the controls <label> to position pseudo-elements over the real form control.

This selector lets us use the :checked state of the element to apply a style to the controls label:

  // SCSS
  .checkbox:checked + .checkbox-label:after {
    // ... adds a 'spot' to indicate checked status

We then also need to make sure we handle focus on the control so that our fancy styling can also indicate state on keyboard navigation:

  // SCSS
  .checkbox:focus + .checkbox-label:before{
    // ... add some styling to indicate focus/keyboard nav

Here’s a demo of solution on CodePen

Customise radio buttons with only CSS

Dev notes

I’m not a huge fan of heavily customised form elements due to the huge variety of implementations of form controls on different devices. For example, how <select> elements are handled on mobile vs. desktop. Avoid the pain of trying to fix countless display bugs and keep your form customisation as simple as possible.

Animated CSS reveal on page load

I’m still playing with animations on page load and put together a little demo and some notes.

What do we want to animate?

@keyframes fadeinanimation {
  from {
    opacity: 0;
  to {
    opacity: 1;

Now we can apply the animation to our elements (the .fadein class):

  .fadedin {
    opacity: 0;
    animation: fadeinanimation ease-in 1;
    animation-fill-mode: forwards;
    animation-duration: 1s;
    animation-delay: .2s;

See it in action: