Skip to content

Instantly share code, notes, and snippets.

@okonet
Created January 29, 2020 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save okonet/b374454a70ca2fed5d236b6b5b8036df to your computer and use it in GitHub Desktop.
Save okonet/b374454a70ca2fed5d236b6b5b8036df to your computer and use it in GitHub Desktop.
Mixins to handle focus ring in CSS-in-JS
import "focus-visible"; // :focus-visible polyfill
import { darken, transparentize } from "polished";
/**
* Mixin to generate consistent box-shadow rule for focus rings and selections
*/
export function focusBoxShadow(color, hasInset = false) {
return {
boxShadow: `
0 0 0 0.2em ${transparentize(0.75, color)}
${hasInset ? `, 0 0 0 1px ${color} inset` : ""}
`,
};
}
/**
* Mixin to add an alternative focus ring to interactive elements.
* It removes the default focus outline.
*
* @example
* styled.div`
* &:focus {
* ${focusRingStyles('red')}
* }
* `
*/
export function focusRingStyles(color, disabled = false) {
if (disabled) {
return {
outline: "none",
};
}
return {
outline: "none",
borderColor: darken(0.1, color),
transition: "box-shadow .125s",
...focusBoxShadow(color),
};
}
export function focusRing(color, disabled = false, hover = false) {
const baseStyles = {
".js-focus-visible &:focus:not(.focus-visible)": {
outline: 0,
},
"&.focus-visible": focusRingStyles(color, disabled),
};
if (hover) {
return {
...baseStyles,
"&:hover:not(:disabled)": focusRingStyles(color, disabled),
};
}
return baseStyles;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment