Skip to content

Instantly share code, notes, and snippets.

@SimonEast
Last active February 21, 2022 22:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SimonEast/16b5bf3d56c0e5035b31 to your computer and use it in GitHub Desktop.
Save SimonEast/16b5bf3d56c0e5035b31 to your computer and use it in GitHub Desktop.
Fix for Google Maps InfoWindows having unnecessary scrollbars

For most of 2014, the Google Maps API v3 has had a weird bug in that scrollbars often appear unnecessarily in InfoWindows, and they look freakin' ugly.

Lots of people suggest simply putting overflow: visible or overflow: hidden on the DIV but this completely removes the scrollbars which are useful when content is larger than the window. This script attempts to keep that functionality as much as possible.

This is the result of many hours of debugging and re-testing. It's not 100%, but it's super close. Still a work in progress.

View Example HTML

http://bl.ocks.org/SimonEast/raw/16b5bf3d56c0e5035b31/
(should always reflect the latest version from Github)

How to apply the fix

  1. Wrap your InfoWindow content in <div class="infoWindow">. For example:
new google.maps.InfoWindow({
  content: '<div class="infoWindow">' + content + '</div>'
}); 
  1. After creating your InfoWindow object but before calling infoWindow.open() ensure you add this callback:
google.maps.event.addListener(infoWindow, 'domready', fixInfoWindowScrollbars);
  1. Include the following JS function on your page:
  /**
   * Fixes a bug (possibly a rounding error?) in Google Maps API v3 whereby scrollbars appear
   * on InfoWindow content.
   * 
   * Yes, this is incredibly hacky and ugly. Argh.
   * 
   * Requires jQuery
   * 
   * Should be called like this...
   * google.maps.event.addListener(infoWindow, 'domready', fixInfoWindowScrollbars);
   * (after creating the infoWindow object, but before calling open())
   */
  function fixInfoWindowScrollbars() {
    
    if (this.hasFixApplied) return;
    
    // Find the DOM node for this infoWindow
    var InfoWindowWrapper = $((this.B || this.D).contentNode.parentElement);
    
    // We disable scrollbars temporarily
    // Then increase .infoWindow's natural dimensions by 2px in width and height    
    
    InfoWindowWrapper.children().css('overflow', 'visible');
    
    var InfoWindowElement = InfoWindowWrapper.find('.infoWindow');
    InfoWindowElement            
        .width(function(i, oldWidth) { return oldWidth + 3 })
    
    // Will this content need scrollbars?  If so, add another 20px padding on right
    if (InfoWindowElement.height() > InfoWindowWrapper.height()) {
        InfoWindowElement
            .css({'padding-right': '20px'})
            .width(function(i, oldWidth) { return oldWidth - 20 })
    }
        
    InfoWindowElement
        .height(function(i, oldHeight) { return oldHeight + 3 })            
  
    // Replace infoWindow content with our new DOM nodes
    this.hasFixApplied = true;
    this.setContent(InfoWindowElement.get(0))
   
  }
  1. Include the following CSS on the page or within your stylesheet:
.gm-style-iw {
  overflow-y: auto !important;
  overflow-x: hidden !important;
}
.gm-style-iw > div {
  overflow: visible !important;   
}
.infoWindow {
  overflow: hidden !important;
}

Please feel free to submit tweaks or improvements on the Github Gist: https://gist.github.com/SimonEast/16b5bf3d56c0e5035b31

Tested in

  • Chrome 40 - working super well
  • Firefox - solves 98% of the issues, although still has some slight issues with height on reeeeeally long content areas
  • IE 11 - works great
