kriasoft / isomorphic-style-loader

CSS style loader for Webpack that is optimized for isomorphic (universal) web apps.

Home Page:https://reactstarter.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CSS injected in the wrong order

allotrop3 opened this issue · comments

I've created a repository to reproduce the issue I am having. Please refer to the readme, which explains the issue.

https://github.com/allotrop3/isomorphic-style-loader-injection-issue

Apparently _insertCss has an prepend option - not documented, unfortunately - that allows us to control the order of the styles as the default behaviour is for the last useStyles called - normally in the innermost child - to be appended at the end.

This example reverses the order which ensures that parents' - outermost then topmost - styles gets added in the end, therefore overriding the children's.

const insertCss = (...styles) => {
  const removeCss = styles.map(style => style._insertCss({ prepend: true }));
  return () => {
    removeCss.forEach(dispose => dispose());
  };
};

In the previous example we need to be careful when using the children outside their Overriding parent

<>
  <OverrideAppBackgroundColor /> {/* This will cancel the override below */}
  <OverrrideOverrideAppBackgroundColor /> {/* This will get the same style as the one above */}
</>

We can solve this by adding an override option:

const insertCss = (...styles) => {
  const removeCss = styles.map(style =>
    style._insertCss({ prepend: !style.override })
  );
  return () => {
    removeCss.forEach(dispose => dispose());
  };
};

// OverrrideOverrideAppBackgroundColor.js
// ...
const Outside = () => {
  useStyles({ ...styles, override: true });
  return <OverrrideOverrideAppBackgroundColor className={styles.app} />;
};

But it's better to not depend on it as things could get messy if OverrideAppBackgroundColor had override: true too. If that happens it might be worth it to consider loading the overriding styles in a higher component to control the order:

useStyles(overrideStyle, style);