question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Style System: CSS-in-JS Workflow

See original GitHub issue

Haiii!! šŸ‘‹

I’ve been thinking and researching a lot in various technical areas for component libraries + css. The notable topics involve performance and user experience (users being designers/devs).

Performance

Since there will be many instances of these components, it is favourable that they have high performance out-of-the-box, with little to no overhead from consumers of the library.

User Experience

The trade-off for having high-perf typically comes at a cost of the internal code being more verbose. This ultimately degrades user experience - for contributors working on the internals and for consumers of the library.

css vs styled

Without question, it appears that the (mostly) static css is more performant. There’s less computation, and there are far less component wrappers. styled offers a much more fluid user experience when it comes to (automatic) prop filtering, theme context consumption, composition and more.

For this ā€œsystemā€ idea, I’ve attempted to go with css.

Concept

I have a working example of this system concept. The main workflow revolves around a (singleton) system object.

From a component library workflow perspective, system offers 2 things:

  • A way to quickly access config values (e.g. color)
  • A way to render high performant (enhanced) React primitive components (e.g. system.div)
Example
import { css, system } from '@wp-g2/system';
const { get } = system;

// Defining component styles
const button = css`
	background: ${get('colorBrand')};
	border-radius: ${get('buttonBorderRadius')};
	color: ${get('colorBrandText')};
	display: inline-flex;
	font-weight: 400;
	justify-content: center;
	padding: ${get('buttonPadding')};
	user-select: none;
`;

const buttonLarge = css`
	font-size: 22px;
`;

// component library level
// uses system.base component
const Button = ({ isLarge, ...props }) => {
	return (
		<system.button
			cx={[button, isLarge && buttonLarge]}
			{...props}
		/>
	);
};

// consumer level
// overrides can happen with special css prop, enabled by system.base
const Example = () => {
	return (
		<>
			<Button css={`background: red;`} isLarge>
				Example
			</Button>
		</>
	);
};

I feel like this offers a balanced workflow!

  1. A ā€œCSS frameworkā€ layer is not required. An example of this would be something like Taychons or Tailwind.
  2. Library level: Main difference would be using system.div vs div. Otherwise, it’s mostly the same.
  3. Consumer level: Unchanged. A bonus would be the inclusion of a special css prop for ad-hoc modifications.

system.base

The system primitives are light-weight wrappers around React.createElement. They include a couple of special props that would be used internally.

  • cx : Accepts styles generated by css. Streamlines className merging with incoming props

The result is a much lighter component tree stack.

Before (using styled and BaseView)

Screen Shot 2020-07-18 at 12 05 24 PM

After (using css and system)

Screen Shot 2020-07-18 at 12 04 51 PM

system.get

The idea for get would be a hook-less way to retrieve (config) values for styling with css.

System Config

In order for hookless features like .get() to work, the system config exists as a singleton - not unlike (deep) emotion internals.

Link to Storybook experiments: https://github.com/ItsJonQ/g2/blob/master/packages/components/src/__stories__/System.stories.js

cc’ing @diegohaz ā¤ļø

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:30 (21 by maintainers)

github_iconTop GitHub Comments

1reaction
ItsJonQcommented, Aug 1, 2020

Extra Specificity (Automatically)

Oh boy! I just add a custom stylis plugin that boosts specificity of rendered styles.

That means, that (Emotion) generated styles automatically look like this:

Screen Shot 2020-07-31 at 10 35 01 PM

This greatly improves the reliability of these Components rendering into an environment with existing CSS rules.

Everything still works as expected āœŒļø

Note: This isn’t full-proof. Existing rules that are MORE specific (e.g. prefixed with an #id) still beat these.

1reaction
diegohazcommented, Jul 22, 2020

Also, another problem with the getter resolved at the module scope is that it’ll only return the initial value. If the theme is updated at runtime, styles will not be affected.

So, if we want to support theme changes, we would have to resolve the getter at a later point anyway, even using a singleton. We just wouldn’t need to use a hook or hook into React.createElement (jsx) to access the context. But we would probably need a hook to subscribe to the singleton changes. 😭

Read more comments on GitHub >

github_iconTop Results From Across the Web

Make sure styled-system is supported Ā· Issue #974 Ā· cssinjs/jss
I think the issue is that styled-system is accessing the theme via props and not from our themed styles function. EDIT: The reason...
Read more >
Enhanced Workflow with Styled-Components and Tachyons
Construct your page compositions with presentational and container components. If you're familiar with component-based systems, you may haveĀ ...
Read more >
Stitches — CSS-in-JS with near-zero runtime
Style your components with confidence. CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.
Read more >
All projects using JSS
It allows to describe style classes for components in a habitual and little less verbose way. PreJSS Fast, scoped, component-friendly and fully customizableĀ ......
Read more >
Bridging the Gap Between CSS and JavaScript: CSS-in-JS
CSS-in-JS libraries create styles at runtime by inserting <style> tags in the <head> . One of the first libraries to put this concept...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found