Search code examples
cssreactjspaypalpaypal-rest-sdk

Horizontal centering of PayPal buttons whose width is specified as percentage


Please have a look at this playground, which presents the following React code:

import React from "react";
import ReactDOM from "react-dom";
import {
  PayPalScriptProvider,
  PayPalButtons,
  usePayPalScriptReducer
} from "@paypal/react-paypal-js";
import "./styles.css";

function App() {
  return (
    <div className="hv-center-container">
      <div>
        <div className="thank-you h-center-container">
          <div>Make the viewport as wide as you can, and some more</div>
        </div>
        <div className="h-center-container">
          <PayPalScriptProvider>
            <div className="paypal">
              <PayPalButtons
                style={{
                  layout: "vertical",
                  shape: "pill",
                  tagline: false,
                  height: 55
                }}
              />
            </div>
          </PayPalScriptProvider>
        </div>
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

and the styles:

.hv-center-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  width: 100%;
}

.h-center-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.thank-you {
  font-size: 3em;
  margin-bottom: 1em;
}

.paypal {
  width: 100%;
}

Had I specified the width property of the .paypal rule in pixels, the PayPal buttons would center properly. But now that it's in percentage, they don't. Why is this happening and how can I fix it?


Solution

  • PayPal uses @media queries to declare min-width and max-width. The widest the buttons can get is 750px. When your .paypal container is wider than that, the buttons become left-aligned inside of the wider .paypal container.

    To have the .paypal container match the width of the buttons inside the <iframe>, you can use the same @media queries that PayPal uses.

    @media only screen and (min-width: 75px) {
      .paypal {
        min-width: 75px;
        max-width: 150px;
      }
    }
    
    @media only screen and (min-width: 150px) {
      .paypal {
        min-width: 150px;
        max-width: 200px;
      }
    }
    
    @media only screen and (min-width: 200px) {
      .paypal {
        min-width: 200px;
        max-width: 300px;
      }
    }
    
    @media only screen and (min-width: 300px) {
      .paypal {
        min-width: 300px;
        max-width: 500px;
      }
    }
    
    @media only screen and (min-width: 500px) {
      .paypal {
        min-width: 500px;
        max-width: 750px;
      }
    }