Add new ring
utilities for custom focus styles and rounded outlines
#2747
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds a set of new
ring
utilities, designed to make it easier to give elements custom focus styles.Here's a quick overview of what they look like in practice:
This will render a custom focus ring (implemented with a box shadow to respect corner radius) with the following visual properties:
It looks like this:
These utilities live inside the following new core plugins:
ringWidth
, forring-2
ringOffsetWidth
, forring-offset-2
ringOffsetColor
, forring-offset-gray-900
ringColor
, forring-white
ringOpacity
, forring-opacity-50
The
ringWidth
plugin hasfocus
variants enabled by default, but the rest only haveresponsive
enabled to reduce file size. You only need to add thefocus:
prefix to theringWidth
utilities anyways.Take a look at the changes to the default config file to get a full picture of what has been added/enabled by default.
Design possibilities
This API is extremely composable and flexible and makes it very easy to create an endless number of custom focus styles without making any changes to your configuration file.
Here are some examples of different styles that are all possible with this API out of the box:
It can also be used to create border effects in situations where you want to add a border that doesn't impact the layout, for example in an avatar group like this:
Detailed implementation notes
Compatible with existing shadows
This is implemented in a way that is fully composable with the existing shadow utilities. Basically this is the CSS we generate (pseudofied to make it easier to understand):
This ensures that if an element has a regular shadow like
shadow-lg
applied to it, it's safe to apply aring
utility on top of it without overriding the original shadow.How offsets work
The actual ring shadow width is calculated dynamically by taking the desired width, and adding the width of the desired offset, like this:
How ring opacity works
Ring opacity is implemented the same way border opacity/background opacity/etc. is, using CSS variables:
Default values
If you simply apply the
ring
orfocus:ring
classes, you'll get a 3px ring using a semi-transparent blue color, very similar to theshadow-outline
class. This approach replaces theshadow-outline
class.Breaking changes
This is a very powerful feature and replaces the need for
shadow-outline
,shadow-xs
, andshadow-solid
, so those have been removed in this PR.Migrating from
shadow-outline
toring
is as trivial as doing a global find and replace sincefocus:ring
does the same thing asfocus:shadow-outline
did.I've added
opacity-5
andopacity-95
so thatshadow-xs
can be easily recreated usingring-1 ring-black ring-opacity-5
.shadow-solid
was never in a proper Tailwind release (although it is used in Tailwind UI and provided by the @tailwindcss/ui plugin) so that's not a huge deal, but it can also be recreated usingring-2 ring-current