Guide on how to customize the appearance of the Stripe.js custom element to match the design of my other floating

I want to customize the appearance of my Stripe.js elements (card number, Cvc, Expiry) by adding floating labels, similar to the floating labels in Bootstrap. I am using ngx-stripe as a wrapper for Stripe.js. While I have managed to style them to match my other bootstrap elements, the labels do not float when focused. View the Stackblitz example here.

Stripe provides some information on floating label appearances here, but despite trying different approaches, the issue remains unresolved. It is possible that I am not applying it correctly or that my Bootstrap classes are interfering with the Stripe CSS.

  1. https://stripe.com/docs/elements/appearance-api?platform=web#form-inputs---floating-labels
  2. https://stripe.com/docs/elements/appearance-api?platform=web#others

This is how the card number element appears with Bootstrap's floating classes:

<div class="form-floating mb-3">
  <div id="floatingNumber" class="form-control stripe-form-control" placeholder="ex. 1111 1111 1111 1111"></div>
  <label for="floatingNumber">Card Number</label>
</div>

Image from my Stackblitz

https://i.sstatic.net/aawZy.png

The label and text positions appear fixed, rather than floating.

Check out my Stackblitz where this setup is implemented. Here are the methods I tried.

  1. Incorporated Bootstrap's floating classes
  2. Added appearance: { labels: 'floating' } during creation of Stripe elements
  3. Included "stripe-form-control" as a class - sourced from the Stripe website

Answer №1

While I may not be an expert in angular, bootstrap, or stripejs, I have taken the time to thoroughly read through their documentations.

To make bootstrap floating labels function properly, it is necessary for the <input> and <label> elements to be direct siblings. This is because the floating label relies on the :placeholder-shown pseudo element. However, an issue arises when your mounted stripe elements are enclosed within an iframe as opposed to being a standalone input, making it challenging for bootstrap floating labels to work seamlessly without modifications.

In referencing the stripe API documentation that suggests using { labels: 'floating' }, experimentation reveals that this feature only applies to elements mounted together in a group (such as 'address'), where the label sits within the iframe structure. For individual mounted elements requiring labels, a different method like this one must be employed. Unfortunately, utilizing this method does not integrate the label inside the iframe, impeding the functionality of floating labels from the appearance API.

Despite residing within the iframe, the inputs still possess the ability to trigger class changes outside the iframe (e.g., StripeElement--focus, StripeElement--complete, and StripeElement--invalid). As a workaround, emulating the bootstrap floating label behavior by replicating it in custom code using CSS seems to be a viable solution.

To address this issue, consider adding the following CSS:

...
/* reset the original behavior of the floating labels for #custom-inputs */
#custom-inputs .form-floating > .form-control:focus ~ label,
#custom-inputs .form-floating > .form-control:not(:placeholder-shown) ~ label {
  opacity: 1;
  transform: scale(1) translateY(0) translateX(0);
}

/* mimic the behavior of bootstrap floating labels for #custom-inputs */
#custom-inputs .form-floating > .form-control.StripeElement--focus ~ label,
#custom-inputs .form-floating > .form-control.StripeElement--complete ~ label,
#custom-inputs .form-floating > .form-control.StripeElement--invalid ~ label {
  opacity: 0.8;
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

#custom-inputs .StripeElement--focus {
  color: #212529;
  background-color: #fff;
  border-color: #86b7fe;
  outline: 0;
  box-shadow: 0 0 0 0.25rem rgb(13 110 253 / 25%);
}
...

Additionally, remember to clear out the placeholder text (to utilize the floating labels):

...
      if (!this.cardNumber) {
        this.cardNumber = this.elements.create('cardNumber', {
          ...this.emptyOptions,
          placeholder: '',
        });
        this.cardNumber.mount('#floatingNumber');
      }
      if (!this.cardCvc) {
        this.cardCvc = this.elements.create('cardCvc', {
          ...this.emptyOptions,
          placeholder: '',
        });
        this.cardCvc.mount('#floatingCvc');
      }
      if (!this.cardExpiry) {
        this.cardExpiry = this.elements.create('cardExpiry', {
          ...this.emptyOptions,
          placeholder: '',
        });
        this.cardExpiry.mount('#floatingExpiry');
      }
...

For a demonstration of these alterations, refer to the modified Stackblitz provided here.

Answer №2

I have made a small adjustment to your code by replacing the div with an input. Is this what you were aiming for? https://example.com/code-link

The code works with an input for the name because you should use an input instead of a div.

   <h5>Working Floating Name</h5>
   <div class="form-floating mb-3">
      <input type="text" class="form-control" id="floatingInput" formControlName="name" placeholder="John Doe">
      <label for="floatingInput">Name</label>
   </div>

As you can see, the style you are trying to apply involves the :focus pseudo-class, which does not work with a div.

.form-floating>.form-control-plaintext~label, .form-floating>.form-control:focus~label, .form-floating>.form-control:not(:placeholder-shown)~label, .form-floating>.form-select~label {
    opacity: .65;
    transform: scale(.85) translateY(-0.5rem) translateX(0.15rem);
}

