- I eschew some of the helper components like <Flex>. You are fine just using plain old Box as the shorthand props in Flex component don't add much. You can just pass display="flex" into a Box.
- Passing hover/active styling requires using PseudoBox (or a component deriving from it), so <Box> - or anything built on top of it - can't have hover colors directly. This means configuration for some components require additional wrappers
- Author is very courteous (if my limited interaction with him on the tracker is any indicator!) If you use Chakra and like it, you can support the creator via https://www.patreon.com/segunadebayo
Chakra UI is a widget toolkit, so it's not on the same level of comparison.
React will use JSX and can use all the cool new JS stuff, e.g. module imports, template literals. With webpack there's automated code splitting. The toolchain is under very active development (from react, to webpack, to babel, to new dependencies I've never heard of - aside: a downside is the dependency graph in node can be crazy)
If your site is simple enough, server site templates will do. For anything non-trivial, where there's a lot of reusability and its very async / API heavy, the benefits shift dramatically to including a frontend framework.
Regarding server side templates, there's limitations to how far templates engines (e.g. django templates / jinja2) can take you. Extending templates works when done carefully, as does overriding blocks. Anything non-trivial becomes very hard to manage - there's no type safety, setting variables is burdensome.
On parataxic, there's no server. It's all static files served from cloudfront via Gatsby (to get an idea of this: https://jamstack.org/)
I have never found sever side rendered templates simplate on harder and more complex web apps. But that's me, maybe it just does not map with your mental model, or maybe I started php and django with the wrong foot. All I know is that for the moment I find react simpler to reason with. I looked a bit at angular and angular, and they also seemed simpler than SSR templates.
I use this library for basically all my projects now, i have tried many component libraries but this is the one I am most productive with
The idea of using atomic css properties is similar to the tailwind philosophy but there is no need to purge the css and you get typescript completion and validation
I work with Segun (the creator of Chakra UI), super cool and down to earth dude. I love that Chakra UI is getting some attention. We have been using it in all our production applications and couldn't be happier. I also just finished creating a short project-based video series on Chakra UI and React yesterday. Have a look if anyone is interested https://www.youtube.com/watch?v=NyG7YJWJd6s&list=PLkZYeFmDua...
I’m not sure exactly what’s going on, but I noticed in iOS Safari (iPhone 11, iOS 13.5.1), the components get progressively less responsive while browsing the components. After switching to a few component menus, for example, the button presses take ~1s to start animating. Reloading the page appears to reset the responsiveness to normal.
In my Firefox on a Macbook the animations seem janky. The toast example does not work at all. When something like the drawer opens, the main content part of the page jumps and moves to the side a bit only to jump back when the drawer gets closed. On every page there's an empty light blue box at the top which just wastes space and makes me scroll.
That being said, many of issues don't seem to be present in the Vue version linked in another comment. Though even there some animations are not smooth and for example the up/down arrows on the slider number input just don't work. And for something that's supposed to provide a unified UI the styles between React and Vue versions are totally different, even the font size and weight. That slider number input that I mentioned looks completely different: shapes, positions, colors etc.
Too many issues for my taste. Unfortunately that seems par for the course with many frontend frameworks.
Really happy that Chakra UI is getting some attention here.
I interviewed the creator, Segun Adebayo, on the JSParty podcast here: https://changelog.com/jsparty/125 You couldn't meet a friendlier maintainer. The fact that he's only been programming full-time for 6-7 months makes Chakra UI even more impressive.
The component I always look for in these libraries is a date picker (and also a time picker). I've never found one that actually works well on desktop and mobile and can be used with a keyboard.
Honestly though. Every third party framework or component you use is going to have an opinion. Your only choice is if that opinion aligns with yours or not.
But for mobile I ended up using react-device-detect and going with customized regular ol' html inputs, iOS is such a pain otherwise... and it worked well for iOS/Android.
On Desktop, I look for a time picker where the top-down arrows on the keyboard work to change the numbers on the hour-minute-second slots. The ant design time picker showcase doesn't work like this it seems.
Same, I use Chakra-UI in a production-grade app and I hit a wall with a date and time picker. I had to build my own with Downshift, but getting it to work correctly on all resolutions and with react-hook-forms was tedious and time-consuming.
They just use the native picker, which is often a very reasonable choice, but presents problems. For example, I might want to use 24-hour time in an application (e.g. emergency services logistics) and not all browsers will permit this.
No. They don't use the native picker only (they provide it as an alternative). Their very first demo is of custom picker implementation using date-fns (which can be replaced with another one of your choice: Bring your own date management library).
What is the threshold for UI component libraries describing themselves as "accessible"> Is it running through automated tools, such axe, is it an audit by an independent third-party group, or is it manual testing by actual users who regularly use screen reader tools?
I don't work on Chakra, I lead the team that builds Elastic's design library[0]. We take accessibility pretty seriously. In general this means:
- We make sure tab order and keyboard control is a equal level citizen.
- All our colors and palettes are backed by math, both for contrast and for color blind qualitative comparison.
- We build using semantic HTML and try to to avoid abstracting things like input controls and labels with too much magic.
- We test and build for screen reader support at the component level and then provide helpers for navigation. Usually, given the complexity, this means a decent mix of native html, aria, and hidden text to make things read correctly.
We do have some automated axe testing, but in all honesty, axes only gets the surface level spec and might cover 30% of what you need. The rest is really hand touched, backed by pretty strict review.
In general the bigger frameworks like ours are getting better at this stuff, but it's still fairly poorly considered in the industry overall. The specs are pretty verbose and poorly standardized against browsers. This make it very much like building a traditional visual frontend during the browser wars of the 2000s (I was there!).
Third party audits are normally done on the products themselves (in our case Kibana), not the framework itself. This ends up being an indirect method of auditing the framework though.
All our work is open source and documented. If you have any questions, please ask away. I love this stuff and web UI has been a 20-year passion for me.
Mostly it's a combination of tools. We write a lot of custom color functions (using Sass). You can check the src here[0]. A common one we'll use is makeHighContrastColor(), which given two colors will automatically make the first one a 4.5 AA accessible contrast by adding tint/shade.
For palette generation, we do a lot of our work with tools like chroma.js[1] which can help with some colorblind math.
I'd rather just use tailwind or other utility css. Why have another proprietary abstraction when you can have something concise that maps more directly to css. You can then build your own local abstractions as needed. Much leaner, universal and comprehensible imo.
I totally agree with you. I will say though, Tailwind with React hooks and Zustand is my go to lately. Feels quite trivial and flexible to build the functionality you mentioned. I've been quite happy with the output.
Chakra UI looks fantastic, however. I am just personally feeling Styled Component fatigue after a few years of using it. I like being able to create consistent presentation with just CSS classes and leveraging hooks for anything more complicated.
Hello fam! Creator of the Vue version of Chakra UI here!
Chimed in a little late, but I'm grateful for the Chakra UI shoutout!
The React team is currently working on publishing new 1.0 Typescript release for Chakra UI. Lots of new goodies coming in next major version for React!
I've gained some useful insight while reading some of the comments made about the libraries. We'll definitely be looking into this in the near future!
The Vue version was recently released a month ago! We're currently improving the release and coming up with new ideas to make developing accessible Vue apps with Chakra UI easier and more fun.
If you have any questions about the Vue version (or React) as well, I'm happy to take them!
We're also very glad to receive contributors to help us improve Chakra UI. If this sounds like something you're interested in doing, feel free to checkout the issues:
I am a big fan of styled-system and glad that more frameworks are utilizing it. This is something that helps a lot when building desktop-alike apps for the web.
I used to have ant.design as my react frontend first pick.
Then I needed to do responsive, and it was much more fun doing this in chakra with it's variable sizes for different viewports, etc, which was much nicer than dabling with ant.design less/css @media queries in my experience.
Material UI is a nightmare to customize, extend or integrate with third party react libraries. This on the other hand is fully customizable (through theming AND the css props) and use emotion, so it plays well with A LOT of libraries that use emotion too.
> Material UI uses a very similar theming system. The interface of the theme itself is different, but that seems to be about it there.
Material UI implements Material UI by default and this is the main reason why it's hard to customize. Too much to change. I guess this is one of the reasons why there are not that many custom themes available for this library.
You don't need to use the Material UI provided theme. You can just use the Base components. Like InputBase [1] or ButtonBase [2] and build your own component out of it.
If you spend sometime with Material UI you will realize that it is actually designed really well.
Are you serious or are you trolling at this point? Because I just mentioned that you don't need to use the components Material UI provides and you can just use the Base components (which is what Chakra provides too or so does any other UI framework). Styling just those Base components will get it down to 8 or so LOC.
Also, since when does LOC say anything about developer productivity? By using Material UI you are avoiding a lot of problems that you will face later on especially if you are building a complex app.
Not trolling. But your second example is indeed more meaningful of the way I'd like to customize styling. And on that aspect, it is -as you mention- exactly the same as chakra, line to line. Except that Material also has a lot of additional stuff and opinions that I don't need.
But anyway, it looks like we have had different experiences, maybe due to different use cases. My experience with Material UI has been the opposite of yours: It is cool to get a quick project stated, and I would use it again for small projects. But for a large SaaS application like I do, that includes 3D views, Openlayers Maps, React Select and others complicated 3rd party libraries and custom UX patterns, I would NOT use Material UI. Too opinionated, not flexible enough, and not being based on emotion is a show stopper for me. So let's agree to disagree maybe on that point.
Regarding the LOC, yes it does indeed say something about developer productivity, and this does match the contortions I had to do in the past to make Material UI fit my need. Lot of LOC, lot of time, no-so-cool results. I want more control, that's all.
I don’t know, did you try to customize both? I did and I can tell you there is a massive difference. Have a look at the source code of both if you’d like. Material UI is like a full framework with a ton of specific tooling around it. Chakra is more like a library based on “standard” tools of the ecosystem, and it has a much smaller footprint. Worst case scenario I can just copy the code from chakra to heavily modify it. Don’t try that with material, it will be painful.
Material UI actually is a lot better when it comes to customization. You can just override the provided component styles by creating ad-hoc CSS-in-JS styles and passing it as classes. This is apart from what Chakra UI provides. Both uses some form of styled-system but Material UI implements it better. Material UI provides an API to modify the styles of core components in any depth that you like. You do it through the `classes` prop.
So for complex components like TextField which has an InputLabel, Input and FormHelper component you have corresponding props: InputLabelProps, InputProps and FormHelperProps which accepts a `classes` prop each. You can then create ad-hoc CSS-in-JS styles using makeStyle and pass them as classnames to the respective inner-components `classes` prop. You'll realize the advantage of this only when you try it out.
The left side is a normal TextField and the right side is a TextField with styles overridden. If you do not like the TextField component Material UI provides you can always create your own with InputBase component.
Edit: Hacker News isn't letting me post a comment to your comment so I am editing my comment here.
Your example doesn't match mine. It just styles the component itself. Not inner components. For that you need a uniform API which neither Emotion nor Chakra provide. Please see my example again. The TextField component is a complex component comprising of InputLabel, Input and FormHelper. The idea is to style those inner components without actually breaking apart the source. We need a uniform API for that and neither Emotion nor Chakra provide something along those lines. Which is the crux of the argument on why Material UI is superior. It not only provides CSS-in-JS styling options like Emotion but also provides a standard API to style inner components no matter how deep in the tree they are. If you want to replicate the same feature you would have to create your own abstraction. But then that abstraction is not on the library level but your application level.
So if someone wants to work on your app, they will have to learn your abstraction first. If they move on to another app they can't carry over your abstraction in case the other app doesn't have the same implementation. They will either have to learn the new implementation or create that abstraction from scratch leading to a lot of bloat.
If I know some project is using Material UI I feel comfortable knowing that the API to modify a component and its inner components will be the same. That gives me a lot of confidence.
Your example doesn't match mine. It just styles the component itself. Not inner components. For that you need a uniform API which neither Emotion nor Chakra provide. Please see my example again. The TextField component is a complex component comprising of InputLabel, Input and FormHelper. The idea is to style those inner components without actually breaking apart the source. We need a uniform API for that and neither Emotion nor Chakra provide something along those lines. Which is the crux of the argument on why Material UI is superior. It not only provides CSS-in-JS styling options like Emotion but also provides a standard API to style inner components no matter how deep in the tree they are. If you want to replicate the same feature you would have to create your own abstraction. But then that abstraction is not on the library level but your application level.
So if someone wants to work on your app, they will have to learn your abstraction first. If they move on to another app they can't carry over your abstraction in case the other app doesn't have the same implementation. They will either have to learn the new implementation or create that abstraction from scratch leading to a lot of bloat.
If I know some project is using Material UI I feel comfortable knowing that the API to modify a component and its inner components will be the same. That gives me a lot of confidence.
The uniform API you are talking about is literally just nested CSS styles with emotion. It is possible to modify deep subcomponents style with emotion. It’s CSS Nothing more.
I agree my example is simpler than yours, but you will also agree that it is functionally equivalent.
My example takes 8LOC of customization. Yours use 45LOC. That matches my experience with customizing styles on larger project, Chakra is 80% simpler to customize.
Material UI in general is more complex and more opinionated (why do Input boxes Have to have this weird animated description? That’s opinionated) Which is why I prefer Chakra. KISS.
> My example takes 8LOC of customization. Yours use 45LOC. That matches my experience with customizing styles on larger project, Chakra is 80% simpler to customize.
Since your contention was the LOC and ability to use nested CSS styles, I have taken your own example and matched it. Line to line. Using Material UI. Updated the above demo:
8 LOC of customization. Same styles you applied to your demo with a few syntactic changes.
Hope this convinces you that you can do exactly the same thing in Material UI as you can in Chakra. Because both use CSS-in-JS. What you can't do in Chakra is ability to change styles of nested components (note I am saying components instead of HTML elements) without worrying about implementation detail.
> The uniform API you are talking about is literally just nested CSS styles with emotion. It is possible to modify deep subcomponents style with emotion. It’s CSS Nothing more.
We are not changing CSS alone here. You can do nested CSS styles through Material UI too. But that doesn't make any sense when you have complex components.
If you are relying only on CSS styling then you are tightly coupling the implementation with presentation. Say you have a nested button that is an <input type="button"> in one component. So your nested CSS style in another component that includes this button component would be: "> input[type=button]". Now tomorrow, some developer on your team decides to change the implementation to <button> instead as it is more semantic. Then what happens? All places that have your CSS nested style goes out of whack because of this one change. Because you have hardcoded your nesting. You will then have to change all references from "> input[type=button]" to "> button" just to meet the change in the implementation detail.
What is the point of CSS-in-JS if you are going to use CSS nested selectors for inner components? You might as well just use CSS modules instead. If you want to do CSS-in-JS do it the right way. Use JS to expose APIs for your components and CSS to style those components by reference. That way your components are truly independent of each other. Right now with Emotion, changing styles for your nested component implies using nested selectors which makes your components tightly coupled.
Now let us make it more complex: What if you want to introduce a <div> in between your parent component and the nested <button> component, as a wrapper? Not only do you have to change your JS implementation but also change all nested selectors from "> button" to "> div > button". It is a big mess at this point!
With Material UI it doesn't matter what your implementation is. Your component can use an input[type=button] or button or heck a div that behaves like a button using ARIA roles. It can even be nested 10 levels deep. You can even swap it out with links and it won't fail. Because styling is applied through a JS interface rather than CSS nested selectors. The implementation takes care of where to apply the styles. For the person outside he is just changing the style of the inner component without knowing how it is implemented. That is the real beauty of CSS-in-JS. Not knowing implementation detail ahead of time.
We are using CSS-in-JS because of limitations of CSS: you can't define custom components in CSS. If you are going to do traditional CSS with nested selectors using CSS-in-JS then you are just doing it wrong! You don't even need CSS-in-JS at this point apart from it being just a convenience. You can just use CSS modules or regular stylesheets.
Please take a look at styled-system and proposed theme specification with variants. This is how you would expose your inner components for custom styling.
Variants are not the same as having an API to override styles of inner components. You can use variants in Material UI too (which btw is inspired by styled-system and prior art): https://material-ui.com/system/basics/#variants
Variants are defined by the implementor of the component in question. What I am talking about is overriding styles by the user of the component. One way to do it is through the ThemeProvider. But that does so globally. If I want to override a style for a particular component only in one place (and the nested components within it) then I will have to use CSS nested selectors or a nested ThemeProvider (which is hacky and ends up slowing down the app depending on how it is implemented). Then I am tightly coupling the implementation with the presentation. There is no API as such to change the nested component styles directly. That is the area where I feel Material UI does better. It has standardized how inner components are exposed to the World for styling. That standardization should happen at the library level instead of at application level. So whenever you import the library you know you have that option available to you too.
It looks like Material UI has its own implementation of styled-system which is great! They should have started with something like that from the start :-)
> What I am talking about is overriding styles by the user of the component.
Please take a look at theme spec where variants become part of your theme object. You use theme.js to provide custom variants to components. This is how you would let users to customize your components via well defined expressed API (typed with TS if you want) :-)
> One way to do it is through the ThemeProvider. But that does so globally.
You can have as many nested ThemeProviders as you want. This is not a hacky way but is the way if for some reason it's not enough for you to have 1 global theme object.
Material UI is great for what it does (implements said kind of design) but if material design is not what you want then using this library with its own layers of abstraction is a no go to me.
> There was a reason we stopped using inline styles...
A few things happened between the 2000's and today tho. Practices evolve along with tools and technologies.
We started styling our React components with CSS years ago at my job and we have been keeping doing so until today. While it works (if everybody on your team agrees to follow the same methodology and conventions, which is hard to enforce), it provides 0 benefits for us. We just went this way because it has always been the way to go while developing web stuff with Java, PHP, Django and friends. Separating the style from the structure while composing presentational components (Text, Box, etc) in a page doesn't actually make much sense and CSS maintenance, class naming and conflicts prevention is a real burden. I've been following the "CSS-in-JS" solutions (which have been developed to solve these exact issues) during the last years and it seems like they could help us focusing on what actually matters.
Note that you're not directly setting the size and the like. Instead, you're selecting items from a scale that should compose well together. They could advertise this better; I've read a post in the past that explained it well, but unfortunately I couldn't find it any more. https://styled-system.com might be a good place to start if you want to investigate why there might be more to it than you might assume at first.
I am sure there are plenty of cases where this approach works just fine.
I assure you that those of us who work on projects where this would not work are not simply bad at naming things and that’s the only reason we picked component based styles.
css was designed to style HTML documents. It was never designed to build rich and scallable apps thus we have all these libraries which fixes a lot of underlining problems.
Refactoring: I suppose one then just refactors js instead of css. And even simpler/safer? If using typescript to make the js and refactorings type safe
This is not a reason why people should not use inline style. Also, CSS was designed 23 years ago. A few things happened in web development since 2 decades.
> No, you give it a good class name. If something is a button, you call it a button
It just doesn't work when your app has 100 buttons. You can introduce a naming methodology like BEM but naming conventions are hard to enforce, annoying to follow, and there are always guys on your team who disagree with them (for bad and good reasons).
This seems to be a thing in the past 5 years or so. I've seen developers refuse to follow the existing coding style simply because there was no lint or prettier rule for it. Like, how fucking hard is it to match the style of the existing code base and not be a dick about it. These are lead and seniors I'm talking about. This is the type of thing junior devs should have learned their first month on the job.
I can't even imagine contributing to an open source project in the '90s or early 2000s and not matching the existing code with whatever I'm doing. I don't care if it's tabs or spaces or whatever variation of if-branch nesting you prefer. When I'm working on code that already exists, I leave my ego at the door and try to make the codebase uniform and coherent.
Hell, the whole reason prettier exists is because we think we can fix these anti-social developers with technology. And of course that doesn't work, so now you need tailwind or whatever.
nah. what about theming? you cannot do that with inline styles.
I think external CSS files for layout is always better than inline.
it's very hard to debug and fix UI issues. nowadays you fix stuff on the fly with your browser inspector. you copy the result and paste it in your CSS file.
cannot be simpler than that
> nah. what about theming? you cannot do that with inline styles.
Nobody is utilizing inline styles in that example. It _looks_ like inline styles but it not. It generates css class name behind the hood which you can override in multiple ways. Starting from the ThemeProvider or just like this:
Yeah, it's the new "utility CSS" thing that is basically just inline style with a bit less boilerplate. It's quick to get started with, hence its popularity, but it's not really great after that.
I'm not a huge fan of atomic CSS, but part of the idea behind it is it solves the "ever-inflating CSS bundle" as well as the "where do I put this CSS" problems, both of which are issues on large projects.
- TypeScript
- WAI ARIA / a11y for accessibility
- Passthrough styling props via Styled System: https://styled-system.com/
- Passthrough responsive conditional props: https://chakra-ui.com/responsive-styles
- Light / Dark: https://chakra-ui.com/color-mode (but it doesn't work on Gatsby: https://github.com/chakra-ui/chakra-ui/issues/305)
- I eschew some of the helper components like <Flex>. You are fine just using plain old Box as the shorthand props in Flex component don't add much. You can just pass display="flex" into a Box.
- Passing hover/active styling requires using PseudoBox (or a component deriving from it), so <Box> - or anything built on top of it - can't have hover colors directly. This means configuration for some components require additional wrappers
- Active! https://github.com/chakra-ui/chakra-ui
- Author is very courteous (if my limited interaction with him on the tracker is any indicator!) If you use Chakra and like it, you can support the creator via https://www.patreon.com/segunadebayo