twind icon indicating copy to clipboard operation
twind copied to clipboard

Can't use @apply within the project's native CSS code.

Open nimser opened this issue 3 years ago • 10 comments

At present, the apply function is only useable within javascript.

It would be great to be able to use it as a css directive @apply so that we can get access and apply all Tailwind classes within any CSS file, <style> tag of an HTML file or Svelte component, etc...

Ideas for enabling this might be to do it with a vite or postcss plugin.

nimser avatar Jan 10 '22 13:01 nimser

I'm not sure I understand, you want to use a CSS-in-JS library to instead process CSS source content?

If you're concerned about perf/bundle size, Twind supports static extraction, which is something I'm particularly fond of.

It sounds to me that what you're asking for is already handled well by the existing ecosystem around Tailwind, and wouldn't really mesh well with other Twind tools AFAIK. That moves into processing of CSS content rather than generating styles from usage.

rschristian avatar Jan 12 '22 09:01 rschristian

In my particular case, I'm making a Svelte component and want to have the ability to apply Tailwind classes to styles I've written in <style> tag of my component. Something like:

Component.svelte

<style>
    h1 {  @apply text(center 2xl) }
</style>

My understanding is that the Twind way of writing CSS rules for a component, while keeping access to apply would be to use the css Twind function as a replacement for <style></style>, and write the styles within the <script> tag of a component. I make this all sounds Svelte-specific, but this could be relevant for any HTML/JS project.

I understood from a conversation with @sastan that a separate Vite or Postcss plugin could allow using apply in CSS files (or HTML, Svelte files etc...), but I'm not entirely sure how that would work.

It may be something to explore outside Twind development though, so feel free to close this if this is not the right place to track this lack of a capability.

nimser avatar Jan 12 '22 11:01 nimser

You can use css and apply programmatically, as function calls:

  • https://twind.dev/handbook/css-in-twind.html#the-css-function
  • https://twind.dev/handbook/overwriting-styles.html#the-apply-function-recommended

...so assuming your HTML template can result in a style element with a given predictable ID (i.e. authored / hard-coded id attribute guaranteed to not create ID collisions), then you can invoke apply on the style element's innerHTML.

danielweck avatar Jan 12 '22 11:01 danielweck

Ah, scrap my comment above :) I have just re-read your post more carefully and I don't think my suggested solution / workaround would work in practice, especially from a DX perspective (e.g. "intellisense" / code completion, etc.)

danielweck avatar Jan 12 '22 11:01 danielweck

What I hope to achieve is integration with existing tooling (postcss, vite, webpack, ...) that would allow full static extraction without any config. Basically what you two (@danielweck and @rschristian) are already doing.

In my opinion, twind should be able to process existing CSS with support apply, theme, and screen.

@twind {
  h1 {
    @apply text(center 2xl);
  }
}

For svelte:

<style lang="twind">
h1 {
	@apply text(center 2xl);
}
</style>

sastan avatar Jan 12 '22 13:01 sastan

Additionally, there is no straightforward way to use shim in combination with apply without using apply function programatically.

Use case:

  • Shim used in Remix in SSR mode meaning shim is scanning classnames and generating stylesheet.
  • Stylesheet is cached and not regenerated on subsequent api calls.
  • Not using tw function works twofold
    • Twind is not shipped to client and rehydrated for no reason
    • Better copy-pastability from tailwind code means faster development instead of having to prefix all classes with tw

Proposed syntax:

  • <h1 className="apply:(text-red-400 px-2 py-4)">Hello</h1>
  • Should also work with nested groups ex. <h1 className="apply:(text-red-400 px-2 py-4 md:(text-blue-400 px-4))">Hello</h1>
  • Generates a single tw-hash class and adds it to the virtual sheet

unbiased-dev avatar Jan 25 '22 15:01 unbiased-dev

Something like that is implemented in v1.

  • inline apply: styles are generated in order they are declared
    • @(underline font-bold) -> @(underline,font-bold)
    • Link@(underline font-bold) -> Link#12345
  • inline shortcut: style are generated as defined by twind — same as if they where used alone
    • ~(underline font-bold) -> ~(underline,font-bold)
    • Link~(underline font-bold) -> Link#abcdef

from Reference

For your other suggestion — using twind within <style> — that is still on the table and a TODO for me.

sastan avatar Jan 25 '22 18:01 sastan

For your other suggestion — using twind within <style> — that is still on the table and a TODO for me.

@sastan will no doubt introduce a clean "native" Twind API to handle the <style> use case, but in the meantime this can easily be achieved in userland with Twind v1 (Work In Progress "next" version https://github.com/tw-in-js/twind/tree/next )

document.querySelectorAll('style[type~="twind/css"]').forEach((e) => {
    tw(css(e.textContent));
});

danielweck avatar Jan 25 '22 19:01 danielweck

That is an amazing idea!

sastan avatar Jan 25 '22 19:01 sastan

I ported the quick demo to https://jspm.org which works better than https://esm.codes for repros that involve markup:

Click here to open the demo

danielweck avatar Jan 25 '22 20:01 danielweck

Hey folks. This issue hasn't received any traction for 90 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it.

stale[bot] avatar Dec 19 '22 01:12 stale[bot]