Customize CSS class names via registerClass arguments.
mattferrin opened this issue · 20 comments
I find myself wanting to be able to customize my CSS class names.
var customNamed = Rcss.registerClass({color: 'red'}, 'custom-named');
I'm sure this has already been considered. What's the status?
Changing
function registerClass(styleObj) {
var styleId = generateValidCSSClassName(hashStyle(styleObj));
// ...
to
function registerClass(styleObj, className) {
if (className) {
var styleId = className;
} else {
var styleId = generateValidCSSClassName(hashStyle(styleObj));
}
// ...
seems like it will not have side effects.
That's a terrible idea. The whole point of RCSS is no conflicts.
I was aware it would introduce the ability to produce conflicts. Couldn't we produce an error or warning when a class is already registered, just check the class registry you'll probably be creating for server-side rendering. It would be nice to read friendly names when inspecting DOM elements in the browser.
@mattferrin for friendly names prefixing can solve it.
className + generateValidCSSClassName(hashStyle(styleObj));
This way the start of the class name is readable and the rest is still unique.
@Raynos I do like prefixing just fine. I feel that the hashStyle function would have to be future proof in that case.
The reason I like this repository is that I want to do everything in JS. I dislike JSX and love your h DOM syntax, by the way.
However, it is possible a CSS guru might want to style some HTML code and be unable to comprehend and learn JS. They would need to be able to style against these class names with the guarantee the hashing result will be future proof and not change on them ever.
@mattferrin https://www.npmjs.org/package/react-hyperscript ;) in case you havnt seen it yet.
Your use case is to write CSS using RCSS but support HTML templates instead of javascript templates? very interesting use case.
That is a valid use case but it should probably be a separate interface.
We should also document the use cases and caveats in the README.
@Raynos I bookmarked the cool node module. Thanks.
Sad but likely:
CSS designer wants to style a RCSS class via traditional CSS.
HTML designer wants to use a RCSS class via traditional HTML.
CSS designer wants to modify a RCSS class, but only sees the generated class name.
CSS designer wants to modify a JS template, but doesn't want to use an object.
Those are how I (as a developer) feel designers might think.
You may not like this suggestion. Let me say that if you're not worried about catering to designers that can't program, my suggestions may not be relevant :)
var RCSS = require('RCSS')('an-incredibly-unique-string-');
function registerClass(styleObj, className) {
if (className && anIncrediblyUniqueString) {
var styleId = anIncrediblyUniqueString + className;
} else {
var styleId = generateValidCSSClassName(hashStyle(styleObj));
}
// ...
@crm416 I enjoyed looking at your pull request #35. Do you believe allowing aliasing styleIds with custom class names is a bad idea?
var classNames = classNamesFromAliases("class-name-alias-1", "class-name-alias-2", ...)
var aliases = aliasesFromClassNames("c8b0d60e1f472a24c57b46052fe65b32a25f5b06d", "c9d9677913c937a6ef741e5467d8c6fe1987268c3", ...)
The idea would be to allow CSS and RCSS to style the same classes. I know you've played with LESS and RCSS and found CSS priority to conflict. Is interoperability between CSS, RCSS, HTML, virtual-hyperscript, and JSX class names a bad idea?
@mattferrin My first impression is that, yes, it's not a particularly good idea, the rationale being that there are a lot of benefits to be gained from having content-addressable class names. I also think that balancing CSS and RCSS will be painful (like you mentioned, the cascade makes this difficult), which sort of lessens my concerns RE consciously supporting it as a feature.
@crm416 I began to think the same way. It may be that your direction could eventually reduce the CSS to a bare minimum without any redundancy, which seems maybe more efficient to me. This issue can probably be closed, but I'll leave that to @chenglou or someone else.
Thanks for improving my understanding.
Maybe add a debug mode where your classes look like 'my-name-somecrazyid'. When you disable debug mode your class looks like 'somecrazyid'. The debug parametter can be on the css generator method.
This is useful if you use React transitions which requires you a postfix "-active" or similar. How to make transitions in react. How would you do that with rcss?
Relevant Features:
- prefix class name (prefix + hash)
- suffix class name (suffix + hash)
- registered class belongs to page (@bitplanets context suggestion to issue #28)
- content addressable hash (already done, but important)
- prefix class name in debug mode (prefix + debugPrefix + hash)
- suffix class name in debug mode (hash + debugSuffix + suffix)
Thoughts:
- Suffix is required for animations.
- Prefix makes just as much sense as suffix because animations could have gone either way.
- Registered classes belonging to a page seems better than instances of an object in server side rendering because addressing by page name is handy.
- I see no reason not to allow debug mode with customizable prefix and/or suffix save that I might not need it.
If we can determine which options are a no-go, we could implement the remaining (assuming there are any).
// possible registration call with options
var options = {prefix: prefix, suffix: suffix, pageName: pageName, prefixDebug: prefixDebug, suffixDebug: suffixDebug};
var customNamed = Rcss.registerClass({color: 'red'}, options);
Thanks for your answer @mattferrin but I've patched and made an wrapper for rcss which makes my life way easier. I will drop in an example as it is: https://gist.github.com/bitplanets/75bc0bec2432a1d33bd0 I hope you can understand, but the most important parts are:
css.setClass('panel-left', {
})
css.setClass('panel-left-enter', {
transform : 'translateX(-100%) scale(1, 1)',
opacity : 0,
}, {
styleId: css.getClass('panel-left') + '-enter'
})
Notice how you can get the class id css.getClass('panel-left')
easily. This has a context defined here var css = new SmartCSS();
so it will not have any interference with other modules.
Then is used here:
new React.addons.CSSTransitionGroup({
component : 'div',
transitionName : css.getClass('panel-' + this.props.side),
}, [openSidePanel]),
Where side
can be "left"
or "right"
.
Here is another use (from another file):
className : css.getClasses({
icon : true,
iconHover : this.state.hover,
}),
@bitplanets I see what your doing. I see how it helps you a lot. I can't view the wrapper module you require (SmartCSS).
Has not been yet released. But do you find interesting?
@bitplanets I believe in being thorough when I find time, which is why I read every issue on hashing to make sure I understood most the implications. Thoroughness is the main reason I was interested in the module code.
I find your syntax in issue #54 interesting. I think being able to access multiple classes or using getters and setters might be more powerful and extensible, but haven't thought through anything more complex than content addressable hashing to see if getters and setters have further use.
++ I would love readablename-{hash}
for the sake of fiddling in devtools
@jaredly here you have it: https://github.com/hackhat/smart-css the classes will be 'myname-1', 'some-other-name-2' ... (is based on RCSS but with a few goodies)
Look at the example https://cdn.rawgit.com/hackhat/fluxmax-smart-css/v0.0.1/dist/index.html and its source code https://github.com/hackhat/fluxmax-smart-css