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.

Answers:

Answer

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

Answer

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]);
Answer
.gm-style-iw{
    height: 100% !important;
    overflow: hidden !important;
}

it works for me

Answer

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.

Answer

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;
                                       ">';
Answer

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

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.

Answer

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>
Answer

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.

Answer

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.

Answer

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)
Answer

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.

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

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','');
Answer

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...

Answer

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

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.

Answer

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

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

white-space: nowrap;
Answer

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...

Answer

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.

Answer

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?)

Answer

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

Answer

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.

Answer

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

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.

Answer

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.

Answer

This solved my problem completely:

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

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.

Answer

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.