8 ms·
Can someone explain the appeal of CSS-in-JS? I've used scoped styling in .vue components extensively, at a quick glance it seems to offer similar benefits (live
by MatekCopatek 5y ago
Can someone explain the appeal of CSS-in-JS? I've used scoped styling in .vue components extensively, at a quick glance it seems to offer similar benefits (lives right in your component and is scoped to it), but most importantly it can be extracted to a plain CSS file when building frontend assets.
Is there something extra these React libraries do that prevents them from doing this?
- jahewson 5y agoFor highly dynamic styles it allows me to avoid all the logic around coming up with class names and applying them. Think of it less like traditional CSS and more like a super version of inline styles.
- troll_v_bridge 5y agoCss-in-js helps minimize context switching for logic related styling, believe this is one of the main advantages from a developers perspective. It also allows javascript developers to colocate their CSS where they want, separate file, inline, same file, etc. This is more flexible than a .vue file in that sense.
- lwhi 5y agoI've never really been comfortable with the idea, as I was raised on the idea that separation of concerns is good thing. I think one of the main appealing aspects is the idea of never having a styling conflict with other components ever. Less macro-level management and organisation required. -- Edit: sorry, just realised you're talking about a specific implementation.
- stevebmark 5y agoCSS and Javascript aren't concerns, they're technologies, and separation of technologies isn't a software engineering principle. "Concern" is pretty undefined in general. If anything, they're all part of the "view" concern. It's the same reason why JSX doesn't violate separation of "concerns."
- rimliu 5y agoMoving goalposts is not a concern either. CSS and Javascript are concerns, becaus HTML is of content/structure, CSS is for styling and JS is for behaviour. Of course somewhere along the road devs thought that HTML and CSS are to primitive to spend any time learning them properly, because of that they later found them to bee too complex and we ended up in the mess we are right now, when we try to hide the lack of understanding under multiple wraps of abstraction.
- stevebmark 5y agoI don't think it's that clear cut, you can define all sorts of behavior with both HTML and CSS, and there's no semantic meaning in `<div>`, which itself changes page style due to its layout properties. I don't know what goalposts are being moved, React/css-in-js have never violated separation of concerns. After all, css-in-js produces CSS, and React produces HTML. Separation of technologies isn't a principle, but DSLs are a well established pattern.
- lwhi 5y agoIs complexity a drawback?
- stevebmark 5y agoWhat?
- lwhi 5y agoI believe any extra layer between intention and result will create extra complexity. CSS in JS just isn't required a lot of the time. We have more mature methodologies available.
- vgel 5y ago> CSS is for styling The web has never lived up to that ideal. Sometimes you need to add a wrapper div with no semantics to make your layout work. Sometimes you need some Javascript to do a special layout CSS doesn't support or work around some other limitation. I've never seen a project that actually had meaningful "separation of concerns" based on technology, whereas almost every componentized project has at least decent separation of concerns along the component axis -- where you can drop a component into a design without thinking about it's internals at all.
- tobobo 5y agoI don't see CSS-in-JS as a rejection of separation of concerns. In fact, one of the big advantages of CSS-in-JS is that it lets you decide how best to separate your concerns. Using hand-tuned CSS will undoubtedly be the most performant option, but it leaves you with very difficult problems at the boundary of your styling and content/structure concerns. If you have even a sliver of dynamic content in your website, it will quickly become near-impossible to verify that your content and styles work together as expected, or even to verify that your class names match between your CSS and HTML. On the other hand, if you use CSS-in-JS, what you lose in performance you gain in compatibility guarantees between your concerns, regardless of how you prefer to separate. Are you putting your styles in the same files as your layout components to fully separate one feature from another? Great, you can unit test those components and be reassured that the elements are styled as expected. Are you isolating your styles to only a certain subset of components that deal directly with styling concerns? Also great—if you're using TypeScript, you can guarantee correct use of those styles at build time. For a large enough team, those guarantees really pay off. If you have lots of customers using 2G/3G networks and want to hand-roll your CSS, I commend you! For most products, I think there's a better way to make that tradeoff and your users won't mind a slightly slower experience that has fewer bugs.
- lwhi 5y agoIf you want to replace all the styling in your project, because you've had a rebrand; I would argue that CSS in JS makes your life more difficult. If you want to share styling between your app and your website; I would also state that this process is made more difficult. If you want to create, implement and maintain an atomic design system to build in consistency and reuse .. again, more complicated that it might have been. To add to that, this article suggests that there's a performance deficit.
- The_rationalist 5y agoCss modules totally solve this without any css in js
- thoughtpalette 5y agoMain thing that I think would prevent it is the ability to use React Props/Arguments in your CSS. e.g. const Container = styled.div` width: $props => props.width `
- TimTheTinker 5y agoWe're migrating to styled-components at my current company. It's nice for abstracting components -- either into shared libraries or separate micro-clients that are composed together at runtime. In those scenarios, there are a few benefits: (a) no worries about accidentally trampling on someone else's styles, or styles from elsewhere overriding your styles; (b) build configuration is simpler; and (c) no worries about how CSS/SCSS is referenced/loaded - all references are handled in plain JS with no special loaders or anything. I wouldn't use it everywhere (I've used other approaches that have worked just fine), but for some scenarios it makes sense.
- 11235813213455 5y agolike you say, the benefit is to easily attach styles to components (in the same programming language, compared to scss/css modules) note: @emotion/styled is equivalent to styled-components, lighter and easier to set up for SSR (it works out of the box https://emotion.sh/docs/ssr#default-approach https://emotion.sh/docs/ssr#default-approach) When using server-side rendered pages, there's no performance loss on the client-side, maybe a little more processing server-side, not sure if significant
- alexchamberlain 5y agoDoesn't SCSS support CSS modules to prevent trampling on each others styles?
- WorldMaker 5y agoSome of the React libraries do support CSS extraction to plain CSS files. styled-components does not, and I'm not sure exactly why. It may be related to that they support runtime variables inline as React props and/or that they didn't want to complicate the build pipeline more than they already complicate it. (Many of the libraries like Vue's have necessarily tighter coupling with webpack or whatever other packer they use to get the extraction automated.)
- jfengel 5y agoI'm afraid I don't get it either. To me, the big disadvantage of css-in-js is that the browser doesn't display it neatly. If I write plain CSS, it's easy to make changes right in the browser and have it react instantly. Or I can make them in the .css file, and webpack (or whatever it is) will automatically redisplay them without having to restart the app. Perhaps if I had much larger projects I'd see more headaches that drives people to css-in-js. But I manage fairly large things and don't have too much grief with plain css.
- lwhi 5y agoImagine you need to implement an alternative stylesheet for people with increased visual needs (e.g. high contrast). How would you go about doing this? -- Edit: to the person who downvoted me for asking a question. Classy.
- notoverthere 5y agoSwitch the `<link href="">` value to point to a high contrast stylesheet. Or alternatively, apply a class to the body tag – e.g. `<body class="high-contrast">` – and declare CSS rules accordingly. Specificity should take care of overriding the 'normal' style rules where needed.
- lwhi 5y agoHaving to override styles that have random namespace tokens in the class names (via CSS in JS) is going to be difficult.
- easrng 5y agoI'd use CSS variables for colors and write another stylesheet, using the cascade so I only override the styles I need to.
- deleted 5y ago[deleted]
- 5y ago
- Kiro 5y agoI love not having to come up with class names. That's it.
- The_rationalist 5y agoYay let's loose semantic meaning aka understandability and reuse
- 1_player 5y agoNothing stops you from adding a semantic class name, if you need one. Let me remind you that a tag can have more than one class.
- eckmLJE 5y agoIf you have a lot of dynamic styles that respond to application state, then even with vanilla CSS you are often writing JS to manage class declarations to get the right CSS combinations. With styled-components, instead of adding/removing/combining class names, you can write javascript inside your declarations that use the state variables. For me, writing javascript that directly sets css properties based on state variables is a more powerful and clearer approach to managing dynamic styles than manually managing class names. Further, when combined with typescript, you can type a theme object in the styled-components theme provider and get auto-complete in your editor on your style tokens like colors, spacing values, timing in ms, etc. So it has many benefits beyond scoping styles to a component.
- lwhi 5y ago> For me, writing javascript that directly sets css properties based on state variables is a more powerful and clearer approach to managing dynamic styles than manually managing class names. I'd argue there's a lot more flexibility available if you choose to use classes. Sure, it's more complicated and involves more work; but to say it's less powerful just isn't true.
- iaml 5y ago> there's a lot more flexibility available if you choose to use classes That is simply not true. Apart from what was described in the post above, in JSS frameworks such as styled-components, you usually have ways to hook directly into css parser, allowing you to implement custom expansions, replacements or basically whatever logic you want. This is not possible unless you write your own language and transform it to css.
- deleted 5y ago[deleted]
- dheera 5y agoConsidering CSS is Turing complete I suppose we could also do JS-in-CSS.
- pentagone 5y agoWe actually do this at my company. Our user base is mostly security focused and browses with javascript disabled so we had to find another way to make reading a simple text with some pictures thrown in terribly slow for them. We like it so much that we are currently developing a server runtime for it called node.css. We are also working on a meta package manager based on this runtime so we can manage our dependencies on different package managers more easily.
- rajangdavis 5y agoIf you want to have a range of applicable values for some CSS property or state-based styling, CSS-in-JS can be a good tool for expressing that as opposed to writing JS that updates some styling declaratively. For example, I've used it on a personal app to allow adjusting the placement and opacity of controls. I prefer the CSS-in-JS approach because the code is simple to understand, I can reuse the code in multiple areas, and I can pass state to some function to generate the styling. I also imagine that I could also write some spec to support it, but it's not something that I plan on quite yet. It's not a technique that I would use for ALL styling, but I think for the use-case I mentioned above, it works great.
- The_rationalist 5y agoCss variables can be exported and modified in js through some libraries and without having the constraints of css in js.
- runarberg 5y agoYou don’t even need a library. Modifying a CSS variable is as easy as: myElement.style.setProperty('--my-custom-property', 'some-value');
- runarberg 5y agoThere are number of techniques that can fit that. State based styling can be achieved with simple class name toggles or CSS animation + the `animationend` event. If you don’t like toggling classes with JS there are number of selectors (including the attribute selector) which you can use instead. For making code easier to understand you can set a CSS custom property instead of specific style values, and the CSS will be really straight forward.
- rajangdavis 5y agoTo be clear - when I need to toggle a basic state with a class or set of classes, that is the strategy I use. Where that technique fails is when you have hundreds of possible values that can occupy a given state. If I want to set the rotation or opacity for a control and I want to use a range of values, there is nothing native in CSS to allow me to do that. You can use SCSS to dynamically generate the CSS class declarations for every possible value, but I would only ever use that solution if I needed the performance boost and that was the only way to get it.
- mekkkkkk 5y agoI've worked on and off with React since its inception, and the main reason I would use it is simple ergonomics. If you are working with an MVP or a small widget project, you gain a lot of velocity. You don't need to worry about scoping, naming collisions, class toggles, etc. and as long as you use decently small components, it all fits snuggly in the same file as the component definition. The price you pay comes in the way of performance and maintainability. Since the line becomes very blurry between styling and markup, it's up to the dev(s) to bring order to potential chaos. For any bigger project, my go to solution is SCSS modules. It's by far the most versatile solution I've tried if you want to roll your own CSS and not rely on a CSS framework. You don't need to worry about scoping, the bundle process is excellent, you have access to all of your normal SCSS shenanigans and most important it's a solution that makes it dead easy to collect or break down parts into logical units.
- Kiro 5y agoI've found it easier to maintain CSS-in-JS since I know exactly what will be affected when I change it. I'm always scared to touch the .css files on large projects. I haven't used SCSS modules though.
- mekkkkkk 5y agoWith my preferred SCSS module setup you get a hybrid solution with the best of both worlds. You can keep a clean stylesheet next to your component and then just: import { mainGraphic } from './component.scss'; [...] return ( <figure className={mainGraphic} /> ); Where `mainGraphic` is a regular class block in the SCSS. So it's pretty straight forward and the mapping is still fairly tight. At bundle time, the class name is minimized, deduped and a hash is added to it that corresponds to the rule content. The generated standalone CSS file also gets hashed for cache busting purposes. It's pretty neat. And since it's SCSS you can keep constants, mixins, functions, etc. imported and organized within and between SCSS files, separated from the components.
- iaml 5y agoNobody mentioned this, but for me big benefit is that you can remove everything related to css from webpack, and no dependency on ruby/dart/whatever else. Oh, also autoprefixer out of the box.
- the__alchemist 5y agoI think there's a conflation that confuses this: We have CSS in SPA components vs CSS, and inline CSS in HTML. In the latter, you may prefer inline to prevent flipping between files, and creating reusable data structures that are used once. In the former, you may have the same, or additional reasons like programmatically changing styles.
- betoharres 5y agoReact Native
- mmgutz 5y agoAn underlying appeal of React is it's just Javascript (yes even JSX templates). CSS-in-JS gives you the same flexibility and control over CSS from Javascript. No need to learn SASS, Less etc. It replaces the functionality those utilities with just Javascript. No setup required.
- hmsimha 5y agoFor anyone capable of using React, there's no barrier to 'learning' sass (you can be productive with it in about 30 seconds). Admittedly there might be some additional work around configuring compilation to work with the rest of your build and dev processes, etc. But sass in it's most basic usage (nested selectors) is really what CSS should have been.