[javascript] Google Maps: How to create a custom InfoWindow?

The default Google Maps InfoWindow for a map marker is very round. How do I create a custom InfoWindow with square corners?

This question is related to javascript html css google-maps

The answer is


Here is a pure CSS solution based on the current infowindow example on google:

https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple

#map *{
  overflow: visible;
}
#content{
  display: block;
  position: absolute;
  bottom: -8px;
  left: -20px;
  background-color: white;
  z-index: 10001;
}

This is a quick solution that will work well for small info windows. Don't forget to up vote if it helps :P


EDIT After some hunting around, this seems to be the best option:

https://github.com/googlemaps/js-info-bubble/blob/gh-pages/examples/example.html

You can see a customised version of this InfoBubble that I used on Dive Seven, a website for online scuba dive logging. It looks like this:


There are some more examples here. They definitely don't look as nice as the example in your screenshot, however.


I found InfoBox perfect for advanced styling.

An InfoBox behaves like a google.maps.InfoWindow, but it supports several additional properties for advanced styling. An InfoBox can also be used as a map label. An InfoBox also fires the same events as a google.maps.InfoWindow.

Include http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobox/src/infobox.js in your page


Styling the infowindow is fairly straightforward with vanilla javascript. I used some of the info from this thread when writing this. I also took into account the possible problems with earlier versions of ie (although I have not tested it with them).

var infowindow = new google.maps.InfoWindow({
  content: '<div id="gm_content">'+contentString+'</div>'
});

google.maps.event.addListener(infowindow,'domready',function(){
  var el = document.getElementById('gm_content').parentNode.parentNode.parentNode;
  el.firstChild.setAttribute('class','closeInfoWindow');
  el.firstChild.setAttribute('title','Close Info Window');
  el = (el.previousElementSibling)?el.previousElementSibling:el.previousSibling;
  el.setAttribute('class','infoWindowContainer');
  for(var i=0; i<11; i++){
    el = (el.previousElementSibling)?el.previousElementSibling:el.previousSibling;
    el.style.display = 'none';
  }
});

The code creates the infowindow as usual (no need for plugins, custom overlays or huge code), using a div with an id to hold the content. This gives a hook in the system that we can use to get the correct elements to manipulate with a simple external stylesheet.

There are a couple of extra pieces (that are not strictly needed) which handle things like giving a hook into the div with the close info window image in it.

The final loop hides all the pieces of the pointer arrow. I needed this myself as I wanted to have transparency on the infowindow and the arrow got in the way. Of course, with the hook, changing the code to replace the arrow image with a png of your choice should be fairly simple too.

If you want to change it to jquery (no idea why you would) then that should be fairly simple.

I'm not usually a javascript developer so any thoughts, comments, criticisms welcome :)


You can use code below to remove style default inforwindow. After you can use HTML code for inforwindow:

var inforwindow = "<div style="border-radius: 50%"><img src='URL'></div>"; // show inforwindow image circle
marker.addListener('click', function() {
    $('.gm-style-iw').next().css({'height': '0px'}); //remove arrow bottom inforwindow
    $('.gm-style-iw').prev().html(''); //remove style default inforwindows
});

Below piece of code may help you out.

var infowindow = new google.maps.InfoWindow();
 google.maps.event.addListener(marker, 'mouseover', (function(marker) {
            return function() {
                var content = address;
                infowindow.setContent(content);
                infowindow.open(map, marker);
            }
          })(marker));

Here is an article < How to locate multiple addresses on google maps with perfect zoom > that helped me achieved this. You can refer it for working JS Fiddle link and complete example.


I think the best answer I've come up with is here: https://codepen.io/sentrathis96/pen/yJPZGx

I can't take credit for this, I forked this from another codepen user to fix the google maps dependency to actually load

Make note of the call to:

InfoWindow() // constructor

I'm not sure how FWIX.com is doing it specifically, but I'd wager they are using Custom Overlays.


You can even append your own css class on the popup container/canvas or how do you want. Current google maps 3.7 has popups styled by canvas element which prepends popup div container in code. So at googlemaps 3.7 You can get into rendering process by popup's domready event like this:

var popup = new google.maps.InfoWindow();
google.maps.event.addListener(popup, 'domready', function() {
  if (this.content && this.content.parentNode && this.content.parentNode.parentNode) {
    if (this.content.parentNode.parentNode.previousElementSibling) {
      this.content.parentNode.parentNode.previousElementSibling.className = 'my-custom-popup-container-css-classname';
    }
  }
});

element.previousElementSibling is not present at IE8- so if you want to make it work at it, follow this.

check the latest InfoWindow reference for events and more..

I found this most clean in some cases.


You can modify the whole InfoWindow using jquery alone...

var popup = new google.maps.InfoWindow({
    content:'<p id="hook">Hello World!</p>'
});

Here the <p> element will act as a hook into the actual InfoWindow. Once the domready fires, the element will become active and accessible using javascript/jquery, like $('#hook').parent().parent().parent().parent().

The below code just sets a 2 pixel border around the InfoWindow.

google.maps.event.addListener(popup, 'domready', function() {
    var l = $('#hook').parent().parent().parent().siblings();
    for (var i = 0; i < l.length; i++) {
        if($(l[i]).css('z-index') == 'auto') {
            $(l[i]).css('border-radius', '16px 16px 16px 16px');
            $(l[i]).css('border', '2px solid red');
        }
    }
});

You can do anything like setting a new CSS class or just adding a new element.

Play around with the elements to get what you need...


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