Is there something extra these React libraries do that prevents them from doing this?
Is there something extra these React libraries do that prevents them from doing this?
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.
I haven't used SCSS modules though.
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.
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.
How would you go about doing this?
--
Edit: to the person who downvoted me for asking a question. Classy.
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.
The best you can hope for is to forget about it. It's unsatisfying, but less unsatisfying than trying to get back at them or apply "sour grapes" or whatever. None of that works.
The sooner you put your brain on something else, the sooner you'll forget that somebody was a dick to you and got away with it. It sucks, but it's the least worst alternative. Treat it as noise -- which I think is what the OP was trying to say.
I also think it's worth calling it out too though.
Sadly, Chrome doesn't support this standard (it has been around for a while and is in HTML4, HTML Living Standard, CSSOM). But you can work around this by JS, see above.
(Edit: It's for things like this that you still want a menu bar for your browser.)
https://developer.mozilla.org/en-US/docs/Web/CSS/Alternative...
I’ve implemented that two ways: having JavaScript pop the alternative attribute off for all but the desired style sheet or simply using a top-level class to modify the relatively few things we were customizing. Back in the day, I used SCSS but CSS Variables have matured to the point where you can do an awful lot that way, too.
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.
myElement.style.setProperty('--my-custom-property', 'some-value');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.
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.
.rotatable {
transform: rotate(var(--rotation-angle));
}
...and set it directly with JavaScript document
.querySelector('.rotatable')
.style.setProperty(
'--rotation-angle',
`${angle}deg`,
);If 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
I think there is a fundamental difference in setting style properties in JS and setting CSS custom properties (even though CSS custom property is a style property). The main difference is that it is clear from the CSS that this property is dynamic and can be expected to change. If you overwrite a style attribute (e.g. `element.style.transform = "rotate(50deg)"`) this is less clear.
So in honestly I don’t see how setting a CSS custom property in JavaScript as lacking in expressing the intent.
With React, you don't modify the DOM directly, so the use case you have laid out is not applicable.
With that in mind, you are still free to use the CSS custom property with React, but if you want to have multiple transformations across multiple parts of an application, it's a lot simpler to use CSS-in-JS to generate styling based on state.
The use case you have brought up should work well with vanilla js/jquery; however, the context of the discussion is rooted in front-end libraries and the popularity of CSS-in-JS, so I am not sure how custom properties are relevant.
Also I explain on a sibling thread that there is a fundamental difference between setting a custom property (like I do here) and setting a specific style value. While I do see how the latter can be problematic as there are no hints to the changed style in the CSS file, the former does not have that issue, particularly if you name the property with a hint to the dynamic nature if it.
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.
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.
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.
I find it hard to believe you think you can do more with plain CSS than with the full power of the Javascript programming language.
However, when used correctly you can create a system that will allow you maintain and apply your presentation layer in an efficient, extensible, consistent and reusable way.
Lack of knowledge isn't an excuse for believing otherwise.
--
Edit: I'm actually shocked by how much bad feeling there is for standard front-end technology.
A domain specific solution is a benefit.
If that is your intention, typescript is a better tool for the job: you get type safety, ide autocomplete, tests (have you ever written a test for css?). You are right, being a domain specific solution is a benefit, but that has nothing to do with how good of a system you can make with it. I'm sure it's possible to write a system in typescript that would be as good as what you describe, but it will be more flexible at expense of being slower.
I think you are entirely incorrect.
Typescript is absolutely not the solution.
I also find much state has a nice selector (e.g. :hover, :checked, :invalid, :empty, :focus-inside, etc.) or media queries `@media (prefers-color-scheme: dark)` which I can change the custom property values inside. So it is really an exception when I manually need to change the value of custom properties with JavaScript.
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.
CSS in JS just isn't required a lot of the time. We have more mature methodologies available.
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.
> I've never seen a project that actually had meaningful "separation of concerns" based on technology.
With respect, you just need to look a little harder.
I've used react libraries which are fundamentally tied to their styling, due to the fact they use CSS in JS.
Applying custom styling has been more difficult than it should have been.
You're being obtuse. JavaScript is used for more than presentation.
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.
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.
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.
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)
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
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.)
e.g. const Container = styled.div` width: $props => props.width `