csstailwind-css

How can I apply @starting-style formatting to a dialog element using only classes?


I would like to implement the following native CSS code using Tailwind CSS:

dialog {
  border: unset;
  border-radius: 1.25rem;

  &,
  &::backdrop {
    opacity: 0;
    transition: all 0.15s;
  }
  &::backdrop {
    background-color: black;
  }
  
  /* Open */
  opacity: 1;
  &::backdrop {
    opacity: 0.5;
  }

  /* Close */
  @starting-style {
    &,
    &::backdrop {
      opacity: 0;
    }
  }
}
<button commandfor="my-dialog" command="show-modal">Open Dialog</button>

<dialog id="my-dialog">
  <p>Hello World</p>
  <button commandfor="my-dialog" command="close">Close</button>
</dialog>

But by default, I can only do it in CSS using the at-rule.

dialog {
  /* Close */
  @starting-style {
    &,
    &::backdrop {
      opacity: 0;
    }
  }
}
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

<button
  commandfor="my-dialog" command="show-modal"
  class="py-1 px-2 rounded-md bg-sky-500 text-white"
>Open Dialog</button>

<dialog
  id="my-dialog"
  class="
    opacity-100 [::backdrop]:opacity-50 [&,&::backdrop]:transition-all [&,&::backdrop]:duration-300
    fixed top-1/2 left-1/2 -translate-1/2
    space-y-2 py-2 px-4 rounded-lg [::backdrop]:bg-black
  "
>
  <p>Hello World</p>
  <button
    commandfor="my-dialog" command="close"
    class="py-1 px-2 rounded-md bg-sky-500 text-white"
  >Close</button>
</dialog>

But I don't want to use CSS.


Solution

  • With the @custom-variant directive, can add a @starting-style variant that allows us to declare the styling purely as a class name, without writing direct CSS.

    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
    <style type="text/tailwindcss">
    @custom-variant @starting-style {
      @starting-style {
        @slot;
      }
    }
    </style>
    
    <button
      commandfor="my-dialog" command="show-modal"
      class="py-1 px-2 rounded-md bg-sky-500 text-white"
    >Open Dialog</button>
    
    <dialog
      id="my-dialog"
      class="
        @starting-style:[&,&::backdrop]:opacity-0
        opacity-100 [::backdrop]:opacity-50 [&,&::backdrop]:transition-all [&,&::backdrop]:duration-300
        fixed top-1/2 left-1/2 -translate-1/2
        space-y-2 py-2 px-4 rounded-lg [::backdrop]:bg-black
      "
    >
      <p>Hello World</p>
      <button
        commandfor="my-dialog" command="close"
        class="py-1 px-2 rounded-md bg-sky-500 text-white"
      >Close</button>
    </dialog>

    Note: It's important to note, however, that the @starting-style at-rule is part of the 2024 baseline. Therefore, alongside the default minimum browser support defined by TailwindCSS, you must also take into account the minimum browser versions required for @starting-style support.