A lot of companies seem to be adopting to this new way of styling, but I'm perfectly happy with CSS where it's.
I just recently added support for it in RE:DOM redom.js.org/documentation
Didn't like the idea before, but there's many benefits:
I actually enjoy writting css, usually with something like scss. I don't mind CSS in JS; However I like the normal property names, not the javascript camel case. Right now Vue.js and Riot.js get the CSS in JS api correct. You can scope the style, import into a component and more. You also don't need to do all the extra typing like the react solutions. Lastly you can reuse css much easier if it is in the standard syntax and not js friendly.
I write a lot of CSS, and for the most part that means I'm writing vanilla CSS manually (no preprocessors, no build step, no compiling, just CSS in an editor).
There are a number of techniques though that I wish I could use with CSS that CSS isn't powerful enough to reach:
parentNode in JS)previousElementSibling in JS)document.querySelector() in JS):has(), :focus-within)innerHTML or value in JS)<, >, ==, <=, >=offsetWidth)offsetHeight)innerHTML.length or value.length)children.length)scrollLeft or scrollTop)<select> element when emptyheight: 0 to height: autoe.clientX and e.clientY for mouse cursor, or e.touches[0].clientX and e.touches[0].clientY for touchscreen)minmax() or Math.min and Math.max)vw, vh but based on percentages of an element's own offsetWidth or offsetHeight)<iframe> scalable without a wrapper or padding<textarea> or <input> auto-expand to contentsIf I want to style any of the things above my options are:
So these should all be things that CSS-in-JS should make possible. The question shouldn't be: "Should we use CSS-in-JS over writing CSS for these styles?", but rather: "Should we use CSS-in-JS over writing JS for these styles?"
However, having said all that I still haven't had a single client project using React, Vue, Ember, or any of these other frameworks where CSS-in-JS is common. So what use is it to me? If I can't use CSS-in-JS to style the WordPress site my client has and needs work on, it's useless to me. If I can't use CSS-in-JS for the custom CMS a client has built themselves (PHP-based, not Node) then I'm back at the start, having to write custom JavaScript for all of these techniques I might want to use.
This is where JS-in-CSS comes in! (Also called: CSS Reprocessors)
I much prefer the idea of using JS to reprocess CSS styles as often as needed after the page has loaded. This allows you to author CSS (with some extra features for JS to read) and then apply that JS-powered-CSS to any HTML, regardless of how the HTML got there. You don't need React, or a certain framework, or workflow. It could be as simple as writing:
<div id=eqcss>EQCSS Element Query</div>
<style>
@element #eqcss and (min-width: 500px) {
$this { background: lime }
}
</style>
<script src=http://eqcss.com/EQCSS.js></script>
Or, to build the equivalent demo using a totally different CSS Reprocessor:
<div id=cssplus>CSSplus Element Query</div>
<style>
#cssplus[test="this.offsetWidth > 500"] {
background: lime;
}
</style>
<script src=http://csspl.us/selectory.js></script>
There's an example of an 'element query' technique written in two different JS-in-CSS dialects: EQCSS and CSSplus. This is something CSS can't normally do — to set a responsive breakpoint on an element that triggers when that element is wider than 500px. Here in our example we have a tiny bit of HTML (and it doesn't matter what tool was used to write this HTML) one CSS rule, and a link to the JavaScript plugin that makes it work. Notice there's no build step, your HTML doesn't need to be processed — you can just write the HTML however you want, write the JS-in-CSS however you want, then it works when you view it live :D
I think JS-in-CSS (not CSS-in-JS) is the right abstraction to accomplish the long list of techniques I wish CSS could reach :D
CSS in JS isn't what I would call a best practice BUT there are some specific use cases where it might be advantageous. Component based CSS modules are a better approach in my mind. If CSS doesn't come from a stylesheet then it's hard to take advantage of a DRY CSS cascade.
CSS in JS is another thing which I really don't understand why it exists in the first place. It only tries to solve an effect, but not the root cause. Because the initial problem is that people don't know and don't care about CSS architecture. Even here in this very thread, people write about UI overhauls which mess up the entire CSS. How is that even possible, if you stick to stuff, like BEM and ITCSS and namespaces?
CSS in JS is really bad.
To answer your question, let's go back to where the problem was. Initially, before using things like styled-components, if you had used something like Bootstrap, you would use the same classes all over your app. If you want to customize something, then you would add more classes to your div and then add a particular style for that new class in your css files. Again, doing this becomes unmaintainable after a point of time since feature requests or UI revamp will make it a huge mess.
To solve this problem, you can use something like css-modules, in which you can create a separate CSS file and import that CSS file in your JS. It will, in turn, make your app componentized. So, when you want to add more styles in the future, you can only make changes in your components' CSS file. This becomes easier to maintain since you can extract your component, make CSS changes and you're done. You don't need to add extra classes to make it work.
For styled-components, I use it with Ant Design and it's working perfectly. Generally, if I need to make any changes to any of the framework's components, I wrap them inside a wrapper component. Let's say, I want to make style changes to the card component. I would create a file called card-wrapper and override the styles:
/**
*
* CardWrapper
*
*/
import Card from 'antd/lib/card';
import styled from 'styled-components';
const CardWrapper = styled(Card)`
border: 1px solid #eee !important;
border-radius: 0;
color: #333;
&:hover {
box-shadow: none;
}
.ant-card-extra {
top: 8px;
}
`;
export default CardWrapper;
This makes it very easy for me to make changes to the style in the future.
Hope this helps you! :)
Well I personally think it's overhead. But i think a lot of transpiler things are overhead created to make languages / dialects more "accessible".
The principle idea is a very good - as always - it's to scope the problems inside the component.
so there are no "side-effects" to the layout :) so what's the downside ? you bloat the payload and you basically f*ck up heterogeneous systems.
the upside ? you don't have to worry that a change in the component will affect another component.
So as Uros mentioned it's a use-case thing. I personally try to program so that things are available to be reused in as many ways as possible which means ... no JSS but SASS or LESS.
same goes with inline CSS mutations and so on .... there are very specific trade offs and you really have to know what you're doing otherwise it just boils down to taste.
Necessity, then it is all about what you do and how you do it. For example I really like styled-components it is refreshing and it does enrich CSS quite a bit in my opinion like all things it does come with drawbacks but if your whole application is JS that gets transpiled to HTML/CSS/ in my opinion you are better of coupling logical bits of your app in one place, that way if something breaks layout wise it is most likely to be caused by that component or that piece of CSS written in that JS file.
Edit: And by all means if you can keep things separate do so, that is best practice after all.
tl;dr__\_ It really depends on what is your use case, imho i see nothing wrong with CSS in JS_
Ben Buchanan (200ok)
I make some bits of the web.
I'm yet to see a compelling reason to adopt it. If you don't like it, don't use it - just because other companies adopt something doesn't mean it's right for everyone else.