Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save NickColley/791d084ff263786acb433ed0bd13c381 to your computer and use it in GitHub Desktop.
Save NickColley/791d084ff263786acb433ed0bd13c381 to your computer and use it in GitHub Desktop.
Sass mixins to help people implement focus styles

Sass mixins to help people implement focus styles

Overview of mixins

Sass is an extension language for CSS, it adds features to make maintaining large CSS codebases easier.

One feature in Sass is mixins.

“Some things in CSS are a bit tedious to write, especially with CSS3 and the many vendor prefixes that exist. A mixin lets you make groups of CSS declarations that you want to reuse throughout your site.”

In our case we have a group of CSS declarations for our focus style that we want others to reuse.

Here is an example of the Sass needed for things that look like links:

// When colours are overridden, for example when users have a dark mode,
// backgrounds and box-shadows disappear, so we need to ensure there's a
// transparent outline which will be set to a visible colour.
// Since Internet Explorer 8 does not support box-shadow, we want to force the user-agent outlines

@include govuk-not-ie8 {
  outline: $govuk-focus-width solid transparent;
  outline-offset: 0;
}
color: $govuk-focus-text-colour;
background-color: $govuk-focus-colour;

// sass-lint:disable indentation
box-shadow: -5px -1px 0 1px $govuk-focus-colour,
             5px -1px 0 1px $govuk-focus-colour,
            -3px 1px 0 3px $govuk-focus-text-colour,
             3px 1px 0 3px $govuk-focus-text-colour;
// sass-lint:enable indentation

// When link is focussed, hide the default underline since the
// box shadow adds the "underline"
text-decoration: none;

Our users could copy and paste this, but it will be useful for them to be able to use this as a mixin.

@mixin govuk-focusable-fill {
  // Previous CSS declarations go here...
}

Which allows them to use it in their code like this:

.link {
  @include govuk-focusable-fill;
}

Current mixins relating to focus

GOV.UK Frontend version 2.0.0 includes two mixins that help with the existing focus styles.

govuk-focusable

Provides an additional outline to clearly indicate when the target element is focussed. Used for interactive elements which themselves have some background or border, such as most form elements.

and

govuk-focusable-fill

Provides an additional outline and background colour to clearly indicate when the target element is focussed. Used for interactive text-based elements such as links.

Problems with the current approach

The :focus selector is baked into the mixin:

  • limits it's use, as not all focus states are with the simple :focus selector
.link:not(:active):focus {
  // @include govuk-focusable;

  &:focus {
    // Duplicate the declarations in the mixin, or have an additional mixin.
    color: black;
    background: yellow;
    text-decoration: none;
  }
}
  • encourages undoing or overriding css, since convention is to have mixin at the top of a declaration block
.link {
  @include govuk-focusable;

  &:hover {
    text-decoration: underline;
  }

  &:focus {
    // Setting focusable again because the mixin is not included in the right place.
    text-decoration: none;
  }
}

This is explained in more detail in 'option 1'.

Proposal

Option 1: Replace existing mixins with new focus styles

With this option we would update the existing mixins. Our release notes would explain how to review the current use of the mixins, and when to avoid using them, referencing the new guidance.

Things that look like an input:

@include govuk-focusable;

Things that look like a link:

@include govuk-focusable-fill;

Something else, you'll need to do non-text focus and use the following variables.

&:focus {
  outline: $govuk-focus-width solid $govuk-focus-colour;
  outline-offset: $govuk-focus-offset;
  box-shadow: 0 0 0 3px $govuk-focus-text-colour;
}

Pros:

  • Potentially the simplest for users, since their code will not blow up.

Cons:

[Spike] Option 1: Replace existing mixins with new focus styles

Option 2: Remove existing mixins, and include a new mixin for links only.

With the exception of links, the new focus styles are complicated enough that they can't be abstracted without edge cases.

So rather than have people uninclude uses of the more generic govuk-focusable mixin, we would remove them entirely and ask people to replace them with standard CSS with Sass variables.

We could include a new $govuk-focus-offset variable, that is used whenever a user needs to avoid using the mixins.

Things that look like a link:

@include govuk-focused-text;

Something else, you'll need to do non-text focus and use the following variables.

&:focus {
  outline: $govuk-focus-width solid $govuk-focus-colour;
  outline-offset: $govuk-focus-offset;
  box-shadow: 0 0 0 3px $govuk-focus-text-colour;
}

Pros:

  • Forces a review of focus states
  • Can't have bad mixins if mixins don't exist ;)
  • The only abstraction that exists is one we're confident is useful

Cons:

  • Requires replacing code if there are 1:1 replacements.
  • Re-implementing some focus CSS might be done incorrectly if guidance isn't clear enough.

[Spike] Options 2: Remove existing mixins, and include a new mixin for links only.

Option 3: Remove existing mixins, include new mixins for inputs, input errors and links, with no generic focus mixin.

Things that look like an input:

&:focus {
  @include govuk-focused-input;
}
&:focus {
  @include govuk-focused-input-error;
}

Things that look like a link:

&:focus {
  @include govuk-focused-fill;
}

Something else, you'll need to do non-text focus and use the following variables.

&:focus {
  outline: $govuk-focus-width solid $govuk-focus-colour;
  outline-offset: $govuk-focus-offset;
  box-shadow: 0 0 0 3px $govuk-focus-text-colour;
}

Pros:

  • Mixins are explicit for where they should used, so can't be used in the wrong circumstance

Cons:

  • Requires replacing code if there are 1:1 replacements.
  • Not clear if these abstractions are useful for other people, or just the code in GOV.UK Frontend

[Spike] Option 3: Remove existing mixins, include new mixins for inputs, input errors and links, with no generic focus mixin.

End thoughts

The new focus styles are more complicated from a design principle perspective so we wont be able to cover all bases with sass mixins.

We will be introducing new guidance on the Design System website to improve this, and is worth thinking about when considering what we do here.

@NickColley
Copy link
Author

Met with the team, and we went over the different options.

We agreed to go with option 2, but we are interested in the additional more scoped mixins in option 3 in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment