# Styling for Clerk Elements

> This feature is deprecated. With the release of [Clerk Core 3](https://clerk.com/changelog/2026-03-03-core-3.md), the redesigned [hooks](https://clerk.com/docs/reference/hooks/overview.md) are the recommended replacement for building custom flows. They expose stateful objects, step methods that map directly to the flow, and structured field-level errors out of the box, so you no longer need to manage attempt status, loading states, or error parsing yourself.

> - Clerk Elements is for [advanced use-cases](https://clerk.com/docs/guides/customizing-clerk/elements/overview.md#why-use-clerk-elements) that require a high-level of customization. The easiest way to implement Clerk is with our [all-in-one UI components](https://clerk.com/docs/reference/components/overview.md).
> - Clerk Elements currently only works with Next.js App Router and [Clerk Core 2](https://clerk.com/changelog/2024-04-19.md){{ target: '_blank' }}.

You can style Clerk Elements components with the following props:

- `className` – Can be used on any Clerk Elements component that renders markup.
- `asChild` – Can be used to change the rendered element entirely.

This guide will demonstrate multiple different styling approaches using the following basic sign-in flow as a starting point:

filename: app/sign-in/[[...sign-in]]/page.tsx
```tsx
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'

export default function SignInPage() {
  return (
    <SignIn.Root>
      <SignIn.Step name="start">
        <Clerk.Connection name="google">Sign in with Google</Clerk.Connection>
        <Clerk.Field name="identifier">
          <Clerk.Label>Email</Clerk.Label>
          <Clerk.Input />
          <Clerk.FieldError />
        </Clerk.Field>
        <SignIn.Action submit>Continue</SignIn.Action>
      </SignIn.Step>
      <SignIn.Step name="verifications">
        <SignIn.Strategy name="email_code">
          <Clerk.Field name="code">
            <Clerk.Label>Code</Clerk.Label>
            <Clerk.Input />
            <Clerk.FieldError />
          </Clerk.Field>
          <SignIn.Action submit>Verify</SignIn.Action>
        </SignIn.Strategy>
      </SignIn.Step>
    </SignIn.Root>
  )
}
```

## Tailwind CSS

If you are already using [Tailwind CSS](https://tailwindcss.com/), no additional setup is required. Classes from Tailwind can be applied to most Clerk Elements components. Use your editor's IntelliSense to see if `className` is a valid prop on a component you want to style.

filename: app/sign-in/[[...sign-in]]/page.tsx
```tsx
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'

export default function SignInPage() {
  return (
    <SignIn.Root>
      <SignIn.Step
        name="start"
        className="bg-white w-96 rounded-2xl py-10 px-8 shadow-sm border space-y-6"
      >
        <div className="grid grid-cols-2 gap-x-4">
          <Clerk.Connection
            name="google"
            className="flex items-center gap-x-3 justify-center font-medium border shadow-sm py-1.5 px-2.5 rounded-md"
          >
            <Clerk.Icon className="size-4" />
            Google
          </Clerk.Connection>
          <Clerk.Connection
            name="github"
            className="flex items-center gap-x-3 justify-center font-medium border shadow-sm py-1.5 px-2.5 rounded-md"
          >
            <Clerk.Icon className="size-4" />
            GitHub
          </Clerk.Connection>
        </div>
        <Clerk.Field name="identifier" className="space-y-2">
          <Clerk.Label className="text-sm font-medium">Email</Clerk.Label>
          <Clerk.Input className="w-full border rounded-md py-1.5 px-2.5" />
          <Clerk.FieldError className="block text-red-500 text-sm" />
        </Clerk.Field>
        <SignIn.Action submit className="bg-black text-white rounded-md py-1.5 px-2.5">
          Continue
        </SignIn.Action>
      </SignIn.Step>
    </SignIn.Root>
  )
}
```

## With existing components via `asChild`

Many of the Clerk Elements components accept an `asChild` prop that allows you to swap out the rendered element. This is useful if you have an existing design system or component library that you wish to use with Clerk Elements.

filename: app/sign-in/[[...sign-in]]/page.tsx
```tsx
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'

import { Button } from '@components/button'
import { Input } from '@components/input'

export default function SignInPage() {
  return (
    <SignIn.Root>
      <SignIn.Step name="start">
        <Clerk.Connection name="google" asChild>
          <Button>Sign in with Google</Button>
        </Clerk.Connection>
        <Clerk.Field name="identifier">
          <Clerk.Label>Email</Clerk.Label>
          <Clerk.Input asChild>
            <Input />
          </Clerk.Input>
          <Clerk.FieldError />
        </Clerk.Field>
        <SignIn.Action submit asChild>
          <Button>Continue</Button>
        </SignIn.Action>
      </SignIn.Step>
      <SignIn.Step name="verifications">
        <SignIn.Strategy name="email_code">
          <Clerk.Field name="code">
            <Clerk.Label>Code</Clerk.Label>
            <Clerk.Input asChild>
              <Input />
            </Clerk.Input>
            <Clerk.FieldError />
          </Clerk.Field>
          <SignIn.Action submit asChild>
            <Button>Continue</Button>
          </SignIn.Action>
        </SignIn.Strategy>
      </SignIn.Step>
    </SignIn.Root>
  )
}
```

Notice how the Clerk Elements components are wrapping the rendered `<Input>` and `<Button>` when `asChild` is used. This ensures the underlying event handlers and necessary props are passed along automatically.

### Configure your components for `asChild`

To use the `asChild` prop, your component must spread its incoming props and return [`forwardRef()`](https://react.dev/reference/react/forwardRef). Here's an example of how you might implement a custom `<Input />` component:

```tsx
import { forwardRef } from 'react'

const CustomInput = forwardRef(function CustomInput(props, forwardedRef) {
  return <input ref={forwardedRef} {...props} className="custom-class" />
})
```

## CSS Modules

Classes from an imported CSS module can be applied to most Clerk Elements components with `className`.

filename: app/sign-in/[[...sign-in]]/page.tsx
```tsx
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
import styles from './sign-in.module.css'

export default function SignInPage() {
  return (
    <SignIn.Root>
      <SignIn.Step name="start" className={styles.startStep}>
        <Clerk.Connection name="google" className={styles.provider}>
          Sign in with Google
        </Clerk.Connection>
        <Clerk.Field name="identifier">
          <Clerk.Label className={styles.label}>Email</Clerk.Label>
          <Clerk.Input className={styles.input} />
          <Clerk.FieldError className={styles.error} />
        </Clerk.Field>
        <SignIn.Action submit className={styles.submit}>
          Continue
        </SignIn.Action>
      </SignIn.Step>
      <SignIn.Step name="verifications" className={styles.verificationsStep}>
        <SignIn.Strategy name="email_code">
          <Clerk.Field name="code">
            <Clerk.Label className={styles.label}>Code</Clerk.Label>
            <Clerk.Input className={styles.input} />
            <Clerk.FieldError className={styles.error} />
          </Clerk.Field>
          <SignIn.Action submit className={styles.submit}>
            Verify
          </SignIn.Action>
        </SignIn.Strategy>
      </SignIn.Step>
    </SignIn.Root>
  )
}
```

### Inline styles

You can also use inline styles with Clerk Elements. This is useful when you need to apply styles conditionally or  avoid creating a separate CSS file.

filename: app/sign-in/[[...sign-in]]/page.tsx
```tsx
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'

export default function SignInPage() {
  return (
    <SignIn.Root>
      <SignIn.Step
        name="start"
        style={{
          backgroundColor: 'white',
          padding: '1rem',
          border: '1px solid #dddddd',
          borderRadius: '4px',
        }}
      >
        <Clerk.Field name="identifier">
          <Clerk.Label
            style={{
              color: '#dddddd',
              fontSize: '0.875rem',
            }}
          >
            Email
          </Clerk.Label>
          <Clerk.Input
            style={{
              border: '1px solid #dddddd',
              borderRadius: '4px',
              padding: '1rem',
            }}
          />
        </Clerk.Field>
        <SignIn.Action
          submit
          style={{
            backgroundColor: '#111111',
            color: 'white',
            padding: '1rem',
            borderRadius: '4px',
          }}
        >
          Continue
        </SignIn.Action>
      </SignIn.Step>
    </SignIn.Root>
  )
}
```

## State-based styling

In some cases you might want to style components based on their state. Clerk Elements exposes data attributes for this purpose, as well as components that expose the state programmatically to support more complex logic.

### Data attributes

`<Field>` and `<Input>` can be styled based on their validity state by targeting the `data-valid` or `data-invalid` attributes:

filename: style.css
```css
.input {
  --border-color: gray;
  border: 1px solid var(--border-color);

  &[data-invalid] {
    --border-color: red;
  }
}
```

filename: page.tsx
```tsx
<Clerk.Input className="input" />
```

### Function as children

If you need programmatic access to state for more complex styling, several components accept a function as children. This is useful when dealing with animations, or for conditionally rendering elements based on state.

For example, to access a field's state, use `<FieldState>`.

filename: page.tsx
```tsx
<Clerk.Field name="email">
  <Clerk.FieldState>{(state) => state === 'invalid' && <ErrorIcon />}</Clerk.FieldState>
  <Clerk.Label>Email</Clerk.Label>
  <Clerk.Input />
  <Clerk.FieldError />
</Clerk.Field>
```

---

## Sitemap

[Overview of all docs pages](https://clerk.com/docs/llms.txt)
