DEV Community

Miguel Piedrafita
Miguel Piedrafita

Posted on • Originally published at on

Building complex interfaces with Stripe Elements

It all started with a Tweet by Muhammed Erdem where he showcased a cool credit card form he had designed on Codepen:

Liquid error: internal

I was using the standard Stripe Element input (pictured below) and challenged myseld to implement the above design into a real application.

Default input for Stripe Elements
Default input for Stripe Elements

I started by copying the styles for the card and moving the Vue code to a single file component (Card.vue). After getting the original code working on Sitesauce I noticed the first problem: the code was using regular inputs to capture the credit card details and show them in the card while I needed to use Stripe Elements to be able to process payments to that card.

After digging through Stripe's documentation I found that just as there was a Card element that encapsulated the card number, expiry date and CVC code there were individual CardNumber, CardExpiry and CardCvc elements that I could use.

My solution consisted on adding the inputs directly on the card. This involved updating the styling both on the card and on the elements (which you can do with the style & class options when creating it).

const cardNumber = elements.create('cardNumber', {
    classes: {
        base: 'card-item__number',
        focus: 'card-item__focus',
    style: {
        base: {
            color: '#ffffff',
            lineHeight: '1',
            fontFamily: '"Source Code Pro", monospace',
            fontSmoothing: 'antialiased',
            fontSize: '27px',
            fontWeight: "500",
            '::placeholder': {
                color: '#cbd5e0'
        invalid: {
            color: '#fa755a',
            iconColor: '#fa755a'
Enter fullscreen mode Exit fullscreen mode

I also updated the logic for detecting the card brand to rely on Stripe (which I assume is more accurate and also means I have less code to maintain) and added automatic focus to make the input more intuitive, and ended up with a really cool result.

A video of the interface I ended up with

Discussion (0)