Skip to content
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

RFC: interface for writing styles which render to CSSOM #18677

Closed
kof opened this issue Apr 20, 2020 · 2 comments
Closed

RFC: interface for writing styles which render to CSSOM #18677

kof opened this issue Apr 20, 2020 · 2 comments

Comments

@kof
Copy link

kof commented Apr 20, 2020

I know it's a long-lasting and controversial topic and probably not the highest priority for the team right now, but let me try to create the first simplified vision for a CSS implementation we all could agree on.

CSS-in-JS like React is on a dual mission, supporting both complex apps and small(ish) sites. This has created a big divide in the community because of the very different needs that these types of projects have. Like React, CSS-in-JS was born out of the need to reduce the complexity of maintaining large applications.

While there are many options for authoring CSS, it is super tiresome to convince a team to use a particular approach. It creates a big divide and lots of frustration. While there is a huge value in not having a built-in solution and giving the space to 3rd party libs to thrive and experiment, the friction and frustration for not having a good built-in approach that covers 90% of use cases is real.

Goals

  • High-performance static styles via CSSOM. Rendering CSS only once and reusing across components and updates allows avoiding additional work within components render cycle.
  • Lists - inline styles have no way to be reused across list elements, where typically styles are repeated.
  • Support the full CSS spec. Inline styles are limited to CSSStyleDeclaration and we need to support the full spec on the web.
  • Adhere to React's component model and the upcoming Suspense architecture

Non-goals

  • Enforcing CSS-in-JS over vanilla CSS or css-modules (you can still use className)
  • Replacing every possible interface/idea CSS-in-JS libs came up with
  • Composition [separate RFC]
  • Overrides [separate RFC]
  • Dynamic or state-based styling [separate RFC]
  • Theming [separate RFC]
  • Alternative object-based syntax [separate RFC]

Proposal

Tagged templates

  • familiar syntax
  • syntax highlighting
  • linting
  • ability to return a data structure that react can identify, not just a string
  • interpolations
import {css} from 'react-cssom';
const buttonStyle = css`color: red;`; // {css: 'color: red;'}

render(<button style={buttonStyle}>x</button>)

Using style prop for both inline and CSSOM styles

Since we can return from the tag function any data structure we want, we can identify styles created using our css function and we have no problem accepting both types of styles.

Using the style prop allows us to be flexible in the future about how React wants to optimize and treat this interface.

That being said using a new prop like css is also an option:

render(<button css={buttonStyle}>x</button>)

Babel plugin

Babel plugin can be optional and can enable advanced features like:

  • vendor prefixing
  • optimizations
  • other preprocessing options e.g. using PostCSS

After babel plugin the call into css tag function can be removed and the result of the above example can be compiled to:

const buttonStyle = {css: `color: red;`}
render(<button style={buttonStyle}>x</button>)
@kof
Copy link
Author

kof commented Apr 20, 2020

Closing in favor of a PR reactjs/rfcs#159

I found a bunch of RFCs here as issues and thought this is the right way.

@kof kof closed this as completed Apr 20, 2020
@thysultan
Copy link

Something like the following:

// library
class Style {
	handleStyle(type = 'insert|update|delete', name = 'color', value = 'red') {
	// logic to insert styles in browser
	}
}

// author
<button style={new Style({color: 'red'})}></button>

// in react
if ('handleStyle' in style) {
	for (var name in style) {
		style.handleStyle(type, name, style[name])
	}
} else {
	// normal react logic
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants