-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider using Radium for inline styles #684
Comments
A good suggestion. Any one shed view on this? |
Tried 0.8. |
Yes, vendor prefixing in radium is only client-side to keep the code small Server-side prefixing is hard to get right and there are good projects that On Wed, Jun 3, 2015, 6:36 PM Eric Fong [email protected] wrote:
|
Better to have same output from server and client. |
Doing proper prefixing means keeping a database of all necessary prefixes. On Thu, Jun 4, 2015, 5:58 AM Eric Fong [email protected] wrote:
|
Awesome just what I was looking for :) |
Thanks @wmertens - I think Radium is looking really good. I can see us moving away from doing our own inline style merging and prefixing and transition to use Radium. |
At the risk of starting a flame war, is CSS Modules a possible contender? |
I may be wrong, but I feel like CSS Modules is really closed to what Radium or react-look are providing. |
Good point (though there is rtlcss for postcss). What's your opinion about react-look vs. Radium? On paper, it looks like it ticks more boxes. |
At this point, I don't have any opinion. However, whatever we choose, I think that we need the following features:
This link could help https://github.com/FormidableLabs/radium/blob/master/docs/comparison/README.md @shaurya947 @rofrischmann @ianobermiller @javivelasco would you mind give your point of view on what's best and why? So we can make an informed choice. Thanks. |
Actually, debugging is easier with css modules since you can just play Css modules work fine together with inline styling for the rare occasions For me, the autoprefixing and debugging are the strong points of css. In |
First of all I'd like to say that I never had the pleasure to test CSS Modules which means I only know theoretically what's possible. Seems like the main question is Inline Styles vs. CSS (Modules) as I'd say both Radium and Look would do the Inline Job well.
API CompatibilityI am also not familiar with your existing style API, but as you're actually using Inline Styles I'd assume that the compatibility should not be the problem if you choose Inline Styles (Can't speak for CSS Modules). Pseudo Styles, Media Queries and SyntaxWhile Radium, Look and CSS Modules all support pseudo styles, media queries and a CSS/Sass-like syntax on client side, you might need some extra configuration to get those working on server-side if choosing Inline Styles, but it's nothing impossible either. Dynamic behaviorTalking about dynamic styling there's a huge difference. While with Inline Styles you're free to do whatever you want, CSS Modules still render to static CSS which means having e.g. props or state depending styles is not quite possible (Therefore this might be solved by using CSS Modules for static styles & Inline Styles for dynamic styles). In my opinion the dynamic behavior is the most important advantage of Inline Styles as especially within React Components your styles quite often depend on the components Extracting CSSThis is trivial with CSS Modules as it actually does this automatically. Extracting your Inline Styles to static CSS files would drastically lead to disadvantages (in my opinion) as you would immediately loos flexibility and dynamic behavior. JavaScript vs. CSSWhile CSS is just a descriptive StyleSheet language, JavaScript is a powerful programming language that allows you to quite anything with your styles. Autoprefixing SummaryCSS Modules win at extracting CSS, caching styles and developer experience. There's also an advantage on server-side as everything works just as expected. If choosing CSS Modules you might consider using them in cooperation with Inline Styles as @wmertens mentioned above. Additionally some information on Look especially for your use case:
Well, that's it. I hope I covered everything. Happy reading :P And keep in mind that this is still my own opinion as creator of Look. Feel free to contact me if you'd like to have additional information or other questions according that topic. |
Despite bringing them up, I'm not a biased proponent of CSS Modules. In fact, I still think I'm more comfortable with inline styles because I understand them better. However, to be fair, I want to point out that it's not quite true that CSS Modules take away the ability to be dynamic with styles in the code. After all, you still have to decide, in the code, which classes to apply. It just requires a different approach. That's even true of global CSS (after all that's why people write different classes), but because the CSS is always scoped locally, it theoretically should make it easy to reason about that logic. It would just mean writing different classes for the different style states and choosing them with something like |
@neverfox Well yeah, that's true. You can create multiple classes for different states, but you still need to predefine them which also assumes that every value is yet known while building. After you're build step there are just static CSS rules that should not be modified later on. And don't get me wrong: I still think CSS Modules is totally capable of this job. It's a great project with a great community and awesome contributor behind. |
@rofrischmann Thanks for this great comment! |
I'll second the fact that @rofrischmann's comment was great. |
Hi guys, first of all sorry for my late response, I've been so busy these days. I loved @rofrischmann effort writing his point of view and I think it's worthy to go with my opinion through the same bullet points. Also I'm adding a disclaimer:
API CompatibilityIt looks like if you use a solution like Radium its no big deal to generate stylesheets. If you choose CSS modules I think switching is way more complicated. You may be able to generate an specific style object for Radium from CSS... but each IS solution has its own API. This leads me to give +1 to CSS modules because CSS is already an standard. IS libs have close APIs but they are not exactly the same. Pseudo Styles, Media Queries and SyntaxYou can't get rid of classic CSS to make your app work on the server side. CSS modules provides media queries and psedudo-elements/selectors. Although you can achieve it with Radium it's more difficult to do. Dynamic behaviorHere Inline Styles are strong, but using CSS modules does not mean you can't use IS too. When you need dynamic behavior just add some inline styles. I think your UI depends on the state but usually a state refers to a bunch of CSS grouped on a class. Instead of providing styles when state changes just provide different classes. That's all. Extracting CSSNo need to do magic with CSS Modules for obvious reasons. I don't know much about Inline Styles but as far as I know, you'd need to extract to render on the server. JavaScript vs. CSSStill, if you need to perform dynamic transforms or something like that you can always add IS. CSS is for styling... and if you need variables, mixins, etc, you can use SASS on top of CSS. AutoprefixingPrefixing in CSS is so easy, just add an autoprefixer or something. With inline styles you can do it with libs too but it's not providing anything else in my opinion. SummaryWith CSS Modules your style is separated, allows the browser to cache styles and server side rendering works. Inline styles can be used along with CSS modules so its main advantage is not so important. Also, it's not a so usual scenario. Then, there is the theming issue... Theming with inline styles is difficult since inline styles have too hight priority and can't be easily overridden. It's true that there is no theming solution for CSS Modules either but you can use SASS loader and override SASS variables to customize components (see the approach in toolbox-loader). You can unveil structure in the component or provide custom classes to add your custom styles too. There are a lot of ways to solve the issue actually. Finally, the developing experience is poor since you browse the DOM and see nothing but CSS mixed with DOM nodes which makes difficult to identify your structures and debug. And also I want to point that CSS Modules are, of course, not a perfect solution either. You are forced to use webpack or browserify... but is it an issue?? Of course this is sooo opinionated. I understand why people support Inline Styles but at the moment I'm more a CSS Modules guy :) Thanks for asking for my opinion @oliviertassinari !! |
Wow. Great answer as well! Quite interesting to learn what people voting for CSS Modules think about it. Just one thing to add: I think in the end it basically depends on the liking of each individual user which one to prefer. Seems like you can achieve quite everything with both solutions. |
I agree with you @rofrischmann. As everybody says there are no better or worse solutions, just the most appropriated for your use case :) |
What about something like react-themeable? You'd still have to decide what to use for the default theme, but it would allow users to override the theme with whatever method they desire. FWIW, Radium does have server side support for prefixing (via inline-style-prefixer), and keyframes and media queries are in the works. |
CSS Modules with LESS/SASS or PostCSS chain solves most of problems with CSS mentioned in CSS in JS presentation. From library user perspective, sometimes it is necessary to bend the look of the compoment in a way that library authors could not percieved. And it is much easier to edit some stylesheets than to fork or try to PR component. With power of JS goes also responsibility, with inline styles it is possible to engineer logic into styling that is difficult to grasp for outsider. CSS rules and logic is at least well known albeit limited. Inline styles clutter component source, e.g. in TextField 8 out of 23 props are styles definitions with proportional part of component source. So I hope that you decide for CSS Modules and this awasome library will be even more awasome. |
Since this project is currently using inline styles, I think we should stick with inline styles (or more importantly continue defining styles in javascript instead of CSS). That being said, I still think there is value in investigating approaches or styling libraries that support extracting inline styles into CSS. Right now, I think jsxstyle is the first one I'd like to try out. Could it make sense to create a todomvc like project or branch that compares different approaches to styling for some of material-ui's basic components? We could use it as a basis for discussion and maybe we'll learn something. I get a feeling that if this project's goal is really to support both react and react-native, there may not be a single approach that works and we may need to investigate how we can apply style transformations at build time. |
I think that idea. But what ever is chosen, one of the things that will be important to consider is making some of the more complex components more transparent to styling all the way down the internal chain of components, to @jzelenka's point about bending "the look of the compoment in a way that library authors could not percieved". I've run into that with the current incarnation, e.g. AppBar, where the style prop can only affect the root element. This is also a good opportunity to circle back to the Material Design document because some of the components don't currently follow some of the more explicit specifications all the way, especially under responsive conditions. |
I agree with that 100% @dverbru. To add insult to injury, material-ui depends on |
Let me give another reason why inline styles have to go: component state. For example, It was designed only to open from the bottom, but in a project I wanted it to open from the top. With CSS, this would have been simple. With inline styles, it's not. Any import React from 'react';
import { Snackbar, Styles } from 'material-ui';
export default class FlashSnackbar extends ReactComponent {
componentDidUpdate() {
monkeyPatchSnackbar(this.refs.snackbar);
}
render() {
return (
<Snackbar
ref="snackbar"
style={{minHeight: 54, maxHeight: 96, display: 'flex', top: -4, bottom: 'auto', height: 'auto'}}
bodyStyle={{boxShadow: '0px 0px 0px 6px rgba(0,0,0,0.4)', background: Styles.Colors.amber100,
lineHeight: '22px', minHeight: 30, maxHeight: 90, height: 'auto', padding: '10px 24px 6px',
textAlign: 'center'}
... />
/>
);
}
}
// This is a really good argument for not using inline styles
function monkeyPatchSnackbar(bar) {
let getStyles = bar.getStyles;
bar.getStyles = function() {
let styles = getStyles.apply(this, arguments);
const {
desktopSubheaderHeight,
} = this.constructor.getRelevantContextKeys(this.state.muiTheme);
styles.root.transform = 'translate3d(0, ' + (-1 * desktopSubheaderHeight) + 'px, 0)';
return styles;
};
} (for whatever reason, overwriting There's no way to overwrite vital parts of component styles without looking into the source. |
So react-free-style is out of the question? |
@terrisgit Nothing is really out of the question and a decision hasn't been made. We know there are issues/challenges with the current implementation and we are working on refactoring the codebase to get to point where we can experiment with alternative style approaches/libraries. If you have any issues not already described above or anything you else you think that should be considered in the decision process, feel free to leave a comment and we will probably end up revisiting this whole topic when we're closer to ready to making a change. |
@STRML Thanks for your input. It's really appreciated! 😄 |
@dverbru Thanks for your input as well! 😄 |
I think the best way for us to evaluate this is to generate a list of requirements we have for this solution, then choose which library fits it best. Qualitative things like the size of the community / uptake help, but in the end we just should be doing what fits this library best. Here is a great list of CSS in JS Libraries for React. I'll edit this comment if there are good contributions below.
What I consider less important, but up for debate:
Of the items in the comparison, I think the top contenders are: Note I am not including Radium as it does not support extraction to CSS. IMO this is a step backwards and we've already seen what it feels like. I also have not looked through all of the list. There may be some I have missed. It appears that JSXStyle is the most fleshed out (or at least, it has the best README). Perhaps we should try converting a few components in each to really make a decision. |
@dverbru Now that I think of it, do you have any references for that, in particular with reference to vendor prefixes (not platform features)? In general, doing assuming feature compatibility via user-agent is indeed a very bad thing. But trimming prefixed properties is generally pretty foolproof AFAIK. Famous last words I guess. IMO I think we could drop the requirement wholesale and just use autoprefixer. It has great support and I agree that with gzip, the impact is negligible. |
This package seems like it could be used for react inline styles specifically: https://github.com/postcss/postcss-js I don't see why we couldn't implement that sooner if this is indeed the better approach. @STRML or @dverbru feel free to make a new issue on that particular point. |
Nice link @newoga. I agree that this would be worthwhile while we figure out the other issues. Porting is labor-intensive, however, so of course it depends on volunteer availability. |
Some responses to @STRML:
The particular implementation of using global.navigator may be poor, but using the
Your example has nothing to do with component state, and is a poor way to implement styles anyway. Ideally, the defaults should be some module level vars that cannot be overwritten at all. IMO this is a feature and not a limitation of inline styles; you can't muck with stuff that wasn't intended to be mucked with. For a library like material-ui, all extension points, including overriding styles, should be carefully considered to reduce the burden of breaking legitimate users with trivial changes. For example, if you are relying on some specific element hierarchy to do your styling via CSS, and they add in a wrapper div, your styles may break.
It's not really as bad as it sounds, particularly with rich editors (for instance, there is a nice Atom extension for incrementing values, e.g. 5px to 6px, with a Chrome-like key combo) and hot code reloading. Once your inline style library commits to extracting to CSS, you have to solve the precedence issue, particularly when composing components and using them in slightly different ways from which they were intended; the move to inline styles was motivated by some real issues with CSS. @newoga Honestly there is a lot of FUD in this thread, and I don't think the discussion has been super fruitful. I'd suggest locking it and just making the decision. Also I'm glad that Radium sparked your interest, but since the topic of inline styles is clearly bigger than Radium, you might want to change the title of this issue as well. Good luck with the choice, and I'd be happy to help evaluate the options (I did collate that gigantic table, after all ;). |
@ianobermiller Using Re: the state example, perhaps the component's source would make the problem more clear. Since we can't simply add a className to the component when it's Every element that has children needs to define extension points for each of its children, and for every possible state ( This is not a feature, being able to do something trivial like change the height or position of a component should not be this difficult. The developers can and should not be expected to anticipate every way that a user might want to use a component. Re: element hierarchy, I agree and believe this is even more of a reason to move to classNames. Otherwise, if the element you want to style has not defined every possible extension point, you need to rely on its internal structure to style it. Then, the library changes and your style breaks. That's why you use classNames via CSS modules or some other mechanism that guarantees non-clashing identifiers and support of :hover et al. |
More than a few.
This (the AppBar and IconButton are a good examples). I don't know if CSS Modules are the answer or not, but this is something to take seriously in whatever decision is made. One option (though I don't know how feasible this is) is to go heavily in the direction of avoiding overly nested uber-components. Make everything explicitly nestable and leave the building of complex components to the user (more like the approach of List and ListItem, for example). |
Yes, I said that; the problem is the implementation, not the concept.
Why is it worse to have a bunch of props instead of a bunch of CSS classes? I'd expect that an extensible component library has a significant number of extension points. A lighter-weight option would be to take in a
You will inevitably end up with CSS classes that are added to the component even though the default styles don't actually use them. Extensibility should be a conscious choice by library designers, not the default, as is the case with global CSS classes. But perhaps for a library like Another possibility is that the base components be agnostic to style; they offer an extension point for just about everything, and you could pass in either inline styles or a classname (or any props, I guess). I'm sure we could come up with enough abstraction to make writing such a component tolerable. |
@STRML All those issues are perfectly valid. We plan to promote composibility which will solve many customization issues. Plus we wish to add
It is planned 😁
I completely agree with you. our current implementation is very bad. granted. But it can be improved. My own opinion: Polluting global scopes (css classes) is a framework smell. Many things such as complex css queries can go wrong! I believe inline-style with user-agent aware prefixing is the future. Sure some implementations are weak for the moment, but atleast we will avoid framework smells, for example this discussion is going off topic. All these issues mentioned can be solved in both css and inline style. I'm all for inline-style. I think we should come to a conclusion on CSS vs Inline-Style first and then see what library/framework/method/concept to use or follow in that direction. Just as a reminder, this library used to work with css but then it migrated to inline-styles for what it's worth take a look at #30. @oliviertassinari @newoga @STRML @ianobermiller @neverfox @mbrookes And everyone else. Lets please discuss this before deciding on library. After the decision is made. I will lock this issue and open a new one for further discussions. Thank you everyone. |
IMHO it would be far better to adopt a solution, where we write the style in JS. Hence, I would just drop CSS Modules.
Yes, can we stick to radium in this thread and move to #1951 for the other style related discussion. Thanks. |
From google search, Material-UI is very professional grade and cleanly built framework that implements Google’s material design. As I can see in demo, it contains huge amount of best quality components. BUT: can it be used in large modern Web project, when I can read such information like bellow?
<button style="border:10px;background:none;box-sizing:border-box;display:inline-block;
font:inherit;font-family:Roboto, sans-serif;tap-highlight-color:rgba(0, 0, 0, 0);
cursor:pointer;text-decoration:none;outline:none;transform:translate3d(0, 0, 0);
vertical-align:bottom;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
position:relative;height:56px;width:56px;padding:0;overflow:hidden;
background-color:#ff4081;border-radius:50%;text-align:center;-webkit-appearance:button;"
tabindex="0" type="button" data-reactid=".0.1.0.0.1.1.1.0.0">
<div data-reactid=".0.1.0.0.1.1.1.0.0.0">
<div style="transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; top: 0px;"
data-reactid=".0.1.0.0.1.1.1.0.0.0.1">
<svg style="display:inline-block;height:56px;width:24px;transition:all 450ms
cubic-bezier(0.23, 1, 0.32, 1) 0ms;line-height:56px;fill:#ffffff;color:#ffffff;
-webkit-user-select:none;" viewBox="0 0 24 24" data-reactid=".0.1.0.0.1.1.1.0.0.0.1.1:$/=10">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" data-reactid=".0.1.0.0.1.1.1.0.0.0.1.1:$/=10.0">
</path>
</svg>
</div>
</div>
</button> instead of something like <button class="rui-button-float rui-icon rui-icon-plus"/> |
Performace section in google web fundamntals https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations recommends bem
and css module will make it easy. |
An in-between alternative that you may find interesting: https://github.com/rtsao/csjs |
I've decided to use BEM on my own projects, until something becomes standardized. IMO there are way too many bandaid solutions for this particular problem right now. |
@ffxsam CSS Modules feel exactly like BEM but with the benefit of isolation via automatically generated class names
.self { /* ... */ }
.header { /* ... */ }
.footer { /* ... */ }
import React from 'react';
import styles from './component.css';
export const Component = (props) => (
<div className={styles.self}>
<div className={styles.header}></div>
<div className={styles.footer}></div>
</div>
); No need to prefix every class name with "component_". After a compile step, the class names are all unique, and the Animations and Media Queries all just work. You don't sacrifice any CSS features, you just gain computer-aided isolation and the wonderful alleviation of stress that it brings. :) This approach works well with browserify and webpack. You can build to a single CSS file at the end, or have JavaScript load the styles, and you can combine this with CSS post-processing. There are ways to use SASS and LESS with this, too. |
Folks, we've asked several times to keep this discussion on topic, but as that doesn't seem to be possible, I'm locking this thread. While we're still exploring options for the future of styling in Material-UI, I think it's safe to say that it will be based on CSS in JS in some form. You are of course welcome to use whatever you wish in your own projects. |
https://github.com/FormidableLabs/radium adds "interactive" styles (hover etc) to inline styles, and also allows hierachical styles and automatic vendor prefixing. It's fast and pretty light-weight (32KB minimized).
The text was updated successfully, but these errors were encountered: