In my design, I want to remove the outline ring on an input
element when it's focused via mouse interaction but still keep it visible when focused using the keyboard.
This similar question was raised about a week ago here, unfortunately with no solution provided.
However, my scenario has some nuances.
Input HTML:
<form class="custom-form">
<label class="custom-label" for="my-input">
<span>My Input</span>
<input id="my-input" class="custom-input" name="my-input" type="number" min="0" max="100" value="00.00" step="1.00" required
aria-valuemin="0" aria-valuemax="100" aria-required="true" aria-invalid="false">
</label>
</form>
Input TailwindCSS:
.custom-form {
@apply flex flex-row;
}
.custom-form .custom-label {
@apply flex flex-col space-y-1;
}
.custom-form .custom-label > span {
@apply pl-1;
}
.custom-form .custom-input {
@apply max-w-[100px];
@apply mr-2 px-1 py-[3px];
@apply text-base;
@apply border rounded border-gray-200 dark:border-neutral-600 focus:border-neutral-600 dark:focus:border-neutral-100;
@apply outline-none;
/*@apply focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
@apply focus-visible:outline-neutral-600 dark:focus-visible:outline-neutral-100;*/
@apply bg-neutral-100 dark:bg-neutral-700;
@apply transition-all duration-75;
}
.custom-form input[type=number].custom-input {
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
I've already set up a border
on the focus
state following W3's Relationship to Non-text Contrast Success Criterion.
This same focus style is implemented across my other UI elements, yet they maintain the outline ring when navigated with the keyboard.
For example:
Button HTML:
<button class="custom-button">
Button
</button>
Button TailwindCSS:
.custom-button {
@apply px-3 py-1 rounded;
@apply bg-neutral-100 hover:bg-neutral-200 active:bg-neutral-300;
@apply dark:bg-neutral-900 dark:hover:bg-neutral-700 dark:active:bg-neutral-600;
@apply border border-gray-200 dark:border-neutral-600;
@apply focus:border-neutral-600 dark:focus:border-neutral-100;
@apply focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
@apply focus-visible:outline-outline-light dark:focus-visible:outline-outline-dark;
@apply transition-all duration-75;
}
Essentially, I aim to achieve the same styling behavior of the button
on the input
element.
Practical and viable alternatives:
- Omit outlining rings entirely and solely rely on
border
styling throughfocus
state.
Though feasible, I prefer keeping the outline for quick keyboard navigation.
- Add outlines to other UI elements as needed.
Outlining everything necessitates additional spacing to prevent overlap and detracts from the minimalist aesthetic I'm aiming for.
- Set the default outline to
none
in CSS and utilize a JavaScriptTab
key listener on eachinput
element. When an element gains focus this way, "enable" the outline.
I could consider this last option as a final resort, but I'm unsure of the performance implications, given there are around a dozen input
fields per form at most.
Can the behavior of :focus-visible
be modified at all? It seems browsers handle this differently based on what I've read.