πŸ‘©β€πŸŽ€ CSS-in-JS library designed for high performance style composition

Last update: May 14, 2022

Emotion logo

emotion

The Next Generation of CSS-in-JS

Emotion 11 has been released πŸš€ See the blog post

Backers on Open Collective Sponsors on Open Collective npm version Build Status codecov @emotion/css size @emotion/css gzip size @emotion/react size @emotion/react gzip size @emotion/styled size @emotion/styled gzip size slack spectrum

Emotion is a performant and flexible CSS-in-JS library. Building on many other CSS-in-JS libraries, it allows you to style apps quickly with string or object styles. It has predictable composition to avoid specificity issues with CSS. With source maps and labels, Emotion has a great developer experience and great performance with heavy caching in production.

πŸ‘€ Demo Sandbox

πŸ“– Docs

Frequently viewed docs:

Quick Start

Get up and running with a single import.

npm install --save @emotion/react
/** @jsx jsx */
import { jsx } from '@emotion/react'

let SomeComponent = props => {
  return (
    <div
      css={{
        color: 'hotpink'
      }}
      {...props}
    />
  )
}

Do I Need To Use the Babel Plugin?

The babel plugin is not required, but enables some optimizations and customizations that could be beneficial for your project.

Look here πŸ‘‰ emotion babel plugin feature table and documentation

Demo Sandbox

Demo Code Sandbox

Examples

Ecosystem

In the Wild

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Thinkmill

GitHub

https://github.com/emotion-js/emotion
Comments
  • 1. Emotion 10

    Emotion 10 is going to introduce some new APIs for React users.

    The main aim with these new APIs is to move all insertion to inside the React tree, this enables a couple of things:

    • SSR just works because we can render style elements directly into the React tree.
    • Setting things like nonces, container elements and stylis plugins is much easier since it only requires a Provider at the top of the tree.
    • Global styles can change over time and be removed
    • It forces people to think in terms of styling elements instead of creating class names
    • The css prop works without the babel plugin because it's implemented as a custom createElement (this isn't necessarily a result of moving things inside the React tree but a side-effect of the new implementation)

    The main new APIs are a custom createElement for the css prop and a Global component for global styles.

    Example

    The exact APIs are likely to change before Emotion 10 is released.

    /** @jsx jsx */
    import { jsx, Global } from '@emotion/core'
    import css from '@emotion/css'
    import { render } from 'react-dom'
    
    render(
      <div>
        <h1
          css={css`
            font-size: 500px;
          `}
        >
          This is really big
        </h1>
        <Global
          css={{
            body: {
              backgroundColor: 'hotpink'
            }
          }}
        />
      </div>,
      document.getElementById('root')
    )
    

    If you want to try this, look at https://github.com/emotion-js/next but note that there will be breaking changes very often for now.

    Another change that e[email protected] will bring is that styled.div and etc. will work without a babel plugin. The tag list will be included in @emotion/styled but if you use @emotion/styled.macro with babel-plugin-macros or the babel plugin, styled.div will be replaced with styled('div') and @emotion/styled-base will be imported instead which doesn't include the tag list.

    Compatibility with Preact and non-React-like libraries

    While the majority of Emotion users use React, there are some users who don't use React and we have to figure out how to cater for them.

    Non-React-like libraries

    Since all the packages on the @emotion scope are very modular, we can build the current emotion APIs with the packages on the @emotion scope. This should be pretty simple.

    Preact

    There are only a few APIs that we use that are new.

    Fragment

    Fragments are only used for SSR so we could have an alternative SSR API for that similar to extractCritical now.

    createContext

    We could tell people to use create-react-context and essentially polyfill createContext.

    forwardRef

    We could conditionally use forwardRef so if it's not available then we don't use it. I'm not a huge fan of this because I think it would be confusing to tell people they should use ref when using React and innerRef when using Preact but I'm not totally sure yet.

    The other option to all of this is to not support the new APIs on Preact and have Preact users use the current emotion API.

    Migration

    This is something I'm still thinking about and I've got some ideas about but nothing concrete yet. I'm thinking of migrating emotion.sh and seeing what's difficult, how to make incremental migration easy, what can be done automatically with codemods and what warnings would be useful to provide.

    Removing extractStatic

    extractStatic hasn't been something that we've encouraged for a long time so @tkh44 and I think it's time to remove it. For people who like static extraction, libraries like Linaria and css-literal-loader do static extraction much better than Emotion does so those people should use those libraries.

    Only do transformations when emotion is imported

    babel-plugin-emotion currently transforms anything with the names of emotion's exports. While this works it transforms things for other libraries (#626 and #344) so we should only transform . I want to do this in Emotion 10 since it could be a breaking change for some people.

    TODO

    • [x] Support source maps in @emotion
    • [x] Try to make the keyframes API more convenient
    • [x] Reorganize some internals
    • [x] Add a babel plugin for hoisting objects in the css prop and adding a css call around the object since we can't use a babel macro.
    • [x] Add an alternative SSR API to get around the caveats with rendering style elements
    • [x] Add component selectors to @emotion/styled.macro
    • [x] Add a dev warning when :first-child and selectors like it are used and recommend replacements because of problems when rendering style elements in SSR and those selectors targeting the style elements.
    • [x] Move https://github.com/emotion-js/next into this repo
    • [x] Decide on how versioning should work since there are lots of packages that will likely have breaking changes that don't affect most end-users so should we do major versions really often(probably not) or do independent versioning for each package and if so should we start at 1.0.0 or 10.0.0?
    • [x] docs. docs. docs.
    • [x] Add a deprecation notice for extractStatic in babel-plugin-emotion and add a notice to the docs (if anyone wants to submit a PR for this, that would be great!!)
    • [x] Remove extractStatic
    • [x] probably more stuff
    • [x] Make it so the new snapshot serializer doesn't mutate the object that's passed in
    Reviewed by mitchellhamilton at 2018-04-27 23:59
  • 2. Emotion v10 unusable with pure TypeScript

    • emotion version: 10.0.0
    • react version: 16.6.3
    • typescript version: 3.1.6

    Relevant code.

    const flexContainer = css`
      display: flex;
      justify-content: space-between;
    `;
    

    What you did: I've tried to use it as:

    <div className={flexContainer.styles} />
    

    Or:

    <div css={flexContainer} />
    

    What happened: I've got this in html:

    <div class="
      display: flex;
      justify-content: space-between;
    "></div>
    

    Or:

    <div css="[object Object]"></div>
    

    I'm using only TypeScript without babel.

    Problem description: How can I use css or className with emotion v10 and TypeScript?

    Reviewed by krzysztofzuraw at 2018-11-28 13:55
  • 3. Emotion 11

    We're planning to do a major version of Emotion soon, we don't have a definite timeline but it should be out before the end of the year, most likely earlier.

    We don't currently have any massive API changes planned but there will be some package renaming which should be possible to migrate with codemods alone. (This isn't anything like the v9 -> v10 change)

    The big changes that we are currently doing:

    • Package renaming (#1635)
    • Use hooks internally which means a better tree in React DevTools and a smaller bundle size (#967)
    • Rewrite TypeScript definitions (#1501)
    • Allow mapping of imports in the babel plugin (#1220)

    We'll update this issue for larger planned changes. For smaller changes, please see the v11 milestone. The issues on the milestone aren't necessarily going to be addressed in v11 but we'll consider them.

    We are already doing pre-releases which will be available on the next dist tag on npm.

    Reviewed by mitchellhamilton at 2019-11-04 23:11
  • 4. Problems surrounding SSR injection of