Google maps infowindow scrolling bug: How to solve for all cases?

EDIT

In your specific case, it has to do with the Roboto web font. It is included in the Google Maps API, but nothing is using it at the time on your page before an InfoWindow is opened so the browser has no reason to download it, and doesn't.

When you open the infoWindow, however, the browser at the point realizes it needs the font, and starts to download it, but google maps has measured the infoWindow size before the font is downloaded (see the original answer on how google maps api measures on infoWindow's size). When the font has finished downloading, the content in the infoWindow gets re-painted in the Roboto font which in fact makes the infoWindow a different (larger) size than the size that Google measured it to be before the font was downloaded and it's at this point you'll see scrollbars.

This also explains why you see scrollbars the first time - when google maps measured the infoWindow before the font was downloaded - but you won't see them after - because the font is already downloaded, whatever measurements google maps takes now will be the correct ones.

So, the solution is to

a) Render something in the Roboto font on your page (causing the browser to download that font) before the first infoWindow is open OR

b) Use a different font (one that is used elsewhere on your page, and thus is downloaded on page load) for your infoWindow content.

I'll leave the rest of my answer up because it's a common misunderstanding of how infoWindows work, and, as you pointed out with your google search, a lot of people got hung up on it.

TLDR:

Never use a parent selector (e.g. like #map-canvas) to style the HTML content of your infoWindow.

It's not a bug. Here's how google maps info window styles work:

When you tell google maps API that you want to open an infoWindow with HTML content, google dynamically creates a div element, appends it to your body tag, grabs the measurements of the dynamically created div, and then appends a div with those measurements to the map which is your infoWindow.

Here's where the trick comes into play.

Let's say this is your HTML:

<div id="map-canvas">
</div>

and this is your infoWindow content:

<h1>I'm an infoWindow</h1>
<p>Hi there!</p>

and here is your CSS:

h1 { font-size: 18px; }
#map-canvas h1 { font-size: 24px; }

Google will almost always draw this infoWindow incorrectly - because when it dynamically creates infoWindow div and appends it to the body to get the measurements, the div will have an h1 font-size of 18px. So now google has the measurements and places this div on the map, at which point the h1 font-size increases to 24px so now google is using the wrong measurements and your infoWindow will end up having scrollbars.

I've always found the easiest way to work with infoWindow CSS is to use a wrapper div and always target it, so you're infoWindow HTML content would look like:

<div class="info-window-content">
    <h1>I'm an infoWindow</h1>
    <p>Hi there!</p>
</div>

And then your CSS could look like:

/* global styles */
h1 { font-size: 18px; }
p { line-height: 1.6; }

/* info window styles */
.info-window-content h1 { font-size: 24px; }
.info-window-content p { line-height: 1.2; }

and you wouldn't end up with scrollbars in your infoWindow.