Konsta UI – Mobile UI Components Built with TailwindCSS
konstaui.com
konstaui.com
I just use Vanilla Extract (with their Sprinkles API) and call it a day, it uses TypeScript as the preprocessor language and then compiles it to raw CSS, similar to SCSS but without writing SCSS.
I don’t think tailwind is perfect but coming into a well-established codebase I am so much happier to see tailwind. I can’t think of a single issue I’ve encountered with tailwind in this context.
You can certainly write good, maintainable CSS and I’m sure tools like Vanilla Extract make it easier but to say tailwind is worse is just wrong (in my experience, anyway).
But in the days of components, Tailwind simply is worse to me from a maintainability perspective than just having scoped CSS. It is at best equal to CSS classes because inevitably the pattern used is with @apply or making a space separated string of all the Tailwind classes in JS in order to add that as a variable to whatever div you needed to. Which is, well, CSS classes reinvented.
The only problem with tailwind is it goes super overboard with the idea. You want to use probably 30% of tailwind and use their naming convention. But once people start to write some long on demand single classes its always better just name a class and use CSS.
I think its because the authors need to be seem they are making updates all the time and can't accept that it's pretty much finished project. They also don't want to accept that utility classes are not solution to everything and good old CSS still has lots of use.
If you have a design system, Tailwind.config can be used to both extend and limit the classes. Notably, we cut all tailwind colors out and only define theme colors. We also define all sizing, shadows, and text styles around our design system. This constrains your design down to only “legal” values. This doesn’t mean every design will be magically right, but it separates the possibility of non-standard values out at the very least and has actually caught bad mocks as well.
I think, to me, tailwind isn’t done and I need one thing: let me group classes with modifiers.
I want xl:[text-bold p-4] instead of xl:text-bold xl:p-4
Ultimately I don’t think tailwind is perfect at all…but no CSS framework is. In fact, I think part of the reason it is a hit is because mixing custom components with both custom css AND bootstrap is a mess as well in the real world. At least Tailwind has a single source of truth.
Your example xl:[text-bold p-4] is performance anti-pattern. Don't forget that main reason utility classes came to be was performance. It's fastest to put class directly on element and you end up with very small css file because you don't repeat. When you start to do xl:[text-bold p-4] you will end eventually write xl:[text-bold p-4 pb-2] or even xl:[p-4 text-bold]. Now you lost one of the main advantages of utility classes and end up in more confusing world than pure css.
Yes you can make utility classes for typography styles..that’s entirely the point of extending the framework, they are extremely clear that you should even. None of this precludes the idea that it is configurable to the point of making it a better solution for one’s needs.
Personally the vanilla extract example looks like literal boilerplate hell for any sort of actually complex application. It might make complete sense if the whole thing was based on a declarative template where the objects also define elements but here it is just SCSS done elsewhere.
The reason why people like Tailwind at build time is that it removes a step of defining classes out of the flow and puts all your styles in one place. That is the innovation: mental, not technical. I have a pet theory that Tailwind is more preferred by those with ADHD as it completely removes a mental blocker element.
Additionally, CSS Modules is not a replacement for TailwindCSS. TailwindCSS ships and strongly promotes the use of design tokens. It is harder to NOT use design tokens in TailwindCSS.
Because of this, there is no CSS Modules v. TailwindCSS. It is CSS Modules + X v. TailwindCSS. Where in the worst case "X" is just a stand-in for "everybody does whatever" which produces horrendous unmaintainable stylesheets whether they are global or not.
In the first example of vanilla extract, it uses exact px measurements which already demonstrates it’s not geared to solve one of the primary selling points of tailwind (using config as a constraint to reduce mental overhead when building things).
> I’ve found what you said to be completely untrue unless you’re totally lazy.
Ah yes, the laziness argument. Let's not blame our tools but ourselves for the tools are always good and righteous. If only those darn C programmers weren't so lazy writing their memory leaks.
Once you know the syntax of Tailwind you can jump into any codebase and instantly know what’s going on. With “standard” CSS you’re forever jumping between components and class definitions.
Only if you already have no clue what CSS is. If you know CSS and can’t figure out what a given tailwind class does, then I don’t know if anyone can help you.
That said, I do often feel that I might as well just write the css directly. Writing tailwind feels like another translation layer.
I've never fully committed to TailwindCSS, but I have tried out my own utility classes on a smaller scale, and I found myself having to parse the entirety of the code to figure out what was going on.
My preference now is a mix of utility classes for super basic things that would be tedious to set a class on, and custom classes for everything else. Especially if media queries are involved, because good lord is that ever tedious to do with utility classes. If I find myself setting more than 2-3 utility classes on an element, I usually end up moving that to a CSS class for one reason or another. I don't define the utility classes until I need them, and I really don't use very many.
.reset {
display: inline;
appearance: none;
font: inherit;
border: none;
border-radius: 0;
margin: 0;
padding: 0;
color: inherit;
background: none;
list-style: none;
text-align: inherit;
user-select: inherit;
}
This is defined first in my CSS index file, so that any other classes will override it.(Note that there's probably a better way of writing this rule. This is just something that evolved organically.)
The problem is, everybody already knows Bash. Tailwind? Not so much.
Highly doubt it.
> at the cost of readability.
You mean the readability of "p-2 bg-red-500 text-lg font-medium" or "i-dont-remember-what-this-class-does"?
I'd argue the readability in Tailwind is better. Tailwind is highly indicative of what it does and doesn't waste time when it comes to consistency.
The only real argument is that it adds extra length to the class attribute, but then again, it doesn't cause issues like finding the same class in 50 different CSS files or not having any auto-completion.
No, I'm pretty sure he means the readability of "absolute bottom-0 text-sm md:text-base text-white leading-relaxed tracking-tighter transition-all duration-300 ease-in-out m-3 md:m-4 px-6 md:px-8 py-4 md:py-6 opacity-0 w-full", as opposed to a single well-named class such as "image-caption".
If long class names aren't your thing, then sure, use CSS, but I'd rather save time and have understandable code than maintain those CSS classes like "image-caption".
Well, I don't appreciate the snarky comment, quite honestly. But okay, I'll assume you have had more experience than me, and you've managed things I haven't, have a good day.
> I'd rather save time and have understandable code than maintain those CSS classes like "image-caption".
Sorry, but the snarkiness was in your comment first, and when you said you didn't want to maintain those classes, that's exactly what it sounded like to me, that, well, you didn't want to maintain said code. If you had a different point I'd be happy to hear it.
> I've often found that people who are in the frontend don't properly learn CSS and just hack it together. That was me too for a long while which is why I hated it. Then I started learning it from first principles and it makes a lot of sense. Now I can build whatever I need in plain CSS classes.
So sometimes people just... misunderstand or use the tool wrong?
CSS is definitely a write-only language. I've yet to see anyone understand CSS in a large system and refactor it. You end up with dozens and hundreds one-off classes and overrides everywhere.
Worse.
With Tailwind you have a consistent set of classes scoped usually per component. Thos p-x, m-x, and others don't change from component to component or from project to project.
Hell if I know what `.chip-text__content` is, how it's different from `.icon-button__content`, why it interferes with my CSS, and what other 15 CSS classes I need on top of that to make it work.
How are you going to maintain consistent values across components such as spacing colors etc? Those tend to grow to the size of Tailwind
Every design system I've come across contains any combination of:
- rigid inflexible components that need complex overrides even for the simplest cases
- multiple classes with seemingly innocuous names like "col col-8" that get increasingly obtuse and one-off like "uxg-menu-header uxg-avatar-hero-block uxg-avatar" [1] or "fas fa-fw fa-bell pf-c-alert pf-m-info pf-c-alert__title" [2]
- multiple often contradicting css variables (esp. colors)
- ... i'm missing something else, but it's late here and my brain doesn't work ...
[1] Design system by some new age finance company: https://design.fusionfabric.cloud/components/app-bar?tab=dev
[2] Opensource design system by RedHat https://www.patternfly.org/v4/components/alert/html
I've been writing CSS since 1997 and tried every fad technique that's come along. Tailwind is the first one that didn't make me dread dealing with CSS.
Of course you can build big things with semantic CSS. You also can with Tailwind.
Some people like Tailwind and find it incredibly helpful.
Some people don't.
Some people actively despise Tailwind.
No one has to 'win'. All these opinions can coexist.
Even in this thread there are people doing so: https://news.ycombinator.com/item?id=34921960
I understand perfectly well why people like Tailwind. The problem is not initial productivity; indeed, I can write bash scripts too very quickly that make me feel infinitely productive. It's what comes afterwards, the maintenance, the teasing of code written, that Tailwind makes so difficult.
And sure, use what you want, but I won't use it.
The maintenance is what makes Tailwind awesome. I've written CSS professionally since Internet Explorer 6 and have gone through many different strategies for writing maintainable CSS (BEM, OOCSS, SCSS and multiple different CSS-in-JS methods) but Tailwind is the first time I actually feel relieved of all the issues. To me, it's such an enormous improvement from normal CSS that people arguing against it feels like someone trying to convince me not to use syntax highlighting.
That's what CSS is, a HUGE inheritance graph, just even more convoluted, because absolutely every "class" is part of the same graph.
Yes, being able to copypaste self-contained HTML with all styling included and no depedencies is amazing.
Your copy pasting analogy makes no sense because "syntax highlighting" was referring to you trying to convince me to stop using something I can't live without and had nothing to do with Tailwind. Anyway, nothing wrong with copy pasting code and avoid premature abstractions until they are needed. Being religious about DRY and trying to shoehorn subsequent iterations of similar code into an inflexible abstraction leads to unmaintainable monstrosities.
Eh, when the heading prominently mentions TailwindCSS, I’d say the topic is very much about that choice. If it were a minor implementation detail, it would be different.
This is exactly the situation Tailwind prevents.
Unless your team has incredible discipline, CSS across a large system very often becomes a tangled mess where you can’t change one thing without unintentionally affecting another.
When you change the Tailwind classes on an element, you know there’s no risk of subtly breaking something somewhere else.
Don’t conflate “visually busy” with “unmaintainable”.
Web apps, not as much.
- Devs who make relatively small e-commerce-type websites, who loves tailwind, bootstrap, etc. Good defaults, fast throughput, maintenance is less important
- Devs who make relatively big web apps, who hates them. Everything ends up customized one way or another, maintenance is most of the work, tailwind and bootstrap end up only getting in the way.
The problem here is that this distinction is seldom make explicit, and here we are.
You find yourself having to do "Right click > inspect" a whole lot less often to figure out what's going on
Tailwind is not easier than a custom internal design system either, as that has been tailored to your company and the maintenance of that system is integral to your design team. You might think that offloading to Tailwind is better, but you're just doubling up duties because someone internally is going to have to customize away from the defaults.
Tailwind can be easier to maintain than similar libraries. After trying most of these, I can't say whether that actually shows itself during development. I suppose if one was exclusively used to Vue or was brought up in the world of overzealous BEM, Tailwind might seem easier/refreshing. But if you've worked with Bootstrap or its alternatives (of the time), Tailwind isn't much different and can feel like a step back when you now have to rely on additional libraries like Konsta, Daisy, or Tailwind UI to create premade components for you.
Your example confuses me too, because why wouldn't your devtools be open anyways? You're in development so use the tools you have to make your job less of a guessing game. I guess what you say might be true, you can load a page and just tell a component has a margin right but you're going to be opening the devtools anyways to double check.
I still think Tailwind is great for solo devs, it's a design system with sane defaults they can rely on and get something in production very fast. Every other reason I've seen Tailwind devs give winds up confusing me about how they're actually working, or if they've ever bothered with anything else.
Instead I find myself going to the Tailwind docs to find out how they renamed this random css property.
But it’s still better than plain CSS.
The reality is that if the codebase and style code is in flux, that idealized CSS stylesheet will churn towards a being a mess of tech debt. Utility CSS contain redundancies (on the HTML side of things), but the rule of dumb is that you shouldn't refactor redundancies until you are absolutely sure what the unit of abstraction / isolation should be. In the case of prototype and fleshing out your designs, having a concise CSS stylesheet won't work, especially if you work with other people who are tunnel visioned on one specific scenario (a sort of tragedy of the commons) and not thinking hollistically as you would as an solo developer. We can think of that idealized, perfectly concise, stylesheet an "unstable saddle point" whereas utility CSS is not already at the saddle point but it does converge towards a stable one.
Interesting. That’s not been my experience. People tend to clean up as they go, eg if the design says we now need a thinner padding / gaps or a different colour blue, we change the variable, and if we spot cut and pastes we fix them.
It’s certainly much easier to refactor than visual classes mixed into HTML.
https://tailwindcss.com/docs/customizing-spacing
Better yet, it also forces people to use theme spacing sizes or making the use of custom unit very explicit (a [] in your class name)
So global styles are very rare and usually a bunch of branding variables these days.
Like a lot of bad solutions in tech, tailwind seems to exist as a workaround to the core issue of ‘still using react’.
You could argue "well you should learn CSS!" but at the end of the day, I don't need CSS often enough to want to bother. Frameworks like TailwindCSS have been great for people like me.
-
Also you went and dug into its guts to find the implementation details, the actual usage is nowhere near that complicated: https://github.com/konstaui/konsta/blob/master/kitchen-sink/...
I can't even imagine what raw CSS lovecraftian horror captures all of the corner cases the classes you linked are hiding away from me (and to be clear, I'd rather not know or care)
"uppercase" => "text-transform: uppercase;"
"duration-100" => "transition-duration: 100ms;"
"px-2" => "padding-left: 0.5rem; padding-right: 0.5rem;"
For someone who knows CSS I don't see it as a big downgrade in readability?
But for someone like me, the right side of that equation isn't something I could go around writing in my HTML, the left form is.
Even if all it's doing is acting as a short form for CSS that allows me to do a "no-no" and embed CSS in my markup, it enables me to be infinitely more productive in CSS than I've ever been.
-
And the reality is, if one day I work on a product that's so cursed with success that breaking that encapsulation starts to bite me:
a) It's rare there won't be a lot about the design that has to change anyways
b) I can hire/pay people who do this stuff for a living.
And in the meantime I'll still get a ton of value from it
Sure, HTML looks uglier when I add a dozen classes to an element instead of adding one class with a dozen of CSS rules, but I'm more than willing to accept that as a compromise.
Overall, Tailwind made frontend design more accessible to me than it ever was, and I never have to use `!important` again.
It usually comes out as commentary along the lines of "well what's so hard about learning when to use !important?", "that tells me your CSS is poorly organized"... or sometimes just a drive-by downvote
In my experience that comes from a misguided idea that people who jump at it are somehow uncurious, or irresponsible, for "wanting the sausage without learning how it's made" and not caring anything at all about the craft.
-
I don't know if it occurs to them that there are some of us who have our hands in so many pies that, regardless of will or want, there is simply no more time for more pies:
The last time I picked up CSS, it was to write a static page to serve as a control interface for firmware I wrote for an MCU, for accessing an API engine I had just written for said MCU, embedded in a circuit design I had created and hand assembled, which was in turn embedded in a stepper actuated 3d printed assembly I had designed and printed. And all that was in a weekend: the last thing on earth I had time for at the end of it was figuring out what the idiomatic CSS way to style some buttons was...
The fact is, I get it: I am able to appreciate craft, and I understand how so casually throwing best practices to the wind "because it's easy" could come across as offensive. But at the end of the day, sometimes it really doesn't matter how the sausage gets made as long as it gets made.
I'm not. I have no interest in learning more, same way as frontend developers have no interest in learning to build custom Dockerfiles or Kubernetes deployments. It's not that it's difficult to pick up, we just can't be bothered to. People that do frontend just want their things to run, and I just want to be able to make a website that doesn't look like shit without spending a ridiculous amount of time on it.
Anything that bridges these gaps is a win in my book. Tailwind is better than Bootstrap (granted, it's been years since I've last tried it), better than drag-and-drop website builders, worse than pure CSS if you know what you're doing. It won't make your job obsolete, it just makes things easier for the rest of us. Same goes for docker-compose.
This is a component you reuse across tons of sites, it's not a one off component you're building for yourself. It's also not just a CSS framework like Bootstrap. This is full CSS + JS component's with functionality, Vue/React/Svelte framework integration, and events built in.
Whether css-in-JS as a whole makes sense beyond these generic component type systems is a good question. There's plenty of complexity introduced.
But for a generic component being used in plenty of use cases - not just UI usecases - but highly interactive JS driven ones as well, then it makes a lot more sense to have styling tied to programming languages and conditionals and options and JS data structures.
Classname strings are fine.
IDK about React but Vue also has things like scoping, where the elements get unique IDs appended as data tags so you don't have to worry about CSS global scope clashes. Plus with Webpack/Vite the CSS automatically gets extracted and via HTTP2 only loads the tiny JS and CSS files needed only for the components used on the page.
In that case giant blobs of CSS and JS would be less efficient.
var style="color:blue;text-align:center;"
return <h1 style={style} />
and some CSS in JS frameworks compile down to pretty much that. However, this is a bad practice, because you will consistently see worse performance than just using css files and classnames instead.And utility classes.
Unless they modernized it in recent years, haven't used it in 5yrs.
People use tailwind along CSS. You can write CSS components (written in css) and use them in tailwind and with tailwind.
I am heavy tailwind user and when i see this it seems to me like people forgot css exists.
For sure there is huge trap in webapp developers who mostly copy paste HTML partials from Tailwind UI who succumb to Tailwind marketing and completely forget CSS.
Developers mostly don't like CSS so not many care. That's why there are so many solutions how to avoid it.
But utility classes (and tailwind as most popular utility classes generator) are super useful even if you are not just copy paste UI guy.
In my opinion, this gives you all of the supposed benefits of Tailwind without all of the noise and annoying opinions that come with Tailwind
I mean personally I think any developer worth their salt should be able to learn native development, and any company that wants to make a good app should hire and invest in native developers / development. But that's a hard sell these days.
That said I’m inclined to agree - emulating system controls with CSS always feels very uncanny valley to me.
Such a weird ecosystem the sponsorships have created. I see a lot of other sites with irrelevant sponsors and non-trivial amounts of money, there just for the SEO/ranking
I'm very impressed by the polish of the project but am curious about the main use case for a library like this.
(I guess, in what situation would one want a webpage to feel like a system native app? Potentially this paves the way for PWAs?)
When one has an app that can function as an SPA, wants to distribute outside of app stores but still give a native visual presentation. Currently working on such a side app myself right now. And that I can use this and continue implementing in Vue is a big plus for me.
Konsta UI looks exciting but their Framework7 App Framework looks even more so.
I'd be very interested in something like Tamagui (https://tamagui.dev/) but for Tailwind. I tried Tamagui but it's a bit too complicated when it comes to styling and layouts.
I can't really comment on how it scales in big projects tho.
I think there’s maybe a few desktop UI APIs that use a similar approach to CSS, but having a separate declarative style sheet is almost unique to the web in the grand scheme of things.
I guess it’s mostly people with a document-first mindset to stuff on the web, but I don’t think CSS is a good way to style application UIs.
But to me, removing the context switch is like an ADHD cheat code. I’ve grown to enjoy the ability to look at one block and know exactly what it looks like as well. There’s no key value search to know why some bit of text is red for example.
Looking through the source code, they reimplemented all components for react, Vue and svelte. That's an impressive amount of work.
What confuses me is why they would do that... Why not just use Web Components as the core?
If you want clean integration with a framework, a small "glue" wrapper component should be easy.
I question whether the current development approach is maintainable.
The project has basically 4 parts:
- 1 for the CSS parts: basically a DSL to define a giant tree of Tailwind CSS class properties, with some conditionals to take care of the context (iOS vs. Material) and other optional features.
- 3 for the React/Vue/Svelte components. They seem to provide the same features, each implemented independently.
There is definitively a separation of concern between style and behavior, so the style part could be reused in other frameworks.
But there is also a "DRY" violation with the 3 independently developed framework-dependent parts. Could this be improved by having a framework-independent part (you suggest Web Components, what would be the easier way to get this part done?) and framework-dependent adapter, or would this extra layer of indirection make things harder to understand?
We're looking to find the lowest common denominator of expressing UI components and thinking about JSON metadata instead of Web Components. With this, we'd have to implement some adaptor that maps JSON to each UI library, but in our case we really only have to worry about React and Native Mobile.
It is like "you kind of can, but you're on your own" thing,
> Most people who use React don’t use Web Components, but you may want to, especially if you are using third-party UI components that are written using Web Components.
So it seems like this would be exactly the kind of use case where using web components would be ok.
Because web components suck and are an overkill for what should really be the job of Scoped CSS (now indefinitely delayed because of web components)?
Wondering if there are plans to add a grid with drag+drop? We're looking to emulate the iOS homescreen where you have a grid of Icons that can be dragged/dropped using https://shopify.github.io/draggable. Having an integrated solution would help us avoid haphazard glue code.
Although I'm not very familiar with Tailwind and its component library ecosystem, I found the DIY approach taken by https://github.com/shadcn/ui to be better suited to my needs. This approach offers greater customization and flexibility in designing UI components, which is where I find the most enjoyment in building UI. Of course, pre-built component libraries like OP can provide a quicker solution if resources are limited.
- The components for iOS look nice, but some things are off: Sheet modal is weird. Animation of modals or side panels feel too slow.
- There are no animations when navigating forward or backwards.
- The demo has scrolling issues on iOS Safari and doesn’t always show the header.
- Unfaithful communication: it claims to give you native look and feel, which can never be true for HTML/CSS-based UIs that merely replicate native components.
- I see no point in using this instead of Ionic, because Ionic has the same or more components with less bugs, because it has been around a lot longer.
One small regret: I wish the library was structured like https://ui.shadcn.com/ , which I love because it allows to copy paste the source code of each component and customize it further in your app, rather than importing a rigid pre made component into your app