Skip to content

Instantly share code, notes, and snippets.

@victorouse
Last active October 10, 2019 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorouse/f7f2ddb3c78312443e67666a8296bf71 to your computer and use it in GitHub Desktop.
Save victorouse/f7f2ddb3c78312443e67666a8296bf71 to your computer and use it in GitHub Desktop.
🎨

Emotion

Examples

Using the css prop and POJOs

/** @jsx jsx */
import { jsx } from '@emotion/core'

const SomeComponent = () => (
  <div
    css={{
      color: 'hotpink'
    }}
  />
)

Also can write inline css via the css import

/** @jsx jsx */
import { css, jsx } from '@emotion/core'

const base = css`
  color: hotpink;
`

const SomeComponent = () => (
  <div
    css={css`
      ${base};
      background-color: #eee;
    `}
  />
)

Note: there is a babel plugin babel-plugin-emotion to do the pragma/jsx stuff

Using styled-components-esque api

import styled from '@emotion/styled'

const Button = styled.button`
  color: turquoise;
`

Additional

Styled System

Examples

You can easily add common props to components with nice (and responsive) shorthand methods

import styled from '@emotion/styled'
import { space, color, layout } from 'styled-system'

const Box = styled.div({
  space,
  color,
  layout
})

<Box
  // Arrays as values to set styles responsively using a mobile-first approach
  width={[
    1, // 100% below the smallest breakpoint (all viewports)
    1 / 2, // 50% from the next breakpoint and up
    1 / 4, // 25% from the next breakpoint and up
  ]}
  // These values are from a standard spacing scale, default to powers of 2
  // - p={1} -> padding={1} -> padding="2px"
  // - mb={2} -> marginBottom={2} -> marginBottom="4px"
  p={1}
  mb={2}
  // Sets the background-color to whatever value passed to bg here
  bg="purple"
>
  This is a tomato box, with responsive width, some padding, and margin bottom
</Box>

Can also be used as inline css, pulling values from the theme object (see: next section)

const Box = () => (
  <div
    css={css({
      width: [
        1,
        1 / 2,
        1 / 4,
      ],
      p: 1,
      mb: 2,
      bg: 'purple',
    })}
  >
    This is a tomato box, with responsive width, some padding, and margin bottom
  </div>
)

Setting up theme variables are defined as such

const theme = {
  colors: {
    primary: '#000e1a',
    secondary: '#fff',
    purple: '#007ce0',
    magenta: '#004175',
  },
  space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
}

Then injected via the ThemeProvider

const App = () => (
  <ThemeProvider theme={theme}>
    <div>
      <Box
        width={[
          1,
          1 / 2,
          1 / 4,
        ]}
        p={1}
        mb={2}
        bg="purple"
      >
        This is a tomato box, with responsive width, some padding, and margin bottom
      </Box>
    
      <div
        css={css({
          width: [
            1, 
            1 / 2,
            1 / 4,
          ],
          p: 1,
          mb: 2,
          bg: 'purple',
        })}
      >
        This is a tomato box, with responsive width, some padding, and margin bottom
      </div>
    </div>
  </ThemeProvider>
)

Theme UI (Optional)

Examples

Define as theme as per styled-system

const theme = {
  colors: {
    primary: '#000e1a',
    secondary: '#fff',
    purple: '#007ce0',
    magenta: '#004175',
  },
  space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
}

Inject theme via ThemeProvider and theme props become available via sx prop

/** @jsx jsx */
import { jsx } from 'theme-ui'

const App = () => (
  <ThemeProvider theme={theme}>
    <div
      sx={{
        width: [
          1, 
          1 / 2,
          1 / 4,
        ],
        p: 1,
        mb: 2,
        bg: 'purple',
      })}
    >
        This is a tomato box, with responsive width, some padding, and margin bottom
      </div>
  </ThemeProvider>
)

But how is this different from using just styled-system + emotion?

Theme UI uses @styled-system/css and the same theme spec that Styled System adheres to. Styled System is a much lower-level API that is not in any way coupled to React or Emotion. For example, Styled System works with Node.js, Vuejs, Svelte, and many other libraries. Theme UI is intended to be a higher-level abstraction specifically for use in React applications and includes features that will not likely be added to the core Styled System library.

A slightly more complex example can be found here, which from what I can see includes some extra nice-nice things like:

  • Layout: the root styled component for wrapping other layout components
  • Container: a centered area with a max-width
  • Box & Flex: are convenience components with a few style presets, similar to the ones found in Rebass.

That can be configured via theme

const theme = {
  ...
  styles: {
    Layout: {
      color: 'text',
      backgroundColor: 'background',
      fontFamily: 'body',
      lineHeight: 'body',
    },
    Container: {
      maxWidth: 1160,
      padding: 3,
    },
  },
}

And of course dark mode

const theme = {
  initialColorMode: 'light',
  colors: {
    text: '#392a25',
    muted: '#aaaaaa',
    background: '#f8f8f8',
    foreground: '#ffffff',
    primary: '#92b955',
    secondary: '#9f8a6d',
    modes: {
      dark: {
        text: '#ffffff',
        background: '#111111',
        foreground: '#333333',
        primary: '#1da1f2',
      },
    },
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment