Search code examples
google-signin

Prevent Sign in with google button flickering while loading when centered vertically (Google GSI)


Currently when I use the new API for the personalised sign in with google button, when the button is centered vertically in a flex container, when it is loading it flickers up and down.

Example code is shown below, just in html and css for simplicity, however building this in react - same thing happens.

HTML:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="test.css" type="text/css"
  ></link>
  </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:

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;
}

Any help would be greatly appreciated! Sorta wish google would allow for custom buttons or at least an API so that issues like this could be avoided instead of forcing devs to use an <iframe/>, also the new API isn't awesomely documented (I'm assuming because of how new it is but hopefully this will get better with time.


Solution

  • For some reason, Google created two div's to house identical buttons. The second, with the iframe, replaces the first when the proper font loads. The order in which the css is modified by Google means that no matter how you try to correct the flash with pure css, it will still show up in some way. I went so far as to overlay the div's using position:absolute but the margin gets modified on the first div so it still shifts up before vanishing.

    The only thing I found to work is hide one of the div's permanently. Either way works, the difference is the button font. This one lets the iframe only version load:

    .g_id_signin > div > div:first-child{
      display: none;
    }
    

    This one loads the initial div only, so the font is off, but it shows up faster and the auth flow still works:

    .g_id_signin > div > div:last-child{
      display: none;
    }
    

    You could probably catch and handle the flicker via javascript, but I'm not spending that much time on this. I'll use this css fix until Google updates their code.