chakra-ui icon indicating copy to clipboard operation
chakra-ui copied to clipboard

Add configuration option to <ChakraProvider> to prepend, not append, Emotion's <style> tags to the <head>

Open sgarcia-dev opened this issue 2 years ago • 1 comments

Description

Add optional configuration option to <ChakraProvider> to prepend, not append, Emotion's <style> tags to the <head>

Problem Statement/Justification

Chakra UI component styles are difficult to override by standard CSS classes due to Emotion appending Chakra's <style> tags at the end of the <head>.

This problem is better illustrated visually here: https://stackoverflow.com/questions/73073413/how-to-override-chakra-ui-or-emotion-css-in-js-styling-with-normal-css-class-n

This also makes frameworks like Tailwind CSS useless at overriding any kind of Chakra component. I'm aware that this is by design in some scenarios (Ex: you should be relying on Chakra's style props), but there are plenty of cases where using the as={MyComponent} provided has CSS classes that get overriden by Chakra's emotion styles.

This issue on Emotion's Github Repo also outlines a few more reasons why this should be allowed in Chakra's configuration; https://github.com/emotion-js/emotion/issues/2037

Proposed Solution or API

Allow for an optional configuration flag like <ChakraProvider prepend={true}>, or perhaps a <ChakraProvider appendSelector="[data-chakra-styles]">. This can rely on Emotion's Cache component that supports prepend out of the box.

Here's one way I got this to work using the above implementation;

import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { ChakraProvider } from '@chakra-ui/react';

const emotionCache = createCache({
  key: 'emotion-cache',
  prepend: true, // ensures styles are prepended to the <head>, instead of appended
});

export default function App() {
  return (
    <CacheProvider value={emotionCache}>
      <ChakraProvider>
      </ChakraProvider>
    </CacheProvider>
  );
}

I'm aware this should be off by default to stop chakra styles from being overriden and stop most people from having issues, but it would be really nice if developers could be given a choice here to make for easier implementation with existing CSS solutions.

Alternatives

No response

Additional Information

  • https://github.com/emotion-js/emotion/issues/2037
  • https://emotion.sh/docs/@emotion/cache#prepend
  • https://github.com/emotion-js/emotion/pull/2521
  • https://stackoverflow.com/questions/73073413/how-to-override-chakra-ui-or-emotion-css-in-js-styling-with-normal-css-class-n

sgarcia-dev avatar Jul 27 '22 00:07 sgarcia-dev

Would love to ditto this. We're having an issue with wrapping our exported Chakra components with styled-components. Since the styled-components style tags are being appended first, then emotions through the Chakra library. I also have the same fix as above.

const customEmotionCache = createCache({
  key: 'our-key',
  prepend: true,
});

<CacheProvider value={customEmotionCache}>
   <ChakraProvider theme={themeToUse}>{children}</ChakraProvider>;
</CacheProvider>

Would love to not have to reach outside to emotion directly and have Chakra handle the internals of emotion setup and expose configuration options for it. One thing I'm seeing with the above solution is that global style tags are still not appended, but rather prepended. Would love to see some solutions surrounding this :)

jake-chapman-mark43 avatar Aug 01 '22 21:08 jake-chapman-mark43

The author of stylis-plugin-extra-scope seemed to have the right idea - add extra scope. This way it doesn't matter what order they appear in, whichever has the extra scope wins. It looks like in this case the goal is for something else to override Chakra. If you want Chakra to override but only inside certain elements, you can use this modified stylis-plugin-extra-scope that supports v4 and doesn't add extra scope to :root because that prevents the much needed CSS vars from being declared.

https://github.com/chakra-ui/chakra-ui/issues/2584#issuecomment-1401393990

For this I suggest getting a build of tailwind css or a similar library with extra scope - maybe UnoCSS.

benatkin avatar Jan 24 '23 05:01 benatkin