-
Notifications
You must be signed in to change notification settings - Fork 79
Allow all UI components to accept extra class names and modifiers #33
Comments
How is this different from #31? Not exposing extra class names is by design. |
The rationale here doesn't seem to make sense anymore. In practice, CSS styles will leaks into every component because inheritance, and there's no way to firewall that from the JS side. Designers also have a lot of requirements that we have to implement as exceptions to the rules, we need a way to override the default classes on demand. |
I think a lot of these issues stem from the fact that we haven't finished the backbone migration yet. The component based styles don't use inheritance, the BEM styles are specific to the component and don't inherit styles from anywhere else. I would argue we want to push back against designers making exceptions to the rules - every exception they want to create makes the code base harder to maintain. If we make exceptions we should style them in the CSS for the page, not the component. The main value in using a UI library is the standardization of the components, this breaks that and I think its worth looking at other solutions. |
Typographic styles are inherited almost all the time, they affect sizes, in which there's no one-size-fits-all approach will work. The major problem now is there's no way to pass the props down to the inner components. Using page level styles is a non-solution. Many components like modal, tooltip etc don't get attached to a specific page. The form elements in them also often have style adjustments that we have to deal with. Without being able to add specific class names and modifiers, it's very hard to impossible to target these elements. |
I think What is an example of a form element that can't be styled at the page level? |
We have global typographic styles, and we'll always have them, unless you introduce a |
ID is also a terrible idea. Nobody is going to check if that ID exists already before putting an ID |
I think the point of using a UI library is to avoid global styles and I disagree we'll always need to have them. If you style typography at the component level, and always use I'm not really in favor of using CSS IDs either but I guess I don't understand the issue which is why I was asking for a specific example. What is wrong with this approach for page level styling of
|
The point of having a UI library is to enable logic reuse, not avoid global styles. There will always be a couple of links that need a couple of different colors, a few buttons that have so much text, the paddings and margins of their parents have to be readjusted etc. Yes we can wrap things in Also, text styles like The advantage of allowing extra class names is it enables the generated markup to be contextual and semantic, while giving us an anchor point for CSS selectors to target a whole section of decedents without introducing extra |
I still want to see an example of where this is necessary/desired. Let's be honest, we haven't made a ton of progress on the migration yet. I'm not convinced on the amount of pain this will eliminate in the short term versus create in the long. We've seen what mistakes can be made by allowing too much arbitrary flexibility in components (aka, everything I wrote 3+ years ago). |
This is a larger issue we'll encounter whether or not we have the entire app written in React. The Backbone stuff we have now is actually a combination of trying to generalize everything with configs, misunderstanding of the relationship between Backbone's model/collection/view, and how to arrange the views. Our customized ItemView is a major culprit, since it breaks the contract of both ItemView and CollectionView, spreading everything across dozens of JS module repos is another. Some modules are too tightly defined, like the modal. We have a number of modals that skip/have irregular steps, share data, and have different button combination and behavior. They are very hard to create using our internal backbone modal component. Here's how I imagine it should be done. Forms. We only allow 2 layouts now, and it's required. We simply cannot use them for what we are working on, because we have an irregular form that is required but does not fit into the 2 layouts. This is even more restrictive than Bootstrap. These are purely stylistic props, I don't think any modifier should be required, and if they are, the enumeration should be extensible without having the library user to come back to add one whenever there's something they need. For modals, we often have buttons with really long text in the footer, page rules and dedicated certs come to mind. What we often have to do is to override the button alignments and shrink the text. Some cards like Edge Certs also have really long buttons, and the parent containers, after being wrapped into a couple of <ModalFooter>
<div className="some-specific-footer">
<Button>{{"text"}}</Button>
<Button> <!-- How do I align this, another span wrapping it again? -->
<Text size="small">
{{"some really really long text that should be in a span or some phrasing content, but now it's in a div, and after we get rid of the block, the sizes still aren't right because the ideal size should be between small and normal so now we have to wrap yet another span but div under button still violates HTML spec oh god why"}}
</Text>
</Button>
</div>
</ModalFooter> /* yuck */
.some-specific-footer {
text-align: left;
.cf__button:nth-child(2) {
.cf__text--small {
display: inline;
span {
font-size: 14px;
}
}
}
} Or more simply, just give us back semantic markup, let us append a class name to the container that our custom component renders without having to target decedents in a maze of CSS. So we can do this instead: <ModalFooter classNames={{['some-specific-footer']}}">
<Button>{{"text"}}</Button>
<Button classNames={{['special-button']}}>
{{"some really really long text"}}
</Button>
</ModalFooter> /* Much cleaner */
.some-specific-footer {
text-align: left;
.special-button {
padding: 10px;
font-size: 14px;
}
} Granted, this is just 1 specific instance where a combination of existing cf-component deficiency manifest. We can make |
I don't know why this issue is being made to be so complicated when it's not Classes should be directly tied to the components which they are applied to. Scoping should be eliminated as much as possible, if not altogether. The reasons for this are based on the ideas behind using inline styles: http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html The only reason inline styles are not being used on cf-ui is because we were not allowed to open source CloudFlare's styles due to phishing concerns.
You should be treating the public API of cf-ui components as if they are using inline styles. Sure there are some limitations to inline styles, but working through that was an intentional pain point because it prevents you from hacking something together which will only add to code debt.
Let yourselves feel a little bit of pain so that you can create a better end result. Do not make the same mistakes that |
I'm just going to paste this link here for the many counter points against inline CSS. https://css-tricks.com/the-debate-around-do-we-even-need-css-anymore/ My favorite is, I don't want to see In practice, we have not seen one single React UI component framework that doesn't allow externally supplied There's a reason I haven't implemented this tho, I'm still debating whether we should go all out BEM, and reset every HTML element in every cf-component wrapper. There's some investment in tooling we have to do, but the benefit is we can still avoid inline styles like the plaque, (but can if we want to, supplied from both externally and internally), and have consistent, predictable style without having to worry about specificity and inheritance. The downside is obviously the component specific reset will still reset every wrapper override, and thus make inline styles a necessity. I'm still tending toward keeping global baseline styles as that CSS Tricks article suggest at the bottom. |
That's because most UI libraries aren't built by the sole company who uses them. cf-ui isn't designed to be general purpose, CF can make any change to it at any time. This concern isn't valid.
I've spoken to the React team directly and the teams that have been building React components for years at Facebook about this specific thing – it is considered by many to be a good practice. Inline styles is considered a best practice by pretty much the entire React community. You are going against the grain of thousands of developers who have more experience than this team. |
How do they deal with pseudo classes and media queries? |
There's a slightly out of date comparison of a lot of the libraries here: https://github.com/FormidableLabs/radium/blob/master/docs/comparison/README.md In that list these are all the libraries that support pseudo classes and media queries: Radium, React Inline, React JSS, ReactShadow, React Free Style, React Inline CSS, React Look, React Statics Styles, react-styl, smart-css, Stilr However, there's three that are not on that list that I currently find the most interesting:
^ All three of those support pseudo elements and media queries as well The cool thing about inline styles is that when you decide to use them it's really easy to do major refactors across all of your styles. This is why you see people iterating so quickly on different ideas for libraries. We're starting to get into the phase where people are building inline style tools that can optimize your css just by nature of how they work (ex. virtual css w/ styletron). The benefits to inline CSS are only going to keep growing over time. |
Haha I knew you were going to say something along that line. To use media queries, besides extracting out an actual .css file, I've seen people embedding I don't see Radium and all the other ones in that comparison will catch on until the browsers do something about these problems (i.e. allow media queries and pseudo class in inline styles, and provide a JS API at the HTMLElement level for them, or better, Shadow DOM). Either that or provide an easy way for us to extract a global style sheet out of the JS code base (Radium knock knock). Styletron is something I've never heard of before and it looks interesting. It claims it has a solution for the critical rendering path problems but it doesn't say how it works. It appears to have hooks to extract a global style sheet from JS. I'll look into this one. A lot of the recent trends in React come from people who want to bring mobile development approaches to the Web without understanding the limitations. Mixing structure/look and feel/behavior into the same files is something the Web community hasn't explored in over a decade, I think it's wise to take a cautious approach instead of jumping into the new and shiny right away. P.S. This post is a bit outdated, but I think it's still worth a read. |
@thejameskyle Just so we are clear, do you suggest us wrapping every cf-ui component with our internal component in order to apply some styles? |
https://github.com/MicheleBertoli/css-in-js This list seems to be more up-to-date. The ideal feature set should be 1,1,1,0,1 (need real CSS for fallbacks) or 0,1,1,0,1 (assuming autoprefixing can be added to the CSS extracted). There are only 2 tools that satisfy 1,1,1,0,1 (cssx, styled-jsx), 7 for 0,1,1,0,1 |
@wyuenho you have a serious attitude problem. I've gone out of my way to help CF's open source in my free time. You are representing a company on a company project, you need to act like a professional. |
A lot of the components have hard coded class names and states that get appended to the class names, but we can't append to the class names when customizing, either to override the styles in a specific component in a certain context, or introduce contextual BEM modifiers that will only be apparent at the use site.
The text was updated successfully, but these errors were encountered: