Using "generated" class names in Tailwind under Phoenix 1.7+

Is there an inherent problem with dynamically generating tailwind class names in a component?

I wanted to make the button color configurable. This is mostly from the auto-generated core_components.ex. I only added the “color” attribute, so I could say something like <.button color="red">.

  attr :type, :string, default: nil
  attr :class, :string, default: nil
  attr :color, :string, default: "zinc"
  attr :rest, :global, include: ~w(disabled form name value)

  slot :inner_block, required: true

  def button(assigns) do
    ~H"""
    <button
      type={@type}
      class={[
        "phx-submit-loading:opacity-75 rounded-lg bg-#{@color}-900 hover:bg-#{@color}-800 py-2 px-3",
        "text-sm font-semibold leading-6 text-white active:text-white/80",
        @class
      ]}
      {@rest}
    >
      <%= render_slot(@inner_block) %>
    </button>
    """
  end

The HTML source of the page looks OK to me:

    <button class="phx-submit-loading:opacity-75 rounded-lg bg-red-900 hover:bg-red-800 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80">
  Speichern und beenden
</button>
    <button class="phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-800 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80" name="Weiter">
  Speichern
</button>

But the colors don’t show up unless they are also explicitly used somewhere else.

There is essentially the same problem with my attempt to define a component for a grid column with configurable span:

  @doc """
  Renders a grid column.
  """
  attr :span, :string, default: "1"
  slot :inner_block, required: true

  def gridcol(assigns) do
    ~H"""
    <div class={"col-span-#{@span}"}>
    <%= render_slot(@inner_block) %>
    </div>
    """
  end

The col-span seems to be ignored although the HTML source looks Ok.