Closed ComLock closed 6 years ago
You could do that by just providing a custom createGenerateClassName
.
Docs: http://cssinjs.org/js-api?v=v9.8.7#generate-your-own-class-names
Quick question: Why don't you generate those styles and simply export the classes object?
styles.js
const stylesheet = jss.createStyleSheet({
dF: { display: flex },
});
stylesheet.attach();
export default stylesheet.classes;
index.js
import classes from './styles';
// Use classes like classes.dF
You could even strictly type the classes actually.
const styles = { dF: { display: 'flex' } };
const stylesheet = jss.createStyleSheet(styles);
stylesheet.attach();
const classes: {| [key: $Keys<typeof styles>]: string |} = stylesheet.classes;
export default classes;
I think you are talking about atomic css. I think you could achieve that with a plugin. The question is why? Usually with this model people try to reduce css payload. Also it allows a different caching strategy. At the same time it brings a bunch of problems.
@kof I guess its similar to atomic css, but I certainly do not like writing classnames for styling, I write style objects in js and generate css and classnames from it. No unused classes and low specificity is the result.
@HenriBeck Its the other way around. The stylesheet is generated from component style, not component style from predefined stylesheet. The developer never writes df, and should not care much about what the final classname becomes. The developer should also not need to think about vendor/browser prefixing. In case of conflicting frameworks I guess supporting prefixing could be a good idea.
@kof "At the same time it brings a bunch of problems." Any writeup of this. Very interested in knowing what those are.
Yes, its atomic rendering, but user doesn't have to care about it. I was hesitating adding this plugin, because of the debugging problems it would bring. It needs at the same time some linting tools.
@kof In terms of caching you are correct. Since the css is so small I typically inline it. So there are fewer requests. Reduces time to first paint on first visit, but doesn't affect future requests too much.
@kof Since everything is generated the arguments here are not so hard hitting: https://medium.com/simple-human/the-problem-with-atomic-css-d0c09c7aa38e
@kof "I was hesitating adding this plugin"
Which plugin? render-js is not a jss plugin. So you probably meant something else.
I ment a plugin for jss that would do this, I can write a bunch of things that are going to be a problem, but I will invest into this discussion only if someone is going to do it.
@ComLock If I understand what you mean, then instead of thinking about class names, you can think in JS variable names and just compose objects:
const red = {color: 'red'}
const bold = {fontWeight: 'bold'}
const df = {display: 'flex'}
const style = jss.createStyleSheet({
myEl: { ...red, ...bold, ...df }
}).attach()
const div = <div className={style.classes.myEl} />
@kof, if you make jss.createRule()
return an object which is instance of String
with a className
prop, and if jss.style
was alias for jss.createRule
, it would become easier to "inline styles":
const style = jss.createRule({ ...red, ...bold, ...df })
const div = <div {...style} />
// or
const div = <div {...jss.style({ ...red, ...bold, ...df })} />
// or
const div = <div className={style} />
const div2 = <div className={'other '+style} />
Also see TypeStyle, it makes excellent use of the pattern of mixing simple pieces of CSS, as well as making style sheet objects!
@trusktr I was also thinking of something like this, this interface was initially introduced by glamor. The problem with current createRule is that toString is already implemented and it returns a CSS string of the rule, not just a class name. It is a logical choice and I can't break it.
There is also glamor like interface on top of JSS https://www.npmjs.com/package/glamor-jss it has some quirks but can be used and fixed.
@kof Maybe then jss.style
could just be an alternative function? Also, if it receives multiple objects or falsey values, then it'd be even more concise:
// NICE! And still with JSS unique naming and SSR, and even caching!
const div = <div {...jss.style(red, active && bold, df)} />
There is also glamor like interface on top of JSS
Ah, cool!
Another idea: maybe jss
itself could be a function?
const div = <div {...jss(red, active && bold, df)} />
Whats the problem with using a separate package like glamor-jss?
I see JSS core as a lower level interface, it does not need sugar APIs, it needs correctness, customizability and performance. Everything else can be built on top.
Whats the problem with using a separate package like glamor-jss?
Nothing at all. But it's easier to import 1 package than 2, especially if if we don't know about the second package, then people will like JSS more out of the box.
I see JSS core as a lower level interface
Could be true, but honestly I never saw it that way. From the beginning I thought, "cool, a lib that let's me do clash-free CSS in JS easily with jss.createStyleSheet
! instead of "cool, I'm going to make another CSS lib on top of this".
I'd prefer to just have some bonus features in the lib I was already using.
It has evolved, there are many different interfaces now which use the core. Not knowing something can be fixed with better documentation and landing page. You can as well help here.
True, it could be as simple as adding glamor-jss to the "Abstractions on top of JSS" section
Its there since it exists. Also added on the first readme but not published to cssinjs.org because we are in migration to monorepo.
Oh okay, I see it in the Projects page. But where do we edit the menu for cssinjs.org to add it to the main menu? Or do you want only cssinjs
org projects there?
I think we can close this issue since it is not really actionable. The idea of rendering to atomic css is not new and if someone finds time I am happy to restart this discussion.
Is your feature request related to a problem? No, rather an idea.
Describe the solution you'd like So you may have heard about css tachyons, which is basically single purpose utility classes. Now remembering such tachyon names while programming is not what you want to do.
So while implementing my own html rendering library, I started generating such single purpose classes from style object in js. It also supports media queries. (I did not know about CSS-in-JS at the time). My code for generating css and classnames is spaghetti code :) So I was thinking what if a jss plugin could be written that did a better job than my code.
Example:
Becomes:
This means that any element that uses flex will simply have the class "d-f". The size of css becomes minimalistic, while the number of classes per element grows a bit ;)
There are more advanced examples here:
Perhaps there is some other framework (that I could not find) plugged into react that already does this? It would be nice to not be limited to React and do SSR.
Perhaps even compile time (though thats not to applicable for dynamic components where styling changes depending upon props).
Are you willing to implement it? Yes, but can I :)