-
-
Notifications
You must be signed in to change notification settings - Fork 844
UnoCSS Support #4832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
UnoCSS Support #4832
Conversation
I would not give up hope so early. Because the current documentation website is build using Tailwind 3, I strongly suggest to use wind-3 for verification. And if the UI is still broken it would be very interesting which classes are not supported. And why. But still with the current 80% solution we should be able to make a guess about it's performance improvement. Can you run the numbers @evnchn? |
I'm using wind3 right now. I'll see the performance later. |
Testing on http://127.0.0.1:8080/documentation/section_text_elements, CPU mid-tier mobile, no network throttling. Note that the gains are going to be smaller than what we see in #4806 (comment), since the page itself is more complex. UnoCSS Runtime![]() 7092ms, of which 4885ms is UnoCSS Runtime (68.88%) Tailwind client-side JS![]() 2400ms, of which 405ms is Tailwind client-side JS So I think the idea of UnoCSS is not going to work... |
Went with the unminified version: ![]() Slow function is at https://github.com/unocss/unocss/blob/main/virtual-shared/integration/src/utils.ts#L23 User of said function is at https://github.com/unocss/unocss/blob/main/packages-presets/extractor-arbitrary-variants/src/index.ts#L15 But staring at it, I don't see anything wrong necessarily... |
So apparently UnoCSS detect the DOM changes and generate the styles on the fly by listening to the entire body, and then basically regex-ing all the way through. This is because UnoCSS supports some custom syntax such as attributify and tagify, and that would be impossible to do with just a Mutation Observer listening for class changes, I'd imagine. So I don't think we should consider the UnoCSS runtime from this point on, since the technical direction is incompatible. |
I think you can do it without the mutation observer by only using the core package (see https://unocss.dev/tools/core#usage). The Or you disable observing |
|
So, got UnoCSS working in 7d49615
|
Well, on the 4 metrics as listed #4806 (comment), I think this PR answers YES to all 4 of them. However, there is one issue: if we add classes via JavaScript, then it won't be caught by I still think perhaps I should finish up the rest of the tasks, such as fetching the Tailwind reset CSS, allow configure which UnoCSS to load (since preset-mini should be faster and lighter), as well as separating out the option in |
Want to drop some presets to keep the PR small and to avoid confusion.
Comments
Do tell me what you think! |
@evnchn I do not know any of these presets. I would suggest to only support the current Tailwind 3 classes as close as possible. If all goes well we can add other helpful / non-harmful presets in later PRs. |
From how I look at it, besides documentation, it's pretty ready. Note that |
I'd consider it done by now. It's been a ride! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When planning the upcoming 3.0 release, we thought about switching from Tailwind to UnoCSS. Therefore I started reviewing this PR to see if we want to merge it before 3.0. Here are my thoughts:
- When reloading the documentation page, the drawer randomly slides in or is shown as an overlay (like on narrow screens). It looks like the screen width isn't detected reliably.
- Why do we need to
wait(1)
in the pytest? Is it because we need to wait for UnoCSS to run? - Why do we need to set
app.config
for each page in the pytest? Shouldn't it be enought to set it once for the whole (test) app? Dark mode switching works by checking a condition 10 times per second. Is there a chance to do this more efficiently (without an interval)?Fixed in 9625a1e.- At the moment we always track a set of classes, even if not using UnoCSS. Can this be improved?
- "Adding classes via JavaScript will not be captured by NiceGUI and those classes will not be applied." → This is a hard limitation if we want to replace Tailwind with UnoCSS in 3.0. If there's no (cheap) solution, we might at least need a public function to trigger a CSS update programmatically.
I just replaced the dark mode interval with an event listener. Seems to work nicely. On the other hand I noticed that Tailwind classes are not only ignored when set via JavaScript, but also e.g. in templates for scoped slots: ui.table(rows=[{'ID': 'Alice', 'age': 18}, {'ID': 'Bob', 'age': 21}]).add_slot('body-cell-age', '''
<q-td key="age" :props="props">
<q-badge :class="props.value < 21 ? 'bg-red-500' : 'bg-green-500'">
{{ props.value }}
</q-badge>
</q-td>
''') And you can't easily call some Maybe we find a way to use some kind of efficient observer, maybe only observing individual elements or slots? |
Oh I am SO busy. I think UnoCSS is a worthy change. However, the slot case was an oversight of mine. Eventually, we need to move away from a mutation observer, but right now, for 3.0, I think we really need to get UnoCSS working more than anything (or else we use Tailwind V4 client-side JS...) So, for the time being, an efficient mutation observer (NOT the one built-into UnoCSS since that observes and parses the entire HTML, which is taking a long time) When I have time, I can work on an observer-free implementation, and it will be a "speed improvement" TL-DR: Getting UnoCSS is an important feature, while my insist on not using observer is a speed improvement. Since we can't do the both given my limited time available, we have no choice but to focus on the first one. |
I just agreed with @evnchn to postpone this PR to after version 3.0. Since UnoCSS won't replace Tailwind any time soon, we're going to introduce it as a non-breaking opt-in feature anyway. |
Motivation
As in #4806, UnoCSS is one possible contender, such that we can move away from the monolithic, large, and slow Tailwind client-side JS.
Implementation
npm.json
(excepttailwind.css
style reset CSS, that one to be done later)ui.run
I'd imagineProgress
Some tasks:
tailwind.css
Tailwind Style ResetResults
So, as it turns out, UnoCSS is NOT a 100% drop-in replacement for Tailwind CSS. Documentation says: "It should be noted that complete compatibility may not be guaranteed."
Quite a lot of things break.
But, overall, I'd call it "80% of the way there".
Question for discussion