div:focus -> it will not function as expected

input:focus -> it will work properly

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

HTML Email Clickable Box

I am very new to this platform and I feel like I am overlooking something obvious. What I want is an HTML button that will open the user's native email client with the To: field already filled in. <form> <button class="button-21" ...

What is the best way to retrieve all label values of DOM elements from an HTML file using C#?

My goal is to open an HTML file, scan all the DOM elements with labels, translate those label values into another language, and save the modified file in a different location. ...

Executing the http.put request twice in Angular2 will result in duplicate data being sent

I'm currently facing an issue with updating a company record through an API in my Angular 2 application. Upon debugging, I noticed that the http call is being triggered twice. I came across a similar discussion on Stack Overflow where the solution was ...

Is it possible to change the hover highlight rotation on a link without affecting the surrounding elements?

Is it possible to rotate the highlight on a link when hovered? I'm new at this, so apologies if this question seems basic. This is how my css/html is currently structured: .links { display: block; } .links a { color: #000000; text-decoratio ...

There seems to be an issue with the functionality of my selectAll function

Two functions were written - select all and manual select. Select all is supposed to select all the values and deselect them, while manual select is working properly. However, the select all function is not correctly checking and unchecking the checkboxe ...

By default, populate the text area in an HTML form with content fetched from the database

Can anyone provide suggestions on the best method to extract text from a database field and place it as the default text in a text area? I am thinking of assigning the field to a variable and then utilizing javascript to set it as the default text, but I ...

What is the best way to transfer a segment of CSS, HTML, and JavaScript code from one static template to another?

I have a collection of static files (html, css, and js) and I've identified a specific piece of code (let's say a dinosaur animation) that I want to move to another set of static files (a separate project I'm working on with a different temp ...

Switching from real pixels to CSS pixels

The details provided in Mozilla's documentation on elementFromPoint clarify that the coordinates are specified in "CSS pixels" rather than physical pixels. This raises a question about what exactly CSS pixels entail. Many assume that a pixel in CSS is ...

Is it possible to verify if the @Output is correctly wired up within an Angular component?

When working with Angular and TypeScript, it is possible to access the bound @Input values in the ngOnInit method of a component. However, there isn't a straightforward way to check if a particular @Output event binding has been set up on the componen ...

A guide to traversing a class and pinpointing each element that contains a particular classlist property

Here is my code snippet that generates 4 spans within a class. When a user clicks on a span, it changes color to indicate that it has been clicked. <head> <style> .tagger1010 span { padding: 6px 10px; ...

The withLatestFrom operator will not trigger with a null value

Working on an Angular project that utilizes @ngrx/effect, we are incorporating an observable stream with the withLatestFrom rxjs operator. Here is a glimpse of our observable effect stream: @Effect() handleUsersData$ = this.actions$ .pipe( ofType(HAND ...

Selecting the optimal data structure: weighing the benefits of using boolean check versus array .include (balancing performance and redundancy

My objects can have one or more properties assigned, with a total of 5 different properties in my case. To illustrate this, let's use a simple movie example where each movie can be assigned from 5 different genres. I have come up with two methods to ...

What is the best way to find an element using either 'className1' or 'className2'?

Within my project, all locators are defined as elements of an enum and follow this format: For example, if it is a CSS locator - DIV_LOCATION("css=div.location-text.text-overflow"). This method parses the string and identifies it as a CSS locator if it be ...

Combining HTML, PHP, and Ajax within a single document

Hey everyone! I'm diving back into web programming and challenging myself to create a simple mailing form using just HTML, PHP, and Ajax all within a single file. The goal is to have a self-contained HTML document that doesn't refresh when the fo ...

Establishing the width of a table display

How can I create a layout using display: table and similar properties, while ensuring that elements like display: table-row respect the width property? Is there a workaround for this issue? ...

Tips for customizing scrollbar appearance with CSS

While attempting to create a custom scrollbar, I encountered an issue with the image of the scrollbar not displaying properly when the background color is changed. Specifically, when the background color is dark (such as black), the scrollbar blends in and ...

Is there a way to direct video links specifically to a single iframe on a webpage?

I have an iframe and some links. I would like it so that when I click a link, the iframe is updated. echo "<iframe name='vidframe' width='100%' height='360px' src='http://vidto.me/embed-3t83y76l81ml-640x360.html& ...

Locating a specific div element within a webpage using Xpath and identifying its child elements

I wrote this line of code (I know it isn't correct) driver.find_element(By.XPATH, '//div[contains(div[contains(string(),"Example_String"))]').click() I am trying to locate the div that contains another div which in turn contains a specific ...

Requesting an API Delay with GET Method

Hey there, I've created a code that captures the user's CPF and sends it to the server for validation. If the CPF is valid, it will display the user's name in the console. If it's invalid, it will print "Not Found". Check out the code b ...

Remove numerous entries from the WordPress database by selecting multiple checkboxes

A new customer table named "tblvessel" has been created in the Wordpress database. The code provided below selects records from the database and displays them as a table with checkboxes next to each record, assigning the record's 'ID' to the ...