Google Maps API v3: InfoWindow not sizing correctly
It a开发者_C百科ppears 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.
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;
}
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
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]);
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.
.gm-style-iw{
height: 100% !important;
overflow: hidden !important;
}
it works for me
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;
">';
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.
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;
}
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.
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>
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.
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.
This solved my problem completely:
.gm-style-iw {
overflow: visible !important;
height: auto !important;
width: auto !important;
}
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.
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.
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)
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.
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.
//infowindow.setContent(response);
var infowindowopts = {
maxWidth: 274,
content: response
};
infowindow.setOptions(infowindowopts);
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 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 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;
}
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.
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);
});
Adding the following to my CSS did the trick for me:
white-space: nowrap;
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...
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:
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.
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());
withinfowindow.setContent($(infoWindowDiv.html())[0]);
This turned out to be easiest for me, but there are lots of other ways to get the same result.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.
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?)
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
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.
精彩评论