Amplify UI Home

Overview

A Theme is a structured collection of design decisions that change the appearance of a UI library. An Amplify UI theme is a structured object of design tokens, breakpoints, and overrides. The goals of the Amplify UI theme are:

  1. Leverage platform technologies as much as possible for performance and broad support. This means plain CSS and CSS variables. You can always fall back to writing CSS (or a pre-processer to CSS like Sass).
  2. Use framework-specific patterns to provide an easier developer experience. This is using a createTheme method with a theme configuration which generates the CSS for you and can be used at build-time.

Getting started

Theme object

The theme object is where you define tokens for color palette, font stacks, spacing, and more. Use the createTheme method to create your theme. By default, it will extend from the defaultTheme Amplify UI provides, but you can also extend from another theme as well:

import { createTheme, defaultTheme } from '@aws-amplify/ui';

// by default, createTheme extends the defaultTheme.
export const myTheme = createTheme({
  name: 'my-theme',
  tokens: {
    colors: {
      font: {
        primary: { value: 'red' },
      },
    },
  },
});

export const myOtherTheme = createTheme(
  {
    name: 'my-other-theme',
    tokens: {
      colors: {
        font: {
          primary: { value: 'blue' },
        },
      },
    },
  },
  myTheme
);
// The 2nd argument is the base theme to be extended
// if it is omitted, it will use the defaultTheme

CSS

You can theme Amplify UI using CSS and CSS variables if you do not want to use the theme object structure. Amplify UI components use plain CSS so styling components can be done with CSS (or a pre-processor like Sass). All of the design tokens defined in the Amplify theme are CSS variables which can be overridden:

[data-amplify-theme]: {
  --amplify-colors-font-primary: #333;
  /* you can also use references: */
  --amplify-colors-font-secondary: var(--amplify-colors-neutral-60);
}

If you want more customization than the design tokens provide, you can also override the CSS for components:

/* All components have a class name starting with `amplify` */
.amplify-button {
  font-size: 2rem;
  padding: 1rem 2rem;
  background: none;
  border: 2px solid black;
}

.amplify-button:hover {
  background: gray;
}

Or if you prefer you can use alternative styling with a styling libraries

Unstyled

Amplify UI components can be use unstyled if you want full control over the look-and-feel. To use the components unstyled, import them as you normally would and do not import the CSS.

import { Button, Card } from '@aws-amplify/ui-react';

// don't import the CSS:
// import '@aws-amplify/ui-react/styles.css';

export const App = () => {
  // ...
};

Theme Structure

Design Tokens

Amplify UI uses Design Tokens for storing design decisions and is the primary way to theme the components.

Amplify UI follows the System UI Theme Specification with some modifications. The System UI Theme Specification outlines top-level namespaces for categorizing design token types. For example, colors go under the colors namespace. This specification is used by Stitches, Chakra-UI, and Evergreen.

WebOutlineWidths,
} from './outlineWidths';
import { radii, Radii, WebRadii } from './radii';
import { shadows, Shadows, WebShadows } from './shadows';
import { space, Space, WebSpace } from './space';
import { time, Time, WebTime } from './time';
import { transforms, Transforms, WebTransforms } from './transforms';

export interface Tokens {
  components: any; // TODO type this
  borderWidths: BorderWidths;
  colors: Colors;
  fonts: Fonts;
  fontSizes: FontSizes;
  fontWeights: FontWeights;
  lineHeights: LineHeights;
  opacities: Opacities;

References

One import thing about design tokens is they can reference other design tokens. The default theme tokens use references a lot to make a robust system where you can modify a few tokens to have a large effect. The syntax for design token references follows the draft W3C Design Tokens Community Group specification

const myTheme = createTheme({
  name: 'my-theme',
  tokens: {
    colors: {
      font: {
        // references colors.neutral.100
        // because the default theme defines that color already
        // we don't need to re-define it here
        primary: { value: '{colors.neutral.100.value}' },
      },
    },
  },
});

Breakpoints

Breakpoints allow you to set media query breakpoints for responsive design. You can then define breakpoint-specific token overrides or use the breakpoints for different layouts in Javascript.

export interface Breakpoints {
  values: {
    base: number;
    small: number;
    medium: number;
    large: number;
    xl: number;
    xxl: number;
  };
  unit: string;
  defaultBreakpoint: string;
}

export const breakpoints: Breakpoints = {
  values: {
    base: 0,
    small: 30, // 480px (16px base)
    medium: 48, // 768px
    large: 62, // 992px
    xl: 80, // 1280px
    xxl: 96, // 1536px
  },
  unit: 'em',
  defaultBreakpoint: 'base',
};

You can modify default breakpoints in the createTheme method:

const myTheme = createTheme({
  name: 'my-theme',
  breakpoints: {
    // createTheme does a deep merge with the default theme
    // so you don't have to override all the breakpoint values
    values: {
      // default unit is 'em'
      medium: 50,
    },
  },
  //...
});

Note: Unfortunately right now CSS media queries do not support CSS variables so there is no way to customize the breakpoints using only CSS.

Overrides

An override is a collection of design tokens that should take precedence in certain situations, like dark mode. Overrides are built into the theme configuration, but kept separate, so that Amplify UI can use CSS for overriding parts of the theme.

import { createTheme, defaultTheme } from '@aws-amplify/ui-react';

export const theme = createTheme({
  name: 'my-theme',
  overrides: [
    {
      colorMode: 'dark',
      tokens: {
        colors: {
          neutral: {
            10: { value: defaultTheme.tokens.colors.neutral[100].value },
            20: { value: defaultTheme.tokens.colors.neutral[90].value },
            40: { value: defaultTheme.tokens.colors.neutral[80].value },
            80: { value: defaultTheme.tokens.colors.neutral[40].value },
            90: { value: defaultTheme.tokens.colors.neutral[20].value },
            100: { value: defaultTheme.tokens.colors.neutral[10].value },
          },
          black: { value: '#fff' },
          white: { value: '#000' },
        },
      },
    },
    {
      breakpoint: 'large',
      tokens: {
        space: {
          small: { value: '1rem' },
          medium: { value: '2rem' },
          large: { value: '3rem' },
        },
      },
    },
  ],
});

You can override design tokens in CSS by using a media query or adding extra selectors to [data-amplify-theme="{theme.name}"].

@media (prefers-color-scheme: dark) {
  [data-amplify-theme='my-theme'] {
    --amplify-colors-black: #fff;
    --amplify-colors-white: #fff;
  }
}

[data-amplify-theme='my-theme'].disco {
  --amplify-colors-font-primary: pink;
}
Amplify open source, documentation and community are supported by Amazon Web Services © 2021, Amazon Web Services, Inc. and its affiliates. All rights reserved. View the site terms and privacy policy.
Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.