<!-- Full HTML example with fixes applied -->
<html>
<head>
<script src="//maps.googleapis.com/maps/api/js?version=3.exp"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 700px"></div>
<script>
//------- Create Example Map ---------
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: new google.maps.LatLng(-30, 145.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Create 3 markers
var markers = [];
markers[0] = new google.maps.Marker({
position: new google.maps.LatLng(-37.8181, 145.119),
map: map
});
markers[1] = new google.maps.Marker({
position: new google.maps.LatLng(-37.8181, 107),
map: map
});
markers[2] = new google.maps.Marker({
position: new google.maps.LatLng(-30.8181, 120),
map: map
});
var content = [
'<h2>Aaa bbb ccc dddd</h2>',
'<h2>Aaa bbb ccc dddd</h2> Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd',
'<h2>Aaa bbb ccc dddd</h2> Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd Aaa bbb ccc dddd',
];
$.each(markers, function(i){
var marker = this;
// Create InfoWindows for each marker
var infoWindow = new google.maps.InfoWindow({
//------- FIX STEP 1: Wrap info window content inside the following 2 DIVs -------
// Two are required so that we can prevent collapsing margins
content: '<div class="infoWindow">' + content[i] + '</div>'
});
google.maps.event.addListener(marker, 'click', function(){
infoWindow.open(map, marker);
});
//------- FIX STEP 2: Add this PRIOR to infoWindow.open() -------
google.maps.event.addListener(infoWindow, 'domready', fixInfoWindowScrollbars);
infoWindow.open(map, marker);
});
/**
*------- FIX STEP 3: Add this function somewhere on the page -------
*
* Fixes a bug (possibly a rounding error?) in Google Maps API v3 whereby scrollbars appear
* on InfoWindow content.
*
* Yes, this is incredibly hacky and ugly. Argh.
*
* Requires jQuery
*
* Should be called like this...
* google.maps.event.addListener(infoWindow, 'domready', fixInfoWindowScrollbars);
* (after creating the infoWindow object, but before calling open())
*/
function fixInfoWindowScrollbars() {
if (this.hasFixApplied) return;
// Find the DOM node for this infoWindow
var InfoWindowWrapper = $((this.B || this.D).contentNode.parentElement);
// We disable scrollbars temporarily
// Then increase .infoWindow's natural dimensions by 2px in width and height
//InfoWindowWrapper.css('overflow', 'visible !important');
InfoWindowWrapper.children().css('overflow', 'visible');
var InfoWindowElement = InfoWindowWrapper.find('.infoWindow');
InfoWindowElement
.width(function(i, oldWidth) { return oldWidth + 3 })
// Will this content need scrollbars? If so, add another 20px padding on right
if (InfoWindowElement.height() > InfoWindowWrapper.height()) {
InfoWindowElement
.css({'padding-right': '20px'})
.width(function(i, oldWidth) { return oldWidth - 20 })
}
InfoWindowElement
.height(function(i, oldHeight) { return oldHeight + 3 })
//.parent().css('overflow', 'visible');
// Replace infoWindow content with our new DOM nodes
this.hasFixApplied = true;
this.setContent(InfoWindowElement.get(0))
}
</script>
<style>
/*------- FIX STEP 4: Include the following CSS within the page -------*/
.gm-style-iw {
overflow-y: auto !important;
overflow-x: hidden !important;
}
.gm-style-iw > div {
overflow: visible !important;
}
.infoWindow {
overflow: hidden !important;
}
</style>
</body>
</html>
@mehnert-vecam
Copy link

worked for me. Thanks a lot! :)

@gilsondelrei
Copy link

On Chrome at this time seems that expression on line 82 is not working.

--> var InfoWindowWrapper = $((this.B || this.D).contentNode.parentElement);

It's rasing the following error:
Uncaught TypeError: Cannot read property 'contentNode' of undefined

Even though, it seems not affect the final result intended. Maybe it doesn't more effect

@DACODE
Copy link

DACODE commented Mar 24, 2021

Hey! Have you tested with CSS? I only needed this:

.gm-style .gm-style-iw.gm-style-iw-c {
        box-shadow: none;
        padding: 0;
        border-radius: 0;
        overflow: auto;
}

.gm-style .gm-style-iw.gm-style-iw-c .gm-style-iw-d {
        overflow: visible !important;
}

@SimonEast
Copy link
Author

SimonEast commented Mar 25, 2021

Thanks for the comment @DACODE. I last used this code over 6 years ago, and the Google Maps API has probably progressed since then (and hopefully some of the annoying bugs are fixed). Your code may be all that's required now, but I'm not sure.

Just make sure you test it on InfoWindows with varying lengths of content (short with no scrollbars, and very long ones that may require scrollbars). And test across browsers also, although you may no longer need to support IE 11 which I did in this original example.

Happy coding!

@DACODE
Copy link

DACODE commented Mar 25, 2021

Of course @SimonEast, only saying because I was experimenting the same problem with this scrollbar, and I tried it out after find this, so if this help anyone its fine =)

Happy day =D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment