[javascript] Google Maps API v3: InfoWindow not sizing correctly

It appears my InfoWindow, when you click on the home icon on my Google Maps v3, is not properly auto-sizing to the content of the InfoWindow.

It gives scrollbars when it should not. The InfoWindow should be properly auto-sizing.

Any ideas on why?

Per request, the relevant JavaScript which injects the HTML for the InfoWindow:

listing = '<div>Content goes here</div>';

UPDATE

This bug was handled by Google in issue

https://issuetracker.google.com/issues/35823659

The fix was implemented in February 2015 in version 3.19 of Maps JavaScript API.

This question is related to javascript html css google-maps

The answer is


I think that this behavior is because of some css styling in an outer container, I had the same problem but I solved it using an inner div an adding some padding to it, I know it's weird but it solved the problem

<div id="fix_height">
    <h2>Title</h2>
    <p>Something</p>
</div>

And in my style.css

div#fix_height{
    padding: 5px;
}

This solved my problem completely:

.gm-style-iw {
    overflow: visible !important;
    height: auto !important;
    width: auto !important;
}

You should give the content to InfoWindow from jQuery object.

var $infoWindowContent = $("<div class='infowin-content'>Content goes here</div>");
var infoWindow = new google.maps.InfoWindow();
infowindow.setContent($infoWindowContent[0]);

I found that any setting of line-height within any of the elements inside the infoWindow content caused this issue. removing the line-height settings solved this for me.


Going to add my answer to the list, since NONE of these fixed my problem. I ended up wrapping my content in a div, giving that div a class, and specifying the min-width on the div, AND specifying the maxWidth on the infoWindow, AND they both needed to be the same size, otherwise either the width or the height would be overflowing on boxes with just the wrong amount of content.

Javascript:

// Set up the content for the info box
var content = "<div class='infowindow-content'>" + content + "</div>";

// create a map info box
var infoWindow = new google.maps.InfoWindow({
    maxWidth: 350,
    content: content
});

CSS:

div.infowindow-content {
    min-width: 350px;
}

It wasn't acceptable for me to hard code the width and height of the info window, or to set white-space: nowrap, the maxWidth solution didn't help me and everything else either didn't work or was otherwise inappropriate for my use case.

My solution was to set the content, open the window and then when the domready event is fired, set the height CSS property on the content to whatever the height is, and then force Google Maps to resize the InfoWindow accordingly.

infoWindow is the InfoWindow object, $infoWindowContents is a Jquery object of the contents I want to put in there, map is my Map object. marker is a marker which was clicked.

infoWindow.setContent($infoWindowContents.get(0));

var listener = google.maps.event.addListener(infoWindow, 'domready', function() {
  // Stop listening, otherwise the listeners stack up if the window is opened again
  google.maps.event.removeListener(listener);

  // Set the height on the container to however tall the browser is currently rendering it
  $infoWindowContents.height($infoWindowContents.height());

  // Force Google Maps to recalculate the InfoWindow height
  infoWindow.setContent($infoWindowContents.get(0));
});

infoWindow.open(map, marker);

(I posted the same solution over on a similar question How do I get a google-maps InfoWindow to resize to fit the content that is placed inside of it?)


EDITED (to standout): Trust me, out of the hundred other answers to this question, this is the only correct one that also explains WHY it's happening

Ok, so I know this thread is old, and has a thousand answers, but none of them is correct and I feel the need to post the correct answer.

Firstly, you do not ever need to specify width's or height's on anything in order to get your infoWindow to display without scrollbars, although sometimes you may accidentally get it working by doing this (but it's will eventually fail).

Second, Google Maps API infoWindow's do not have a scrolling bug, it's just very difficult to find the correct information on how they work. Well, here it is:

When you tell the Google Maps API to open in infoWindow like this:

var infoWindow = new google.maps.InfoWindow({...});
....
infoWindow.setContent('<h1>Hello!</h1><p>And welcome to my infoWindow!</p>');
infoWindow.open(map);

For all intents and purposes, google maps temporarily places a div at the end of your page (actually it creates a detached DOM tree - but it's conceptually easier to understand if I say you imagine a div being places at the end of your page) with the HTML content that you specified. It then measures that div (which means that, in this example, whatever CSS rules in my document apply to h1 and p tags will be applied to it) to get it's width and height. Google then takes that div, assigns the measurements to it that it got when it was appended to your page, and places it on the map at the location you specified.

Here's where the problem happens for a lot of people - they may have HTML that looks like this:

<body>
 <div id="map-canvas"><!-- google map goes here --></div>
</body>

and, for whatever reason, CSS that looks like this:

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

Can you see the problem? When the API tries to take the measurements for your infoWindow (immediately before displaying it), the h1 part of the content will have a size of 18px (because the temporary "measuring div" is appended to the body), but when the API actually places the infoWindow on the map, the #map-canvas h1 selector will take precedence causing the font size to be much different than what it was when the API measured the size of the infoWindow and in this circumstance you will always get scrollbars.

There may be more slightly different nuances for the specific reason why you have scrollbars in your infoWindow, but the reason behind it is because of this:

The same CSS rules must apply to the content inside your infoWindow regardless of where the actual HTML element appears in the markup. If they do not, then you will be guaranteed to get scrollbars in your infoWindow

So what I always do, is something like this:

infoWindow.setContent('<div class="info-window-content">...your content here...</div>');

and in my CSS:

.info-window-content { ... }
.info-window-content h1 { .... }
.info-window-content p { ... }
etc...

So no matter where the API appends it's measurement div - before the closing body or inside a #map-canvas, the CSS rules applied to it will always be the same.

EDIT RE: Font Families

Google seems to be actively working on the font loading issue (described below) and functionality has changed very recently so you may or may not see the Roboto font load when your infoWindow opens the first time, depending on the version of the API you are using. There is an open bug report (even though in the changelog this bug report was already marked as fixed) that illustrates that google is still having difficulty with this problem.

ONE MORE THING: WATCH YOUR FONT FAMILIES!!!

In the latest incarnation of the API, google tried to be clever and wrap it's infoWindow content in something that could be targeted with a CSS selector - .gm-style-iw. For people that didn't understand the rules that I explained above, this didn't really help, and in some cases made it even worse. Scrollbars would almost always appear the first time an infoWindow was opened, but if you opened any infoWindow again, even with the exact same content the scrollbars would be gone. Seriously, if you weren't confused before this would make you lose your mind. Here's what was happening:

If you look at the styles that google loads on the page when it's API loads, you'll be able to see this:

.gm-style {
     font-family: Roboto,Arial,sans-serif
 ...
}

Ok, so Google wanted to make it's maps a bit more consistent by always making them use the Roboto font-family. The problem is, for the majority of people, the before you opened an infoWindow, the browser hadn't yet downloaded the Roboto font (because nothing else on your page used it so the browser is smart enough to know that it doesn't need to download this font). Downloading this font isn't instantaneous, even though it is very fast. The first time you open an infoWindow and the API appends the div with your infoWindow content to the body to take it's measurements, it starts downloading the Roboto font, but your infoWindow's measurements are taken and the window is placed on the map before Roboto finishes downloading. The result, quite often, was an infoWindow whose measurements were taken when it's content was rendered using Arial or a sans-serif font, but when it was displayed on the map (and Roboto had finished downloading) it's content was being displayed in a font that was a different size - and voila - scrollbars appear the first time you open the infoWindow. Open the exact same infoWindow a second time - at which point the Roboto has been downloaded and will be used when the API is taking it's measurements of infoWindow content and you won't see any scrollbars.


This works for me. Put a div in the setContent

sh_map.infoWindow.setContent([
  '<div id=\"mydiv\">',
  'Your content goes here',
].join(''));

Then add this CSS to your page:

<style type="text/css">
#map-canvas {
 text-align: center;
 vertical-align: middle;
}
#mydiv {
 font-family: "Comic Sans MS", cursive;
 font-size: 10px;
 border-top-width: 0px;
 border-right-width: 0px;
 border-bottom-width: 0px;
 border-left-width: 0px;
 border-top-style: none;
 border-right-style: none;
 border-bottom-style: none;
 border-left-style: none;
 letter-spacing: normal;
 text-align: center;
 vertical-align: middle;
 word-spacing: normal;
}
</style>

For example, see http://www.student-homes-northampton.co.uk; click the links under the house pics to display the Google map.


I know that lots of other people have found solutions that worked for their particular case, but since none of them worked for my particular case, I thought this might be helpful to someone else.

Some details:

I'm using google maps API v3 on a project where inline CSS is something we really, really want to avoid. My infowindows were working for everything except for IE11, where the width was not calculated correctly. This resulted in div overflows, which triggered scrollbars.

I had to do three things:

  1. Remove all display: inline-block style rules from anything inside of the infowindow content (I replaced with display: block) - I got the idea to try this from a thread (which I can't find anymore) where someone was having the same problem with IE6.

  2. Pass the content as a DOM node instead of as a string. I am using jQuery, so I could do this by replacing: infowindow.setContent(infoWindowDiv.html()); with infowindow.setContent($(infoWindowDiv.html())[0]); This turned out to be easiest for me, but there are lots of other ways to get the same result.

  3. Use the "setMaxWidth" hack - set the MaxWidth option in the constructor - setting the option later doesn't work. If you don't really want a max width, just set it to a very large number.

I don't know why these worked, and I'm not sure if a subset of them would work. I know that none of them work for all of my use cases individually, and that 2 + 3 doesn't work. I didn't have time to test 1 + 2 or 1 + 3.


Short answer: set the maxWidth options property in the constructor. Yes, even if setting the maximum width was not what you wanted to do.

Longer story: Migrating a v2 map to v3, I saw exactly the problem described. Windows varied in width and height, and some had vertical scrollbars and some didn't. Some had <br /> embedded in the data, but at least one with that sized OK.

I didn't think the InfoWindowsOptions.maxWidth property was relevant, since I didn't care to constrain the width... but by setting it with the InfoWindow constructor, I got what I wanted, and the windows now autosize (vertically) and show the full content without a vertical scrollbar. Doesn't make a lot of sense to me, but it works!

See: http://fortboise.org/maps/sailing-spots.html


Also important is height of the map container. If to small infoWindow always will be on 80px height. Otherwise maxWidth and #innerDiv fix works like a charm.


Add a div inside your infowindow

<div id=\"mydiv\">YourContent</div>

Then set the size using css. works for me. This asumes all infowindows are the same size!

#mydiv{
width:500px;
height:100px;
}

I couldnt get it to work in any way shape or form, I was including 3 divs into the box. I wrapped them in an outer div, with widths and heights all set correctly, and nothing worked.

In the end I fixed it by setting the div as absolute top left, and then before the div, I set two images, one 300px wide and 1px high, one 120px high and 1px wide, of a transparent gif.

It scaled properly then!

Its ugly but it works.

You could also do one image and set a zindex I expect, or even just one image if your window has no interaction, but this was containing a form, so, that wasn't an option...


I tried each one of the answers listed. None worked for me. This finally fixed it PERMANENTLY. The code I inherited had a DIV wrapper around all the <h#> and <p> entries. I simply forced some "style" in the same DIV, taking into account a desired max width, threw in the line height change just in case (someone else's fix) and my own white-space: nowrap, which then made the auto overflow make the correct adjustments. No scroll bar, no truncation and no problems!

html = '<div class="map-overlay" style="max-width: 400px;
                                        line-height: normal;
                                        white-space: nowrap;
                                        overflow: auto;
                                       ">';

Well this is the one that did the trick for me:

.gm-style-iw>div {
    overflow: visible !important;
}

Only setting overflow: visible on .gm-style-iw actually made the problem worse! I noticed in the Chrome developer tools inspector that there are two divs inside the .gm-style-iw element, both which have overflow: auto set by default.

I'm displaying quite a lot of HTML-formatted text in my InfoWindows, that might be why the other solutions didn't work at all for me.


As of mid-2014 there appears to be an InfoWindow sizing bug in Google Maps v3 that affects multiple browsers.

It has been reported here:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5713
(and a demo JSFiddle here)
Please click the star on the issue above to vote for it to be fixed!

From all my testing, it appears to be related to element size rounding errors, as it only occurs at some font-sizes.

Bad workarounds:

Having toyed with most suggestions on this page, the following are NOT good solutions:

  • overflow: hidden (can potentially cut off content)
  • white-space: nowrap (can potentially cut off content)
  • Passing a jQuery object or DOM nodes (content potentially overflows outside the InfoWindow)
  • Setting the InfoWindow content after it is opened (on its own, does not help)
  • Changing font away from Roboto (the issue can occur with any font)

One possible workaround is giving your InfoWindow a fixed width (such as those who've suggested setting max-width and min-width), however when you have lots of markers and the amount of content varies fluctuates, this is not ideal. It's also bad for mobile/responsive designs.

A reasonable workaround:

So until Google fix this, I've had to build a workaround. After about 12+ hours of testing and debugging I came up with the following:

This does not have the same drawbacks as other suggestions.

  • Content should never be clipped (unless you have large images that exceed the width of the InfoWindow).
  • Vertical scrollbars are added, but only when necessary.
  • No content should overflow outside of the InfoWindow
  • In most cases the InfoWindow is sized automatically to fit the content (not a fixed size)
  • Should be suitable for mobiles and responsive layouts
  • Margins, padding, fonts should all work OK

Downsides:

  • My version requires jQuery, but it could probably be reworked to be pure JS
  • It creates 20px of padding on the right of the content to make room for the scrollbar in case it is needed. You could skip this if you prefer, or do some more checking to only add padding when necessary.
  • It's rather hacky, but without editing Google's javascript, it's possibly the only way.

View Code on Github

Please submit improvements and corrections as you find them.


Adding the following to my CSS did the trick for me:

white-space: nowrap;

If nothing else, try adding the content after the window has been opened. This should force it to resize.

infoWindow = new google.maps.InfoWindow()
infoWindow.open(map, marker)
infoWindow.setContent(content)

My answer is to add a listener (using addListenerOnce) to check if the infoWindow has been added to the DOM, then opening the infoWindow again (no need to close it).

// map, marker and infoWindow code, we'll call them 
// myMap, myMarker and myInfoWindow

myInfoWindow.open(myMap, myMarker);
google.maps.event.addListenerOnce(myInfoWindow, 'domready', function(){
                myInfoWindow.open(myMap, myMarker);
            });

Add a min-height to your infoWindow class element.

That will resolve the issue if your infoWindows are all the same size.

If not, add this line of jQuery to your click function for the infoWindow:

//remove overflow scrollbars
$('#myDiv').parent().css('overflow','');

I have tried all of these solutions and none worked. After some trial and error I figured it out.

<style type="text/css">
#map_canvas {
    line-height:normal;
}
</style>

Set line-height:normal for the map canvas div.


//infowindow.setContent(response);    
var infowindowopts = { 
    maxWidth: 274, 
    content: response
};
infowindow.setOptions(infowindowopts);

I was having the same issue, particularly noticeable when my <h2> element wrapped to a second line.

I applied a class to a <div> in the infoWindow, and changed the fonts to a generic system font (in my case, Helvetica) versus an @font-face web font which it had been using. Issue solved.


I had an inline element (an a tag) directly inside of the div with style="overflow:auto"[... wrapped that in a p tag and fixed it.

Looks like any inline element that is not nested in a block element directly inside of the infowindow will cause this.


I know this is an old thread, but I just encountered the same problem. I had <h2> and <p> elements in the InfoWindow, and these both had bottom margins. I removed the margins, and InfoWindow sized correctly. None of the other suggested fixes worked. I suspect that the InfoWindow size calculation doesn't take the margins into account.


add to css

.gm-style-iw{
    overflow: hidden !important;
}

info window text:

<div style="width: 200px; height:150px;">
  here text of the info window
</div>

Use the domready event and reopen the info window and show the hidden content after the domready event fires twice to ensure all of the dom elements have been loaded.

// map is created using google.maps.Map() 
// marker is created using google.maps.Marker()
// set the css for the content div .infowin-content { visibility: hidden; } 

infowindow = new google.maps.InfoWindow();    
infowindow.setContent("<div class='infowin-content'>Content goes here</div>");
infowindow.setPosition(marker.getPosition());
infowindow.set("isdomready", false);
infowindow.open(map);   

// On Dom Ready
google.maps.event.addListener(infowindow, 'domready', function () {
    if (infowindow.get("isdomready")) {
        // show the infowindow by setting css 
        jQuery('.infowin-content').css('visibility', 'visible');               
    }
    else {
        // trigger a domready event again.
        google.maps.event.trigger(infowindow, 'content_changed');
        infowindow.set("isdomready", true);
    }
}

I tried just doing a setTimeout(/* show infowin callback */, 100), but sometimes that didn't work still if the content (ie: images) took too long to load.

Hope this works for you.


After losing time and reading for a while, I just wanted something simple, this css worked for my requirements.

.gm-style-iw > div { overflow: hidden !important; }

Also is not an instant solution but starring/commenting on the issue might make them fix it, as they believe it is fixed: http://code.google.com/p/gmaps-api-issues/issues/detail?id=5713


Just to summarize all the solutions that worked for me in all browsers:

  • Don't use margins inside the infowindow, only padding.
  • Set a max-width for the infowindow:

    this.infowindow = new google.maps.InfoWindow({ maxWidth: 200 });

  • Wrap the contents of the infowindow with

    <div style="overflow:hidden;line-height:1.35;min-width:200px;">*CONTENT*</div>

    (change the min-width for the value you set on the infowindow maxWidth)

I have tested it and it worked on every browser, and I had over 400 markers...


.gm-style-iw{
    height: 100% !important;
    overflow: hidden !important;
}

it works for me


It appears that the issue is with the Roboto webfont.

The infowindow is rendered with inline width and height properties based on the content provided. However, it is not calculated with the webfont already rendered/loaded. Once the font is rendered AFTER the entire map is printed to the screen, then it causes the scrollbars to appear due to the "overflow:auto" properties inline inside the window's DIVs.

The solution I found to work is to wrap the content in a DIV and then apply CSS to override the webfont:

.gmap_infowin {
    font-family: sans-serif !important;
    font-weight: normal !important;
}

<div class="gmap_infowin">Your info window content here.</div>

I tried most (if not all) answers alone from above but none worked in my case.
So i combined a couple of them trying to figure out the minimum i need.

And this combination worked for me:

div.infowindow {
    font-family: Courier;
    white-space: nowrap;
    overflow: hidden; 
}

Your milage may vary. good luck.


I was having the same problem with IE and tried many of the fixes detailed in these responses, but was unable to remove the vertical scrollbars in IE reliably.

What worked best for me was to switch to fixed font sizes inside the infowindow -- 'px'... I was using ems. By fixing the font size I no longer needed to explicitly declare the infowindow width or height and the scrollbars were gone for good.


Funny enough, while the following code will correct the WIDTH scroll bar:

.gm-style-iw
{
    overflow: hidden !important;
    line-height: 1.35;

}

It took this to correct the HEIGHT scroll bar:

    .gm-style-iw div
    {
        overflow: hidden !important;
    }

EDIT: Adding white-space: nowrap; to either style might correct the spacing issue that seems to linger when the scroll bars are removed. Great point Nathan.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to google-maps

GoogleMaps API KEY for testing Google Maps shows "For development purposes only" java.lang.NoClassDefFoundError:failed resolution of :Lorg/apache/http/ProtocolVersion How to import JSON File into a TypeScript file? Googlemaps API Key for Localhost Getting "Cannot call a class as a function" in my React Project ERROR: Google Maps API error: MissingKeyMapError This page didn't load Google Maps correctly. See the JavaScript console for technical details Google Maps API warning: NoApiKeys ApiNotActivatedMapError for simple html page using google-places-api