Search code examples
cssreactjssassemotioncss-in-js

How to style body tag with CSS-in-JS approach?


I am a beginner to CSS-in-JS and emotion, and trying to port a sass react app to emotion. Right from the start I already have the issue of not knowing how to style the body tag.

Do people generally use document.body.style to do this? I can't find this covered anywhere ...

Suppose I want to port following code to emotion, how would that be accomplished?

$bodyFillColor: rgb(218, 236, 236);

body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  max-width: 100vw;
  background-color: $bodyFillColor;
  .noScroll {
    overflow: hidden;
  }
}

Have any best practices evolved yet that cover this?


Solution

  • With Emotion you can set something up, like the following create-react-app example, to inject global styles:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Global, css } from '@emotion/core'
    
    const bodyFillColor = `rgb(218,236,236)`;
    
    class App extends React.Component {
      render() {
        return(
          <div>
            <Global
              styles={css`
                body {
                  background: ${bodyFillColor};
                  margin: 0;
                  padding: 0;
                  min-height: '100vh';
                  max-width: '100vw';
                }
              `}
            />
            <Global
              styles={{
                'body.noScroll': {
                    // Prevent scrolling; conditionally activate this
                    // in subcomponents when necessary ...
                    overflow: 'hidden',
                },
              }}
            />
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    

    This shows an example of injecting a style on the body and also assigning a class to the body that can conditionally be activated later on.

    eg.

    {this.state.activate && <Global styles={{`stylesetc`}}/>}
    

    https://emotion.sh/docs/globals

    Alternative

    StyledComponents uses a CSS-in-JS approach and works great with React applications. This is a technique I've used in the past straight from the documentation:

    import { createGlobalStyle } from 'styled-components'
    
    const GlobalStyle = createGlobalStyle`
      body {
        color: ${props => (props.whiteColor ? 'white' : 'black')};
      }
    `
    
    // later in your app
    
    <React.Fragment>
      <Navigation /> {/* example of other top-level stuff */}
      <GlobalStyle whiteColor />
    </React.Fragment>