Decompose shorthand/compound styles to their constituent parts #95
Comments
Interesting. Sounds like a bug to me, I'll check it out. Unrelated to this bug, I would handle that style with box-shadow so that you don't need to deal with magic numbers for the padding: http://jsbin.com/gexavibeqa/2/edit?html,css,output |
@alexlande Thanks for the tip! Super helpful. After wrestling with Radium all weekend + chatting with @balanceiskey this morning, I’m rethinking whether this is a problem or not. IE 9–11 still have problems with computing margin + padding when values aren’t explicit. Perhaps it’s better just to always be explicit with “shorthand” margin + padding and avoid …Top, …Right, …Bottom, …Left altogether. However, that might put this issue outside the scope of what Radium is trying to solve. |
Unfortunately this is the expected behavior by React: facebook/react#2231 |
Hmm, that's unfortunate. facebook/react#2013 has more good information on this as well. |
@azazdeaz @alexlande Thanks for tracking those down. I’m all for being more explicit, but I am still curious in exploring the parse + merge idea as @syranide mentions. I guess we’ll see. |
@mattborn I've played around a little myself and from a technical perspective, by simply disallowing "complex" shorthands (like PS. I even played around with a React branch that entirely drops the concept of classes for the user, it only takes style objects and creates/shares classes on-the-fly at runtime. It's really surprisingly perfomant as it turns out you really don't use very many unique style combinations at any point in time. You avoid all the issues traditionally associated with classes (even specificity). |
@syranide Which React branch drops classes? Sounds nuts + awesome at the same time. |
@mattborn https://github.com/syranide/react/tree/classstyle , |
@alexlande Nice tip on box-shadow! I think for Radium, we should decompose shorthand/compound styles to their constituent parts before passing it on to React. That gives us another value add above plain inline styles and also eliminates this weird edge case. |
👍 |
1 similar comment
👍 |
Something like this might be useful: https://github.com/ksanders/grunt-css-longhand/blob/master/tasks/css_longhand.js |
Alternatively, we could just throw a warning whenever you have a longhand and a shorthand property in the same style object, e.g.
|
Thanks for taking care of this @ianobermiller! |
@ianobermiller I think the right way to handle this would be to allow mixing, but to take the more specific as an override. For example:
This is a really common pattern that lets you not have to specify the border multiple times. And it's pretty obvious you'd want the more specific value to override in every case. Thoughts? |
@natew yup, I agree to your point here. |
Yes, that is the ideal way to do it. Unfortunately to allow that style would require Radium to parse the As an example, |
@ianobermiller it's not actually browser junk, and From the spec:
|
This style of the spec is even more visible in rules such as animation, wherein the first time value is ALWAYS the duration, and the second time value is ALWAYS the delay, and so on... |
Good point, thanks @kumarharsh. The point still stands that I haven't yet found a JS library to properly parse shorthand properties :) |
Ok, I admit I did not look very well: https://www.npmjs.com/package/css-shorthand-expand. It certainly isn't lightweight, though. |
@ianobermiller Any update on this? I upgraded Radium on a project but now am getting heaps of warnings. I suppose I could add in css-shorthand on my own for the meantime. In all honesty, I'd trade the modifiers and all nesting for being able to use the mixed modes. Modifiers have almost no use to me, but mixed mode styles I use in nearly every component. |
Just looked at css-shorthand-expand, doesn't seem that big, no? Looks like ~100 lines total including all packages. |
And by 200 I mean maybe 500 but within an order of magnitude :) |
Including all dependencies, css-shorthand-expand is roughly 5k (after uglify + gzip). This would probably be better as a plugin, given the size. |
Another relatively slim module that someone pointed me to for this purpose: https://github.com/ActionIQ/style-builder Agree that this behavior makes the most sense as a plugin. |
And a blog post about it: http://www.actioniq.co/blog/reactjs-cramping-my-style/ Thanks @rgerstenberger |
@alexlande I looked at |
Cross-posting comment from #218 (comment). Quite annoying to see these warnings when it's done deliberately, e.g.; // utils.radium.js
export const resetBoxModel = { margin: 0, padding: 0, border: 0 };
// foo.jsx
import {resetBoxModel} from './utils.radium';
const styles = {
base: {
...resetBoxModel,
marginRight: 5,
paddingLeft: 10,
}
}; or are there better ways of doing this? |
@williamboman The warnings exist exactly for this reason. Your code is susceptible to the React issue mentioned above: facebook/react#2231 Considering that margin, padding, and border are the most common culprits here, perhaps we pull in style-builder just for those so the majority of people don't see the warning. |
@ianobermiller added in support for other ordering of border properties (like |
Ah, thanks for the heads up, missed that one.
Maybe make |
It should also be possible for us to include style-builder only in the DEV On Thu, Nov 19, 2015 at 8:46 AM William Boman notifications@github.com
|
You are welcome to contribute your experiences to this discussion: facebook/react#6348. |
It seems React 15+ has this problem solved? If so, is there a way to turn off the warnings from Radium? It's kind of annoying. |
I don't think React 15 did anything to solve this. |
I've reached this thread after searching for a solution to a different problem, but the two seems to overlap and what I want to be able to do would possibly solve both issues. I've been frustrated that while I can use variables for specific values in my styles, when it comes to more complex margin, padding and border definitions, I have to resort to writing a CSS value into a string. This feels out of place given that the rest of the definition are pure Javascript. What I would like to do is something like this: const big = 20;
const small = 10;
const styles = {
demo: {
margin: [small, small, big, big],
// margin: '10px 10px 20px 20px
padding: [big, small],
// padding: '20px 10px'
}
} This example has the margin and padding shorthand values set as arrays, which can then be compiled into a CSS string. const styles = {
demo: {
margin: [0, 10],
marginLeft: 30
}
} In this case, we would decompose In order to extend the model to variable shorthand properties like const styles = {
demo: {
border: {
width: 1,
style: 'solid',
color: 'red'
},
borderBottomColor: 'green'
}
} Again, Does this sounds like a viable solution? It looks like it would work to me, but I don't know the innards of Radium and the consequences this change would have. |
I like the idea! This should be very easy to do with a plugin. You can see a recent PR for an example: #703. |
This clashes with the margin style from the same place and causes a warning in the browser console: Radium: property "margin" in style object Object {fontWeight: "lighter", float: "left", marginLeft: "20px", display: "inline", lineHeight: "12vh"…} : do not mix longhand and shorthand properties in the same style object. Check the render method of Logo. See FormidableLabs/radium#95 for more information.
I have some buttons in a nav with a default padding value:
When selected, I add a thin left border + adjust only the left padding accordingly:
Unfortunately, when the item becomes unselected, Radium is using
0
for thepaddingLeft
value instead of the original20px
value. I’m assuming this is because I don’t havepaddingLeft
as a property in the default styles:I was able to fix this by changing
paddingLeft
topadding
+ using a more explicit string value:My gut tells me Radium should be able to intelligently merge related properties like
padding
+paddingLeft
,margin
+marginTop
, etc. on modifier changes.The text was updated successfully, but these errors were encountered: