Emotion CSS-in-JS Library

repository·main·Indexed 12 days ago

https://github.com/emotion-js/emotion

A performant and flexible CSS-in-JS library for styling applications using string or object styles with predictable composition. Includes framework-agnostic styling via @emotion/css, a React integration, and a suite of Babel plugins and presets for optimizations like minification, dead code elimination, and the css prop.

Tokens
54.9K
Snippets
230
Records
292
Agent score
95%

What's inside Emotion

  1. Use @emotion/server for SSR

    main

    The @emotion/server package provides three primary APIs for server-side rendering (SSR) workflows. These APIs allow you to extract critical CSS from your rendered components and inline that CSS into your HTML to prevent layout shifts and improve performance.

    The three available patterns are:

    1. Extract critical CSS: Identify the styles required for the current render.
    2. Inline critical CSS to a string: Inject the extracted styles directly into an HTML string.
    3. Inline critical CSS to a stream: Inject styles into an HTML stream for progressive rendering.

    For detailed API signatures and implementation guides, refer to the official SSR documentation.

  2. Explore the Emotion ecosystem of libraries

    main

    The Emotion ecosystem includes various third-party libraries designed to extend its functionality, such as responsive styling, framework integrations, and utility helpers.

    Key libraries include:

    • facepaint: Responsive style values for css-in-js.
    • ember-emotion: Integration for Ember.js.
    • vue-emotion: Integration for Vue.js.
    • CSS to emotion transform: A tool to convert CSS to emotion format.
    • ShevyJS: Configurable Vertical Rhythm & Typography in CSS-in-JS.
    • design-system-utils: Utilities for design system access.
    • styled-map: Maps props to styles.
    • polished: Sass/Compass-style mixins/helpers for JavaScript styles.
    • styled-conditions: Utility to conditionally apply CSS based on React props.
    • manipulative: A React devtool for styling emotion components in the browser.
    • emotion-tailwind-preflight: Merges TailwindCSS base styles into CSS-in-JS projects.
  3. Choose the right Emotion package for your project

    main

    Emotion provides different packages depending on your framework and desired API.

    • React users: Use @emotion/react for the React-specific API. For the styled component pattern, use @emotion/styled (which wraps @emotion/react).
    • Framework agnostic: Use @emotion/css if you are not using React or want a framework-independent way to apply styles.
    • React Native users: Use @emotion/native for the styled API and a css function that returns React Native style objects.
    • React Primitives users: Use @emotion/primitives for the styled API and a css function compatible with React Primitives.
  4. Explore Emotion-based component libraries

    main

    Several popular component libraries utilize Emotion for their styling engine. You can use these libraries to build UIs with pre-built, styled components:

    • react-select: Select components for React.
    • reactivesearch: Search UI components.
    • circuit-ui: A component library by SumUp.
    • govuk-react: React components following the GOV.UK design system.
    • smooth-ui: A UI component library.
    • material-ui (MUI): A widely used React implementation of Material Design.
    • mineral-ui: A component library.
    • sancho-ui: A component library.
  5. Use CSS labels for readable class names

    main

    Emotion supports a label CSS property that is appended to generated class names. This makes the class names in the DOM more human-readable (e.g., css-1abc-some-name).

    You can specify a label manually within a css template literal or an object configuration.

    import { css } from '@emotion/react'
    
    // Using template literals
    let style = css`
      color: hotpink;
      label: some-name;
    `
    
    // Using object syntax
    let anotherStyle = css({
      color: 'lightgreen',
      label: 'another-name'
    })
  6. How @emotion/babel-preset-css-prop works

    main

    The preset enables the css prop for your entire project by transforming JSX code to use Emotion's jsx function instead of React.createElement. It also automatically adds import { jsx } from '@emotion/react' to the top of files where it is required.

    Transformation Example:

    Input:

    <img src="avatar.png" />

    Output:

    jsx('img', { src: 'avatar.png' })
  7. Features enabled by @emotion/babel-plugin

    main

    Enabling @emotion/babel-plugin provides several optimizations and developer experience improvements:

    • Minification: Removes leading and trailing spaces between properties in css and styled blocks to reduce bundle size.
    • Dead Code Elimination: Injects /*#__PURE__*/ flag comments into css and styled blocks, allowing tools like UglifyJS to identify them as candidates for dead code elimination.
    • Source Maps: Enables direct navigation from browser developer tools to the specific style declaration within your JavaScript files.
    • Components as selectors: Enables the ability to target another Emotion component as a selector to apply override styles based on nesting context.
  8. Create custom Emotion instances with create-instance

    main

    While the default @emotion/css export is sufficient for most apps, you can use @emotion/css/create-instance to create custom instances with specific configurations. This is useful for:

    • Using Emotion in embedded contexts like an <iframe>.
    • Setting a nonce on <style> tags for security.
    • Using a container other than document.head for style elements.
    • Using custom Stylis plugins.
    • Running multiple Emotion instances in a single application (requires a unique key).
    import createEmotion from '@emotion/css/create-instance'
    
    // Create a custom instance
    export const { 
      css, 
      cx, 
      injectGlobal, 
      keyframes, 
      cache 
    } = createEmotion({
      key: 'my-custom-key'
    })
  9. Create reusable media queries

    main

    To avoid repetition and maintain consistency, you can define media queries as constants. These constants can then be used as keys in object styles or interpolated into template literal strings.

    Using in Object Styles: Use the media query string as a computed property name in the object.

    Using in Template Literals: Interpolate the media query string directly into the css block.

    import { css } from '@emotion/react'
    
    const breakpoints = [576, 768, 992, 1200]
    const mq = breakpoints.map(bp => `@media (min-width: ${bp}px)`)
    
    // 1. Using in Object Styles
    <div
      css={{
        color: 'green',
        [mq[0]]: {
          color: 'gray'
        },
        [mq[1]]: {
          color: 'hotpink'
        }
      }}
    >
      Some text!
    </div>
    
    // 2. Using in Template Literals
    <p
      css={css`
        color: green;
        ${mq[0]} {
          color: gray;
        }
        ${mq[1]} {
          color: hotpink;
        }
      `}
    >
      Some other text!
    </p>
  10. Compose styles using arrays

    main

    Emotion allows you to pass an array to the css prop to compose multiple style objects. The styles are merged in the order they appear in the array, meaning later styles in the array take precedence over earlier ones. This solves the standard CSS cascade issue where the order of definition in the stylesheet (rather than the order of application in HTML) determines precedence.

    import { css } from '@emotion/react'
    
    const danger = css`
      color: red;
    `
    
    const base = css`
      background-color: darkgreen;
      color: turquoise;
    `
    
    // 1. Only base styles applied
    <div css={base}>This will be turquoise</div>
    
    // 2. base overwrites danger because base is later in the array
    <div css={[danger, base]}>
      This will be turquoise
    </div>
    
    // 3. danger overwrites base because danger is later in the array
    <div css={[base, danger]}>
      This will be red
    </div>
  11. Stylis v4 breaking changes for Emotion users

    main

    Emotion 11 uses Stylis v4, which includes several breaking changes for those using custom plugins or specific CSS patterns:

    • Plugin Compatibility: Plugins written for Stylis v3 are not compatible with v4.
    • Prefixing: The prefix option is removed. To customize which prefixes are applied, you must manually adjust a fork of the prefixer plugin.
    • Custom stylisPlugins: If you provide a custom list of stylisPlugins, you must explicitly include the prefixer (imported from the stylis module) if you want automatic vendor prefixing.
    • @import rules: These are no longer special-cased. They must be placed at the top level of global styles and cannot be nested within other rules.