diff --git a/less/common/mixins.less b/less/common/mixins.less index 716edaed9a..af6c77ec65 100644 --- a/less/common/mixins.less +++ b/less/common/mixins.less @@ -1,3 +1,4 @@ +@import "mixins/accessibility.less"; @import "mixins/border-radius.less"; @import "mixins/clearfix.less"; @import "mixins/light-contents.less"; diff --git a/less/common/mixins/accessibility.less b/less/common/mixins/accessibility.less new file mode 100644 index 0000000000..cf35f08f96 --- /dev/null +++ b/less/common/mixins/accessibility.less @@ -0,0 +1,100 @@ +// This mixin should **only** be used in this file. If you want to define your own +// custom outline style(s), override this mixin in your own theme extension, or in +// the Custom Less section of the Admin dashboard. +#private { + .__focus-ring-styles() { + // This uses the browser's default outline styles, rather than + // using custom ones, which could introduce more issues + + // Source: https://css-tricks.com/copy-the-browsers-native-focus-styles + outline: 5px auto Highlight; + outline: 5px auto -webkit-focus-ring-color; + } +} + +/** + * Adds a focus ring to an element. + * + * This is only shown when focus is provided via keyboard, using the + * `:focus-visible` selector, and `:-moz-focusring` for older Firefox. + */ +.add-keyboard-focus-ring() { + // We need to declare these separately, otherwise + // browsers will ignore `:focus-visible` as they + // don't understand `:-moz-focusring` + + // These are the keyboard-only versions of :focus + &:-moz-focusring { + #private.__focus-ring-styles(); + } + + &:focus-visible { + #private.__focus-ring-styles(); + } +} + +/** + * This mixin allows support for a custom focus + * selector to be supplied. + * + * For example... + * + *? button { .addKeyboardFocusRing(":focus-within") } + * becomes + *? button:focus-within { } + * + * AND + * + *? button { .addKeyboardFocusRing(" :focus-within") } + * becomes + *? button :focus-within { } + */ +.add-keyboard-focus-ring(@customFocusSelector) { + @realFocusSelector: ~"@{customFocusSelector}"; + + &@{realFocusSelector} { + #private.__focus-ring-styles(); + } +} + +/** + * Allows an offset to be supplied for an a11y + * outline. + * + * Useful for elements whose content is right up + * against their bounds. + * + * `.addKeyboardFocusRingOffset(2px)` will add an + * offset of 2 pixels to the outline. + */ +.add-keyboard-focus-ring-offset(@offset) { + .offset() { + outline-offset: @offset; + } + + &:-moz-focusring { + .offset(); + } + &:focus-visible { + .offset(); + } +} + +/** + * Allows an offset to be supplied for an a11y + * outline. + * + * Useful for elements whose content is right up + * against their bounds. + */ +.add-keyboard-focus-ring-offset(@customSelector, @offset) { + .offset() { + outline-offset: @offset; + } + + @realFocusSelector: ~"@{customFocusSelector}"; + + &@{realFocusSelector} { + .offset(); + } +}