This is for all the adopters of theme-UI. It would be fantastic to have a collection of how people use this tool in their project and together with which other tools. It obviously covers a real need since it has so much success. Let's see how people use this.
I'll start:
We're planning a refactoring to our project and are exploring different options of using theme-ui together with a common.scss file that holds a set of utility classes that don't fit inside a theme definition.
Hey @jxnblk,
I'll jump in here to expand on @mihaisavezi's comment (we're colleagues) and detail how we're thinking of using it. We'd really really appreciate your insights. Also, I'll try and be as short as possible (I hate long texts just like the next person, haha).
So, we're thinking of mixing ThemeUI with a few utility classes. For example this one:
/* common.scss */
.flex--center {
display: flex;
align-items: center;
justify-content: center;
}
After doing research and playing with the library, it seems like the ThemeUI way to have a nav with centered children would be something like this:
<Flex as="nav" sx={{ justifyContent: 'center', alignItems: 'center' }}>
...
</Flex>
I personally prefer the native classes aproach here because there are less abstractions:
<nav className="flex--center">
...
</nav>
Now, regarding pros and cons we thought of:
Pros
Cons
mr-2 - and we you have 2 approaches doing kinda the same thing. And one of them is not responding to theme changes.So yeah, the TLDR for me is: I see the value in ThemeUI & CSS-in-JS but I also see the value of classes in certain use-cases. Hope I explained it clearly, and thanks for doing such great work with all these projects (rebass, theme-ui, etc)
@iampava I've left this issue open since it sounded like an open question for the community. Use whatever works for you, but I've written a bit of my own thoughts on utility-based CSS here, since I sorta helped popularize that pattern along with Tachyons: https://jxnblk.com/blog/two-steps-forward/
Hey! Thanks for the article, really nice read.
I guess what I'm trying to ask is if you use exclusively the sx prop or related props when styling native elements/components. I'm thinking that a mix between this and utility CSS would be more desirable 馃
@iampava Yes, the sx prop can be used on any component that accepts className. In my experience, it tends to be easier to stick to one styling approach as opposed to mixing different ones together. You might run into cascade issues (source order, etc.), and the API surface areas can get unwieldy. Ultimately utility-based CSS like Basscss and Tachyons, etc. will never be able to provide everything a team might need for styles, but can work well for individuals and small sites
Ok, got it. What about offering the theme as CSS Variables for styling native elements - like <h1> - without the need for the sx prop?
I posted a comment regarding this here: https://github.com/system-ui/theme-ui/issues/499
@jxnblk I'm new to styled-system / theme-ui, I'm confusing should I just use props of styled-system:
<Box display="flex" justifyContent="center" width={[1, 1, 1/2]} />
Or use sx prop of theme-ui:
<Box
sx={{
display: 'flex',
justifyContent: center,
width: {[1, 1, 1/2]},
}}
/>
May I know which one is better?
@yeungc @jxnblk I also have this question. It may be a deciding factor for our team, since some devs feel like the sx prop is "just too ugly"
Hi guys,
I used ThemeUI on various different projects, I built a Design System based on the "styled-system props way", then I built various websites using the JSX pragma with the sx prop and also websites without the JSX pragma. So here is a quick review of my experience:
I think it's great to build primitive components (pretty much what Rebass does) for something like a Design System and for components that are used for layouting only. But the problem of this syntax is that you are basically creating a new styling API: your developers will have to learn what props are supported or not by each component. Also if you just allow every single CSS property as a component prop, you can introduce props naming clash...
I think this is a great approach if you want to force a limitation of usage of your components (so yeah again, for a Design System), for example a Button has a color prop because it has styling limitations (you don't want your developer to override its font family for example, but only a set of accepted/theme-aware prop). The styled-system props style makes this super clear.
It's great as you can directly use the sx prop on any component. However I experienced 2 issues with this workflow:
sx prop on top of a custom component that was already internally using it, etc.This is "my favourite way" to use ThemeUI:
Box primitive component (can be the one from rebass).Box component.sx prop, this prop is a normal React prop that is just passed down to the primitive Box component, that does the "magic ThemeUI stuff": const Button = ({ sx, ...otherProps }) => <Box as="button" sx={{ borderRadius: 2, ...sx }} {...otherProps} />
This way this is pretty easy to predict how your styles will be merged (it's just top > down).
Also @cameronwlewis you can adopt a similar style as when using Styled-Components even using the sx prop actually, it doesn't necesarilly makes things ugly (even if I have to admit you tend to put everything inline directly in your JSX and that can grow pretty badly).
const StyledContainer = props => <Container sx={{ p: 4 }} {...props} />
render() {
<StyledContainer>
<div>your content</div>
</StyledContainer>
}
Hope that helps,
I'm new to styled-system / theme-ui, I'm confusing should I just use props of styled-system:
<Box display="flex" justifyContent="center" width={[1, 1, 1/2]} />Or use
sxprop of theme-ui:<Box sx={{ display: 'flex', justifyContent: center, width: {[1, 1, 1/2]}, }} />May I know which one is better?
@yeungc Depending on the prop, you can use both in Theme UI! (You can only use theme values as props afaik, I might be wrong there鈥攚e should definitely document a list.) The balance I鈥檝e found in my own (extensive) usage of Theme UI is to only use the props for a few simple properties (whitespace, color, font size, typically) & if there鈥檚 more than 1-2 props, use them inside the sx prop, since you can then use them alongside arbitrary, non-theme CSS properties & the syntax is terser.
@hasparus We can close as a(n inactive) discussion I think :+1:
Most helpful comment
Hi guys,
I used ThemeUI on various different projects, I built a Design System based on the "styled-system props way", then I built various websites using the JSX pragma with the
sxprop and also websites without the JSX pragma. So here is a quick review of my experience:styled-system props way
I think it's great to build primitive components (pretty much what Rebass does) for something like a Design System and for components that are used for layouting only. But the problem of this syntax is that you are basically creating a new styling API: your developers will have to learn what props are supported or not by each component. Also if you just allow every single CSS property as a component prop, you can introduce props naming clash...
I think this is a great approach if you want to force a limitation of usage of your components (so yeah again, for a Design System), for example a
Buttonhas acolorprop because it has styling limitations (you don't want your developer to override its font family for example, but only a set of accepted/theme-aware prop). The styled-system props style makes this super clear.JSX pragma + sx prop everywhere
It's great as you can directly use the sx prop on any component. However I experienced 2 issues with this workflow:
sxprop on top of a custom component that was already internally using it, etc.Without JSX pragma
This is "my favourite way" to use ThemeUI:
Boxprimitive component (can be the one fromrebass).Boxcomponent.sxprop, this prop is a normal React prop that is just passed down to the primitiveBoxcomponent, that does the "magic ThemeUI stuff":This way this is pretty easy to predict how your styles will be merged (it's just top > down).
Also @cameronwlewis you can adopt a similar style as when using Styled-Components even using the
sxprop actually, it doesn't necesarilly makes things ugly (even if I have to admit you tend to put everything inline directly in your JSX and that can grow pretty badly).Hope that helps,