Advance

Styling

Customize the appearance of Stripe Elements

Styling Elements

You can customize the appearance of Stripe Elements using the Appearance API. This allows you to match Elements to your brand's design system.

Appearance API

The Appearance API provides a unified way to style all Elements in your application. You configure appearance options in the Elements provider.

Basic Styling

<script setup>
import { loadStripe } from '@stripe/stripe-js'
import { Elements } from 'vue-stripe'

const stripePromise = loadStripe('pk_test_xxx')

const options = {
  appearance: {
    theme: 'stripe', // 'stripe' | 'night' | 'flat'
  },
}
</script>

<template>
  <Elements :stripe="stripePromise" :options="options">
    <CheckoutForm />
  </Elements>
</template>

Custom Theme

<script setup>
import { loadStripe } from '@stripe/stripe-js'
import { Elements } from 'vue-stripe'

const stripePromise = loadStripe('pk_test_xxx')

const options = {
  appearance: {
    theme: 'stripe',
    variables: {
      colorPrimary: '#0570de',
      colorBackground: '#ffffff',
      colorText: '#30313d',
      colorDanger: '#df1b41',
      fontFamily: 'system-ui, sans-serif',
      spacingUnit: '4px',
      borderRadius: '4px',
    },
  },
}
</script>

<template>
  <Elements :stripe="stripePromise" :options="options">
    <CheckoutForm />
  </Elements>
</template>

Element-Level Styling

You can also style individual elements using the options prop:

<template>
  <CardElement
    :options="{
      style: {
        base: {
          'fontSize': '16px',
          'color': '#424770',
          '::placeholder': {
            color: '#aab7c4',
          },
        },
        invalid: {
          color: '#9e2146',
        },
      },
    }"
  />
</template>

CSS Variables

You can use CSS variables for dynamic theming:

<script setup>
import { loadStripe } from '@stripe/stripe-js'
import { computed } from 'vue'
import { Elements } from 'vue-stripe'

const stripePromise = loadStripe('pk_test_xxx')
const isDarkMode = ref(false)

const options = computed(() => ({
  appearance: {
    theme: isDarkMode.value ? 'night' : 'stripe',
    variables: {
      colorPrimary: getComputedStyle(document.documentElement)
        .getPropertyValue('--color-primary'),
      colorBackground: getComputedStyle(document.documentElement)
        .getPropertyValue('--color-background'),
      colorText: getComputedStyle(document.documentElement)
        .getPropertyValue('--color-text'),
    },
  },
}))
</script>

<template>
  <Elements :stripe="stripePromise" :options="options">
    <CheckoutForm />
  </Elements>
</template>

Appearance Variables

Common appearance variables you can customize:

VariableDescriptionDefault
colorPrimaryPrimary brand color#635bff
colorBackgroundBackground color#ffffff
colorTextText color#30313d
colorDangerError/danger color#df1b41
colorSuccessSuccess color#0dab76
colorWarningWarning color#ffb340
fontFamilyFont familySystem default
spacingUnitBase spacing unit4px
borderRadiusBorder radius4px

Complete Styling Example

<script setup>
import { loadStripe } from '@stripe/stripe-js'
import { Elements, PaymentElement } from 'vue-stripe'

const stripePromise = loadStripe('pk_test_xxx')

const options = {
  appearance: {
    theme: 'stripe',
    variables: {
      colorPrimary: '#0570de',
      colorBackground: '#ffffff',
      colorText: '#30313d',
      colorDanger: '#df1b41',
      fontFamily: 'system-ui, sans-serif',
      spacingUnit: '4px',
      borderRadius: '4px',
    },
    rules: {
      '.Input': {
        border: '1px solid #e0e6eb',
        boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1)',
      },
      '.Input:focus': {
        border: '1px solid #0570de',
        boxShadow: '0 1px 3px 0 rgba(5, 112, 222, 0.1)',
      },
      '.Label': {
        fontWeight: '500',
      },
    },
  },
}
</script>

<template>
  <Elements :stripe="stripePromise" :options="options">
    <form>
      <PaymentElement />
      <button type="submit">
        Pay
      </button>
    </form>
  </Elements>
</template>

Styling Rules

You can use CSS-like rules to style specific parts of Elements:

<script setup>
const options = {
  appearance: {
    rules: {
      '.Input': {
        border: '1px solid #e0e6eb',
      },
      '.Input--invalid': {
        border: '1px solid #df1b41',
      },
      '.Label': {
        fontWeight: '600',
      },
      '.Tab': {
        border: '1px solid #e0e6eb',
      },
      '.Tab--selected': {
        borderColor: '#0570de',
      },
    },
  },
}
</script>

Responsive Styling

Elements automatically adapt to different screen sizes. You can customize this behavior:

<script setup>
const options = {
  appearance: {
    variables: {
      spacingUnit: '4px',
    },
    rules: {
      '.Input': {
        fontSize: '16px', // Prevents zoom on iOS
      },
    },
  },
}
</script>

Dark Mode

You can easily switch between light and dark themes:

<script setup>
import { computed } from 'vue'

const isDark = ref(false)

const options = computed(() => ({
  appearance: {
    theme: isDark.value ? 'night' : 'stripe',
    variables: {
      colorBackground: isDark.value ? '#1a1a1a' : '#ffffff',
      colorText: isDark.value ? '#ffffff' : '#30313d',
    },
  },
}))
</script>

For detailed information about styling Elements, refer to the Stripe Appearance API documentation.