Skip to main navigationSkip to main content
Return to Sky UI homepage

Building with Sky UI

Learn to use and customise Sky UI components. Start with the Developer Quickstart for installation, then explore the code examples below. Examples with a live preview can be edited to see your changes.

Set up global styles

Add GlobalReset once at the top of your app, before the page content:

import { GlobalReset } from "@sky-uk/ui-core";
export default function App({ children }) {
return (
<>
<GlobalReset />
{children}
</>
);
}

It provides consistent browser styles and Sky fonts. See GlobalReset for details and the React Server Components guide for Next.js App Router usage.

Use a component

Import the components you need from @sky-uk/ui-core:

import { Box, Button, Text } from "@sky-uk/ui-core";

Try changing the Button's $variant from primary to secondary:

<Button type="button" $variant="primary" $marginTop={4}>
  Button
</Button>

Styling props start with $. HTML attributes and event handlers keep their usual names, such as type, aria-label, and onClick. Check each component's React API for supported props.

Use theme values

Use theme helpers for Sky UI colours and spacing. Here, color('primary') sets the blue background and spacing(4) sets the padding:

import styled from "styled-components";
import { color, spacing } from "@sky-uk/ui-core";
const MyComponent = styled.div`
background-color: ${color("primary")};
color: ${color("white")};
padding: ${spacing(4)};
`;
export const Example = () => <MyComponent>Hello world!</MyComponent>;

Define styled components outside the React component function. See Foundations for available values.

Use a basic modifier

Use a prop to switch styles. Here, $color="blue" selects blue; other values select red:

import styled from "styled-components";
import { color, spacing } from "@sky-uk/ui-core";
const MyComponent = styled.div`
background-color: ${({ $color }) =>
color($color === "blue" ? "primary" : "negative")};
color: ${color("white")};
padding: ${spacing(4)};
`;
export const Example = () => (
<MyComponent $color="blue">Hello world!</MyComponent>
);

Make styles responsive

Set different values at each breakpoint. Here, padding increases at lg. Open the fullscreen preview and resize the window to see the change:

<Box $border={true} $borderColor="black" $padding={{ xs: 4, lg: 6 }}>
  <Text>Compact spacing on small screens, more room on larger screens.</Text>
</Box>

Use system modifiers

Use applyModifierProps() to add styling props to your own component. This example adds colour and margin props, including responsive values:

import styled from "styled-components";
import { applyModifierProps, color, spacing } from "@sky-uk/ui-core";
const MyComponent = styled.div`
background-color: ${color("grey5")};
padding: ${spacing(4)};
${applyModifierProps({ system: ["color", "margin"] })}
`;
export const Example = () => (
<MyComponent $color="primary" $marginBottom={{ xs: 4, md: 6 }}>
Hello world!
</MyComponent>
);

Modifiers or CSS?

Use modifiers when someone using your component needs to change its styles. For fixed internal styles, use CSS. For example, these values are always set inside MyComponent:

import styled from "styled-components";
import { applyModifierProps } from "@sky-uk/ui-core";
const Wrapper = styled.div`
${applyModifierProps({ system: ["padding", "width"] })}
`;
export const MyComponent = () => (
<Wrapper $padding={{ xs: 4, lg: 5 }} $width="100%">
Hello world!
</Wrapper>
);

Write them directly in CSS instead:

import styled from "styled-components";
import { breakpoint, spacing } from "@sky-uk/ui-core";
export const Wrapper = styled.div`
padding: ${spacing(4)};
width: 100%;
@media (min-width: ${breakpoint("lg")}) {
padding: ${spacing(5)};
}
`;
export const MyComponent = () => <Wrapper>Hello world!</Wrapper>;

Add a custom modifier

Add your own styling choices with applyModifierProps(). Here, $appearance switches from red to blue at the lg breakpoint:

import styled, { css } from "styled-components";
import { applyModifierProps, color, spacing } from "@sky-uk/ui-core";

These imports are already available in the live editor. The outer function keeps the preview self-contained; in your app, define the styled component outside the React component function.

(() => {
  const $appearance = {
    red: css`background-color: ${color('negative')};`,
    blue: css`background-color: ${color('primary')};`
  };

  const MyComponent = styled.div`
    color: ${color('white')};
    padding: ${spacing(4)};

    ${applyModifierProps({
      modifiers: { $appearance }
    })}
  `;

  return (
    <MyComponent $appearance={{ xs: 'red', lg: 'blue' }}>
      Hello world!
    </MyComponent>
  );
})()

Composition

A custom Hero could take all its content through props:

<Hero
heading="Hero heading"
bgAsset="image-url"
cta={{
text: "click me",
href: "link-url",
}}
/>

Composition lets you arrange the content and add components without adding more props:

<Hero>
<Hero.Asset>{image ? <Image src={src} /> : <Video src={src} />}</Hero.Asset>
<Hero.Content>
<Text as="h2">Hero heading</Text>
<CustomComponent />
</Hero.Content>
<Hero.Actions>
<Button href="link-url">click me</Button>
</Hero.Actions>
</Hero>

This illustrates a custom Hero, rather than a component exported by Sky UI. See Hero Sections for the package APIs.

Keep heading levels and interactions appropriate to the page, and follow each component's documented child structure.