csstailwind-csstailwind-css-4

TailwindCSS `@utility` that takes several arbitrary values


I need to write a TailwindCSS utility that takes several arbitrary values.
Specifically, I want a utility for adding a circular clip-path to an image. I was thinking about something like this:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility clipcirc-* {
  clip-path: circle(--value([percentage]) at --value([percentage]) --value([percentage]));
}
</style>

<img class="clipcirc-[40%_50%_50%]" src="https://picsum.photos/200/200">

which should then be invoked with e.g. clipcirc-[40%_50%_50%], but it doesn't work.

I worked around this apparent limitation by splitting it into 3 distinct utilities like this:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility clipcirc-radius-* {
  --clip-circ-radius: --value([percentage]);
  clip-path: circle(var(--clip-circ-radius) at var(--clip-circ-x) var(--clip-circ-y));
}
@utility clipcirc-x-* {
  --clip-circ-x: --value([percentage]);
}
@utility clipcirc-y-* {
  --clip-circ-y: --value([percentage]);
}
</style>

<img class="clipcirc-radius-[40%] clipcirc-x-[50%] clipcirc-y-[50%]" src="https://picsum.photos/200/200">

which works when invoked with clipcirc-radius-[40%] clipcirc-x-[50%] clipcirc-y-[50%].

However, I would much prefer having a single utility like the first implementation. Is there any way to accomplish this?


Solution

  • You can query the entire given value using [*], where the result will have spaces instead of _.

    clipcirc-[40%_50%_50%]
    
    --value([*]) // 40% 50% 50%
    

    The only question now is how to generate the clip-path you requested using this result.

    I believe there aren't enough options to query different values at the moment, so you need to forward the values in a format that matches the clip-path pattern from the start, so you can query them later using [*], something like this: clipcirc-[40%_at_50%_50%]

    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
    <style type="text/tailwindcss">
    @utility clipcirc-* {
      clip-path: circle(--value([*]));
    }
    </style>
    
    <img class="clipcirc-[40%_at_50%_50%]" src="https://picsum.photos/200/200">