'style stripe payment element layout - get rid of stripe grid system

I'm trying to configure the stripe payment element for a custom design

From whay I could see, the only option I have is to use the Elements Appearance API

That's because stripe dinamycally inserts an iframe with the markup (to remain PCI DSS compliant), and that's why I can't find a way to modify it.

Stripe payment element generates the following markup

<div class="p-Grid p-CardForm">
  <div class="p-GridCell p-GridCell--12 p-GridCell--md6">
    <!-- CardNumberInput -->
  </div>
  <div class="p-GridCell p-GridCell--6 p-GridCell--md3">
    <!-- expiryInput -->
  </div>
  <div class="p-GridCell p-GridCell--6 p-GridCell--md3">
    <!-- cvcInput -->
  </div>
</div>

Which uses some custom stripe grid system and produces this:

enter image description here

And above md it displays the following (it's applying the p-GridCell--mdXX classes):

enter image description here

I need to keep the first layout regardless the size of the viewport. How can I disable stripe grids or choose what clases to apply?


Update:

I tried the following approaches to modifiy the classes being applied, with no success:

  1. Use javascript to inject a style tag to the iframe's head:
const iframe = document.getElementsByTagName('iframe')[0]; // this works
const doc = iframe.contentDocument; // woops, this is always null!!!
doc.body.innerHTML = doc.body.innerHTML + '<style>.....' // so I can't do something like this

(taken from this article)

  1. Use javascript to get a reference to the container divs and modify the classes being applied (this approach works in the developer console, only after you inspect the element, but it doesn't work from a javascript block from the html page hosting the iframe)
const numberInput = document.getElementById('Field-numberInput'); // returns null

const numberContainer = document.querySelector('.p-GridCell.p-GridCell--12.p-GridCell--md6'); // also returns null
  1. Following this guide I also tried:
const iframe = document.getElementsByTagName('iframe')[0]; // this works
let y = iframe.contentWindow.document;
y.body.style.backgroundColor = "red"; 

Which throws the following error:

FormElement.svelte:28 Uncaught DOMException: Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.
    at HTMLButtonElement.updateStyle


Solution 1:[1]

I dont know stripe-payment css file but maybe changing md6 to md12 and md3 to md6 will work.

<div class="p-Grid p-CardForm">
  <div class="p-GridCell p-GridCell--12 p-GridCell--md12">
    <!-- CardNumberInput -->
  </div>
  <div class="p-GridCell p-GridCell--6 p-GridCell--md6">
    <!-- expiryInput -->
  </div>
  <div class="p-GridCell p-GridCell--6 p-GridCell--md6">
    <!-- cvcInput -->
  </div>
</div>

will work

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 UPinar