-
Notifications
You must be signed in to change notification settings - Fork 174
Styled Components? #4
Comments
I'm personally find the syntax a little clunky. It feels like a clever abstraction to a problem that needn't exist. Having separate template functions to represent underlying tags could also get very messy, very quickly - Example: The first snippet given on the style-components site is: import React from 'react';
import styled from 'styled-components';
// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
<Wrapper>
<Title>Hello World, this is my first styled component!</Title>
</Wrapper> The 'ReactQL way' could be achieved as follows: style.css .papaya {
padding: 4em;
background: papayawhip;
& h1 {
font-size: 1.5em;
text-align: center;
color: palevioletred;
}
} app.js import css from './style.css';
const Component = (
<section className={css.papaya}>
<h1>Hello World, this is my first styled component!</h1>
</section>
) There are a few advantages to this approach, IMO:
Obviously, YMMV. Much of this is based on personal preference. To be clear, SASS is included as an option for legacy code that requires it, but the recommended approach is to write 'plain' next-gen CSS a la http://cssnext.io/. If you have a |
Concise as always. Thank you! |
My pleasure @kuka |
@leebenson I agree with your points above, but would you mind explaining how this approach would work in more dynamic scenarios?
I have this working with styled-components now, but as you pointed out, it does get rather messy and harder to work with so I would prefer to stick with PostCSS & cssnext if possible. |
@j-jackson - thanks for sharing that use case. I see three possible situations here:
styles.css .theme {
/* main settings that apply to ALL themes */
font-weight: bold;
font-size: 1.2rem;
/* ONLY the 'blue' theme */
&.blue {
color: blue;
}
/* ONLY the 'blue' theme */
&.red {
color: red;
}
} components.js // Lib for dynamically combining classnames
import cn from 'classnames';
// global styles -- pre-defined ahead of time
import css from './styles.css';
// assume that `user.settings.theme` contains the string 'blue' or 'red'.
// This might be gleaned from a DB that stores the user settings, or some
// other source
const themeClass = cn(css.theme, css[user.settings.theme]);
// Create a Button component with the user's chosen theme
const Button = () => (
<button className={themeClass}>Styled</button>
) In this scenario, you already know the user's theme and can set the appropriate classes just by selecting from that existing sheet. This might be a good choice if you have a limited selection of styles that can easily be described by simple strings.
Instead, we can use the native // Same <Button> component, but this time it takes the `theme` as a prop
// which is basically a plain JS object of CSS properties
const Button = ({ theme }) => (
<button style={theme}>Styled</button>
);
// This is the 'shape' we're expecting -- for example
Button.propTypes = {
theme: PropTypes.shape({
fontSize: PropTypes.string.required,
fontWeight: PropTypes.string.required,
}).isRequired,
};
// Assume `user.theme` is a plain JS object that contains CSS. We might get
// this from our NoSQL DB or from other async source. We can now use the
// button component like this...
<Button theme={user.theme} />
Instead, you want to download each This one is trickier because importing a secondary .css file from within the code-split component MIGHT mean that the .css file code path is scanned in Webpack and added to the main In any case, this option generally might be overkill. By the time PostCSS has stripped back white spaces, combined tags and generally optimised the css, and gzip has done its thing, including even a few hundred theme classes that may or may not be used is generally only introducing a few KB of overhead. It's often quicker to load the whole lot in one go (and one HTTP request) than to worry about saving a few bytes with a second HTTP request, as-needed. Obviously YMMV - especially if you're doing lots of fancy things in the CSS like loading extra fonts or included embedded images - but 70-80% of the time in my own projects, fiddling with CSS turns out to be over-engineering/premature optimisation. In any case, I'd like to test this scenario because it'd be useful to know the code path Webpack + the css loaders take in the scenario of async component loading. Will let you know what I find. |
Re-opening to track point 3 above |
@leebenson thanks for your detailed reply, I have learnt a lot from reading the issues! I started reading up on css-modules today, and I think a combination of 2 & 3 looks like a good solution to my particular use case, as it would allow for saved user styles via the I'm fairly new to webpack, but I will continue with this tomorrow and let you know if I find anything useful. |
I use styletron as CSS-in-JS solution and like it so far. Syntax is not that clunky. Who said designers have to work with css? Just extract given styled component in its own file and let the designers modify it without bothering with rest of the code logic. It's not that different as having them to learn LESS or SASS for example. But like I suggested in #20, CSS-in-JS is an "extra" feature and should not be part of this kit by default. Unless you go the (NextJs)[https://zeit.co/blog/next] route and ditch CSS entirely. CssNext is a good enough solution with vars and other improvements. I like it more than using LESS/SASS abstractions. |
The nice thing about styletron or similar is that enabling them doesn't require webpack changes. A user of this starter kit can I personally am not a fan of HOC for style. Writing CSS strings in JS doesn't feel natural to me, and in my professional life, the assets I'm delivered from a front-end team are usually plain CSS that I'd then need to wrestle into JS. I prefer keeping stylesheets separate, but for those that don't, styletron are easy drop-ins.
This is probably stating the obvious, but for the avoidance of doubt, CSSNext compiles down to plain CSS, so there's no concern of compatibility issues. Even if the CSS4 draft changes, it won't affect any prior compiled styles. Nested declarations are unnested, variables are hard-coded, etc - you're not relying on capabilities of the browser to parse this-- the browser sees 'plain', minified CSS.
Per #10, I think CSS and third-party (LESS/SASS) support can be relegated to an option at installation time. If you're using styletron or similar, you can simply drop them in at your convenience. The CSS compilation pipeline is one of the tricker aspects of setting Webpack up correctly. Getting import statements to play nicely across LESS and SASS means adding third-party libs like The point of LESS/SASS is that many third-party frameworks use them, so developers sometimes don't get the luxury of starting from scratch with their own tooling. If you want to edit themes in Semantic UI, for example, you're stuck with LESS. I want to make it simple to play nicely with common themes/frameworks. To that end, I should note that SASS/LESS integration currently works alright, but isn't completely finished. There are differences in the way imports are handled, especially when pulling from node_modules. Those fixes are on my to-do after playing about with code-splitting styles. |
This is a lib issue. The browser will always get easy to digest css, but if (theoretically) CSS4 changes specs for var(--name) CssNext would probably drop the old syntax in future release and you'll have to either upgrade your codebase, or just stuck with older CssNext version. PostCss could mitigate things with a separate plugin allowing old and new syntax, but this is a bad solution (especially for a lib trying to abstract such issues away from user).
Settings are evil. There is nothing wrong for having them, but each option add another use case to support. Unfortunately no solution can completely replace CSS and things would remain "foggy" for a long time. |
This is unlikely to happen. First, features such as I find nesting incredibly useful to organise styles, and IMO that was the biggest selling point of SASS and other CSS 'abstractions' to begin with. It's likely nesting will be supported natively in future browsers, but for now, CSSNext takes care of transpilation down to unnested classes, so this is unlikely to be a major stickler to maintainability.
What's the alternative? The point of this starter kit is to give developers a leg-up on the complexity of configuring common use cases of building React + GraphQL front-ends. Cutting this back to a 'base' starter kit that disavows CSS and other options contradicts the aim of trying to make complex configurations simpler. This isn't so much a settings, as it is a template. If a user chooses css support, then the starter kit is decorated with CSS support by injecting webpack config. Without it, it'd simply cut those pieces out. I'm trying to walk the fine balance of providing a useful starter kit where most of the obvious plumbing is offered done-for-you, but without so much bloat that it becomes a behemoth to manage. Everyone has different opinions on what makes an 'ideal' stack. I'd like to make it easy to skip the tedious set-up with complex config, but also make it simple to drop it when it's not needed. I'm open to ideas for how to play that better. |
Initially this ticket arose from the interest of why there were made certain choices like CSSNext. I’m of opinion that current state of this starter-kit does a great job at giving the initial setup. It saves a decent amount of time with the least amount of friction so those who are not that familiar with React + GraphQL can get up to speed quickly. That’s the whole point. As for CSS implementation, replacing it with any other can be done relatively quickly. The other point is that this repo could gain from a few branches with different implementations of styles and anything else for reference similar to what react-starter-kit has. That way main branch could be kept as simple as possible when other branches could provide a decent point for some variation in this stack. Everyone can put their effort into that without disturbing the main “KISS” branch. |
Maintaining multiple branches could be a lots of work, but with enough maintainers it's doable. |
I dropped a comment here that follows on from the idea of having different branches, BTW. |
Moving to reactql/kit#5 |
Just an FYI for those following this thread - I've updated this issue with an experiment on how Webpack handles CSS on dynamically loaded components. |
I know this is an old issue so may no longer be important to the OP, but v3 of the kit introduces Styled Components. I don’t consider my original observations to be valid any longer— I’ve used SC very successfully in production so it’s now part of the kit. |
@leebenson - I don't see SC mentioned anymore on the latest version. Has this changed since your last comment above? |
yep, I switched to Emotion. Similar premise, but with a better API IMO. |
Hey, Lee!
What are your thoughts on incorporating styled-components instead of SCSS?
The text was updated successfully, but these errors were encountered: