[Idea] - Some ideas from a framework I was developing to fix the same issues as JIT #5725
Replies: 18 comments 2 replies
-
Isn't your second example in child selectors a good use case for groups? <div classname="group">
<div classname="group-hover:bg-black" />
</div> |
Beta Was this translation helpful? Give feedback.
-
@bitttttten You're right in that child selectors wouldn't really add any functionality that isn't currently possible using Tailwind. But it would differ in the sense of how much duplication is in your templates. Taking your example, but with more than one child: <div classname="group">
<div classname="group-hover:bg-black" />
<div classname="group-hover:bg-black" />
<div classname="group-hover:bg-black" />
<div classname="group-hover:bg-black" />
<div classname="group-hover:bg-black" />
</div> with child selectors would become: <div classname="hover:child:bg-black">
<div />
<div />
<div />
<div />
<div />
</div> which is definitely cleaner, and becomes even cleaner if there are more than one child style: <div classname="child:bg-blue child:rounded-full hover:child:bg-black">
<div />
<div />
<div />
<div />
<div />
</div> I'll admit that it's mostly useful for prototyping in the time between when you realise that you want to style a bunch of elements the same and the time when you're are ready to abstract those elements as a component or CSS class. The idea mainly came from the feeling that when I do write normal CSS classes, that I reach for the |
Beta Was this translation helpful? Give feedback.
-
Hey thanks for sharing these ideas! Definitely eager to explore more opportunities for arbitrary stuff, especially in variants — was something I was planning to tinker with already. Will chime in here more as I get a chance to look at some of this stuff 👍🏻 |
Beta Was this translation helpful? Give feedback.
-
Thanks for taking the time to give them a read. You guys really do a great job. The only reason why I started to make my version was because a lot of the sites we build at work are heavily custom, designer-driven sites. Fitting that into a design system can be tricky, with lots of exceptions to any rules you can make. Hence, there's a lot of arbitrary value stuff, and I was essentially looking for a way to write any CSS inline but still make use of tailwind-style variants. Definitely figured you guys would already be thinking of some of this stuff. Having said that, if any of these ideas can be of use, then all the better; especially the CSS variable stuff, I really love using them, and the |
Beta Was this translation helpful? Give feedback.
-
Some really neat ideas here @markbailey0356 :) I'm also excited about the possibilities of the JIT compiler - beautiful work @adamwathan! The first thing I thought of when I saw the arbitrary JIT values was breakpoints, which led me here after a quick search. Often I find myself having to write custom CSS for components because I want very precise control over their breakpoints. It doesn't make sense to create a bunch of different breakpoints in my config that I might only use once or twice. Furthermore, it can become difficult to name all these breakpoints. For years I've used Stylus as my pre-processor of choice and I lean heavily on the Rupture library to create concise, custom breakpoints. I use it with normal CSS and also with Tailwind, eg. .custom
@apply text-lg
+below(520px)
@apply text-center text-md Maybe Tailwind could consider some Rupture-inspired dynamic breakpoints: However, this could get messy very quickly due to the repetition of the dynamic values. In that case, it would be nice to be able to group a bunch of classes under a breakpoint eg. Anyway, just putting it out there in case anyone else has any better ideas! |
Beta Was this translation helpful? Give feedback.
-
There is a case where you cannot do this. If you fetch some raw html through an API, you have a div who can't apply |
Beta Was this translation helpful? Give feedback.
-
Here to say +1 for the dynamic breakpoints. This is my largest pain point at the moment. |
Beta Was this translation helpful? Give feedback.
-
@adamwathan just chiming in to say i love the direction you are going with the JIT. the addition of arbitrary value/unit support is great. if there is any one thing i would really hope to see you add, its some way to allow you to group variant classes. for example instead of the current <a class="text-black hover:bg-black hover:text-white hover:scale-110"> something like <a class="text-black hover:(bg-black text-white scale-110)"> the option to write a bunch of variant styles without having to repeat the variant prefix over and over would be a significant improvement on reducing class name lengths, as well as making it clear how styles are applied to someone looking at the source file with fresh eyes |
Beta Was this translation helpful? Give feedback.
-
@matthewjumpsoffbuildings, I don't think that's possible unfortunately - even if you surround the class names with brackets, the spaces make the browser interpret them as separate, individual classes. That's why all this repetition is needed in the class names. Depending on how you generate your HTML, maybe you could have a helper function that groups the prefixes but it's an extra level of abstraction. It's a problem that might be better solved with tooling such as intelligent autocomplete / grouping / syntax highlighting in the editor. |
Beta Was this translation helpful? Give feedback.
-
@hybridvision couldnt the spacing issue simply be resolved by using some other separator for variant group class names? eg <a class="text-black hover:(bg-black_text-white_scale-110)"> or <a class="text-black hover:(bg-black--text-white--scale-110)"> or <a class="text-black hover:(bg-black,text-white,scale-110)"> thinking about it though, that would generate a new unique class to match that exact classname, so i suppose it would pollute the output css. i have been experimenting with some kind of solution at the html/pug level, eg a build step that converts grouped variants classes into their individual |
Beta Was this translation helpful? Give feedback.
-
@matthewjumpsoffbuildings: it could, but that goes against the main concept of these being individual, composable classes. If you did that, you'd end up with a bunch of longer, specifically-named classes (which also could end up being duplicated if the order of the sub-items wasn't consistent). It's helpful to think of the final CSS that would be generated. In that case, you'd probably be better off giving the element a sensible name and using As developers, I know we're conditioned to avoid repetition and to make things as clever as possible but it's not always practical. At a certain point, it can even become counterproductive... 🙃 |
Beta Was this translation helpful? Give feedback.
-
@hybridvision timing man, i just saw your message as i finished editing my prev comment 😄 |
Beta Was this translation helpful? Give feedback.
-
@matthewjumpsoffbuildings @hybridvision FYI: Windi supports this as variant groups. |
Beta Was this translation helpful? Give feedback.
-
wth the syntax is identical to what i suggested haha. from their docs <div class="bg-white dark:hover:(bg-gray-800 font-medium text-white)"/> |
Beta Was this translation helpful? Give feedback.
-
Haha yes @matthewjumpsoffbuildings, it seems we're on the same page anyway 😉 I think the implications for the PurgeCSS process are very important to consider - maybe you could come with with a different regex but it might end up being less efficient if the matching has to be looser. That's why I personally favour leaning on the tooling with things like autocomplete. It's a question of where you want the complexity to live... @techniq - thanks for the link, I didn't know about that! It's funny that they use the same syntax Matthew suggested... One thing I notice is that the class names get rewritten and expanded out in the preview, so there's an extra step in there. That would make it harder to use in certain setups... |
Beta Was this translation helpful? Give feedback.
-
FYI, if you didn't know this, Windi kind of pioneered the JIT process for Tailwind (and has a lot of added features) |
Beta Was this translation helpful? Give feedback.
-
i was about to suggest using non-standard html attributes to group variant rules earlier, and what do you know, it seems the devs behind windi read my mind again - https://windicss.org/features/attributify.html |
Beta Was this translation helpful? Give feedback.
-
Thanks @techniq, I'd seen Windi sometime ago in passing but it has developed a lot since then. I'm interested to check it out in detail when I have a bit more time :) |
Beta Was this translation helpful? Give feedback.
-
What version of @tailwindcss/jit are you using?
What version of Node.js are you using?
What browser are you using?
What operating system are you using?
Reproduction repository
https://github.com/markbailey0356/postcss-omnicss
For the last few months, off and on, it just so happens that I've been developing a similar postcss plugin that was trying to address some of the problems that I was having when using the AOT version of Tailwind. I have linked to the repository above but it was essentially along the same lines: use purgecss to statically analyse your source code for used classes and generate utility classes for any that match the required format.
With the announcement of this version of Tailwind, it seems wasteful for me to continue developing something that is so similar. Having said that, I would like to bring some of the ideas behind the framework to the table here to see if any of them can gain traction and possibly be integrated into Tailwind. Rather than making a whole bunch of issues up front, I thought to list all the ideas here to gauge interest and make separate issues if any ideas are popular.
Custom media query prefixes
[>=600px]:flex
(or have default as px i.e.[>=600]:flex
)[height<=720px]:h-12
of[h<720px]:h-12
[min-aspect-ratio:16/9]:hidden
or[aspect-ratio>=16/9]:hidden
[orientation:portrait]:hidden
or[portrait]:hidden
In the same way that you might want to break out of your design system for custom values, you may want to do it for custom breakpoints. This would open up the possibilities of what media queries are also possible within the framework without preconfiguration.
Child selectors
child:mb-1
would become the selector `child:mb-1 > *hover:child:bg-black
would become eitherhover\:child\:bg-black:hover > *
orhover\:child\:bg-black > *:hover
Child selectors remove a whole class of duplication issues from your templates. It's especially useful for lists and nav where you want a whole bunch of elements to share the same styles, but you might not be ready to extract a class for them just yet.
There is a subtlety here is that it introduces importance to the order of the prefixes for your class.
hover:child:
would not produce the same results aschild:hover:
: one would style individual children when they are individually hovered, whereas the other would style all children when the parent is hovered.Before & after elements
before before:absolute before:inset-0
Being able to style before and after elements using Tailwind would be great. The class
before
would just applycontent: ""
to the before element so that it can begin to be styled. You could then use any other tailwind classes prefixed bybefore:
to style them however you need.I know that placeholder elements already have their own set of tailwind classes, but an extension of the above syntax would also allow for placeholders (and even
::-webkit-scrollbar
) to be styled by the prefix ofplaceholder:
(andscrollbar:
)Flexible syntax
align-items-center
justify-content-center
max-height-32
Tailwind's shorthand's are pretty good in that they don't go too overboard and shorten everything. But at the same time, they can be a barrier to entry, often requiring new users to have to constantly reference the documentation to figure out how to apply something like
align-items: center
. With the removal of CSS file-size constraints, there is scope to allow for the long-hand version of some of these shorthands to be more beginner-friendly.The concern here would be that this could increase production CSS sizes by having to have multiple different selectors for the same classes, but that is an issue that could be worked around with compiler warnings in production that warn of duplicate selectors or automated tools that de-duplicate your selectors.
Custom syntax for using CSS variables in custom values
w-[$small]
would be a shorthand forw-[var(--tw-small)]
text-[$(black,#000)]
would be shorthand fortext-[var(--tw-black, #000)]
In the framework I was making, the intention was to try and avoid having little to no configuration. In order to avoid having to program things like your color pallette or spacing sizes into a configuration, you would just set those values as CSS variables in your CSS document, then you would reference them in your utility classes. This approach was quite useful when setting inline styles using javascript as you were equally able to reference your custom colors (etc.) using CSS variables there.
Having said that, CSS syntax becomes especially unwieldily when used in utility classes, so I would propose taking a leaf out of SASS's book that would use the
$
symbol as a shorthand for referencing a prefixed tailwind CSS variable.Utility classes for setting CSS variables
[--tw-primary-color]-red-300
or[$primary-color]-red-300
[$width]-12 w-[$width] h-[calc(9/16*$width)]
Tying into the above, one of the major strengths of CSS variables is that they are understood by the cascade and are inherited by children. Being able to redefine them for a particular portion of your document or for a specific component is very powerful. They can also be used to set one property to the same value as another, or even using a calculation based on another.
I would propose a consistent shorthand as the previous section where you could also set CSS variables using the
$
syntax.Option to omit calc keyword when used in utility classes
h-[(9/16*$width)]
Further on the section above with inline calculations, the calc keyword just feels unnecessary in these contexts. A nice shorthand might be to be able to omit the calc keyword and just surround any calculations in round brackets.
Automatic variants for ALL classes (even those in author-defined CSS)
button-black md:button-blue hover:button-outline
Now that we are in the JIT world, it would be an amazing feature to longer need to wrap custom utilities in @variant blocks, etc. This lifts Tailwind into a world where everything is a utility class. If the JIT PurgeCSS finds a prefixed version of any class, it generates the prefixed version as required in the same way it would for a Tailwind utility.
Beta Was this translation helpful? Give feedback.
All reactions