fresh
fresh copied to clipboard
twind integration with islands does not always work
Hi,
I'm having an issue where, if a page contain a tailwind class hidden sm:block
on an element and the page also contain an island that also uses the hidden with a media query like hidden md:block
, on a different element, Then the element on the outer page will be always hidden.
If i remove the island, the hidden behavior of the page element is correct.
I'm using twind similar to the doc section example
// client_deps.ts
import { apply, setup, tw } from "https://esm.sh/[email protected]";
export { apply, setup, tw };
if (IS_BROWSER) {
setup({});
}
Repro at https://github.com/sylc/repro_fresh_hidden_mq
With the current integration, the styles are first rendered on the server and then set in a style tag with id ____FRSH_STYLE
.
When the island render on the client, with the setup mentioned in previous comment, a new stylesheet is created with a id of __twind
. The new stylesheet is altering the order of precedence of the style definitions expected for twind to work.
It seems that the solution would be to hydrate twind with existing styles, but I haven't been able to get this to work.
My current work around is to enable the hash option in the browser so the 2 stylesheets styles names don't conflict. eg:
if (IS_BROWSER) {
setup({ hash: true });
}
no great to develop/debug in the browser, but does the work
I'll look into this. Ideally the browser twind
would also render into the __FRSH_STYLE
style tag (but maybe not directly.
diff --git a/client_deps.ts b/client_deps.ts
index a6818ab..0d9257d 100644
--- a/client_deps.ts
+++ b/client_deps.ts
@@ -1,8 +1,9 @@
export * from "https://raw.githubusercontent.com/lucacasonato/fresh/main/runtime.ts";
import { IS_BROWSER } from "https://raw.githubusercontent.com/lucacasonato/fresh/main/runtime.ts";
-import { apply, setup, tw } from "https://esm.sh/[email protected]";
+import { apply, cssomSheet, setup, tw } from "https://esm.sh/[email protected]";
export { apply, setup, tw };
if (IS_BROWSER) {
- setup({});
+ const styleEl = document.getElementById("__FRSH_STYLE") as HTMLStyleElement;
+ setup({ sheet: cssomSheet({ target: styleEl.sheet! }) });
}
This works for me.
thanks for looking into this. This does not work on my reproduction repo https://github.com/sylc/repro_fresh_hidden_mq.
This make twind push its styles into the "__FRSH_STYLE". but twind is not aware of the styles that are already there and so add them as duplicate after the existing ones, which does not comply with the order of styles required for twind to work.
@sylc Insanely hacky fix: https://github.com/denoland/dotland/pull/2214. I will address this properly soon.
@sylc Insanely hacky fix: denoland/dotland#2214. I will address this properly soon.
that's great! I tested the fix on my sample repro and it is working fine.
Thanks, @lucacasonato for the great stuff you've done on custom render function support and integrating the twind library as a built-in example!
One of the great things about twind is (quote from their main page):
Unlimited styles and variants for one low fixed cost of ~13kB.
Per my understanding, if the custom render function (which runs on the server) calls the twind compiler and then attaches the generated class definitions as part of the HTML response (inside a style tag), we could potentially have a new chunk-size problem for devices with slow network or a cost problem for the service developer.
Why? If pages in the app are complex in styling but also share a lot of styling between them (which probably is the case for many apps, to have a consistent UI), the (potentially huge) style tag would be passed on the wire for every page for every user.
So the great advantage of ~13KB fixed amount of code the user needs to download to get styling, is gone.
Ideally, if twind will only run on the client, the final HTML from the server will only include the CSS class names (but no CSS implementations), which means the chunks are small again. In addition, per my understanding, the issue here raised by @sylc will be also solved.
I'm not familiar enough with fresh/twind to understand whether I'm talking nonsense here. So would appreciate your response :)
this has been fixed by the new twind plugin.