如何解决垂直居中的Google GSI个性化登录按钮加载时的闪烁问题
I've run into a frustrating issue with the new Google Sign-In (GSI) API: when placing the sign-in button inside a flex container set to vertically center content, the button flickers up and down during its loading process. This happens both in a plain HTML/CSS setup and in my React project.
Here's a simplified reproduction of the problem:
HTML Code
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="test.css" type="text/css"> </head> <body> <script src="https://accounts.google.com/gsi/client" async defer></script> <script src="./script.js"></script> <div id="g_id_onload" data-client_id="920029725372-e913v434vc2hfbb6cfkrs7qhiuvuita6.apps.googleusercontent.com" data-callback="handleCredentialResponse"> </div> <div class="button-wrapper"> <div class="g_id_signin" data-type="standard"></div> </div> </body> </html>
CSS Code
body { width: 100vw; height: 100vh; margin: 0; } @font-face { font-family: "Google Sans"; src: url("https://fonts.gstatic.com/s/googlesans/v14/4UabrENHsxJlGDuGo1OIlLU94YtzCwM.ttf") format("truetype"); } .button-wrapper { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; }
What's Causing the Flicker?
From what I can tell, the issue stems from the GSI button being loaded as an iframe. Before the iframe fully loads, the .g_id_signin container has minimal height, which throws off the flex container's vertical centering. Once the iframe loads, the container expands to the button's actual height, forcing the flex layout to re-center the content—causing that noticeable flicker.
Fixes to Try
Here are a couple of workarounds that helped me resolve the flickering:
- Pre-set Fixed Dimensions for the Button Container
Reserve the exact space the GSI button will take up before it loads, so the flex layout doesn't shift. Then unhide the button once it's ready:
.g_id_signin { /* Match the standard GSI button dimensions */ width: 220px; height: 40px; visibility: hidden; }
Add this to your JavaScript to show the button after load:
function handleCredentialResponse(response) { // Your existing login handling logic } // Show the button once the page finishes loading window.addEventListener('load', () => { document.querySelector('.g_id_signin').style.visibility = 'visible'; });
- Use a Placeholder Element
Add a hidden placeholder with the same dimensions as the GSI button to keep the flex layout stable during loading:
<div class="button-wrapper"> <div class="button-placeholder"></div> <div class="g_id_signin" data-type="standard"></div> </div>
.button-wrapper { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; position: relative; } .button-placeholder { width: 220px; height: 40px; visibility: hidden; } .g_id_signin { position: absolute; }
Feedback for Google
On a side note, it would be great if Google could:
- Allow full customization of the sign-in button, or at least provide API hooks to avoid layout shifts caused by the iframe implementation
- Improve the GSI documentation—since it's a newer API, there's a lack of detail around common layout issues and best practices
内容的提问来源于stack exchange,提问作者Marcel Madden

