How does the customization of Info Windows works

The way we’re handling the customization of Info Windows is basically by removing the inline default styles generated by the Google Maps code and copying them into our default CSS.

We do this to make the customization easier so we don’t have to force our own rules with "!important" declarations and we can use more semantic code, like ".storemapper-iw-content" instead of ".gm-style > div:nth-child(4) > div:nth-child(1)".

Note that on most elements we remove & copy appearance rules only, like background, border or box shadow. We don’t mess with positioning properties because they’re handled dynamically by GMaps for placing the Info Windows on the map.

There are some exceptions though, but for most cases we won’t need them.

Step by step

Attaching an event listener

The first thing we do is attach an event listener that is fired when the <div> containing the InfoWindow’s content is attached to the DOM.

google.maps.event.addListener(marker.infoWindow,'domready',function(){
	addInfoWindowStyling();
});

We then call a function called addInfoWindowStyling() that does the following work:

  1. Removes default inline styles.
  2. Adds CSS classes to all the structural elements of the Info Windows.
  3. Sets a timer to display the Info Windows after 200 ms (more on this later).
  4. Creates an event listener to remove the default :hover behavior of changing the opacity when the cursor is over the close button of the Info Window. This is just for aesthetic reasons but it’s also more preferable to do this from our custom CSS. It’s not recommended to touch this because it will affect customers that are using background colors with some opacity (rgba).

Default CSS

The other part of this process is replicate the default styles into Storemapper’s base CSS so the Info Windows continue looking the same way as usual but now we’re using the CSS classes we created in the previous step. For example:

#storemapper .storemapper-iw-layout .storemapper-iw-triangle-shadow {
	border-right: 10px solid transparent;
	border-left: 10px solid transparent;
	border-top: 24px solid rgba(0, 0, 0, 0.0980392);
}

This makes the process of customization easier because we can overwrite these declarations from our themes or the customers’ custom CSS.

All the styling rules are available in "app/views/api/users/_default_styles.erb"

Delaying the display of Info Windows

Previously, I mentioned we use a timer to display the Info Windows (step 1-D). This is necessary because otherwise there will be a small “blink” when the default Info Window appears before showing our customizations.

setTimeout(function(){
	iwWrapper.addClass('visible');

	SM$('.gm-style').find('> div:first-child > div:nth-child(4) > div:nth-child(4)')
		.addClass('visible');
}, 200);

It doesn’t look nice, and it’s even more evident when we use a different background color, ie: black.

To fix this issue we do this:

First, keep in mind that the <div> containing the Info Window is generated dynamically when you click on a marker or some other triggering event (like clicking on the “View on map” button) and then is attached to a <div>, which is always the same, every time this happens.

Specifically, the selector of that <div> is ".gm-style > div:first-child > div:nth-child(4) > div:nth-child(4)".

So, what we do is set its opacity and visibility to “1” and “hidden”, respectively, to force it to not be displayed when the showing event is fired.

We then use visibility: hidden because, unlike display: none, the element is not visible, but positioning attributes are assigned to it.

This is important because Google Maps still can place the Info Window above the marker but we are just not displaying it on the page.

It also allows us to use a fading animation that otherwise with the “display” property wouldn’t be possible.

.gm-style > div:first-child > div:nth-child(4) > div:nth-child(4),
	#storemapper .storemapper-iw-wrapper,
	#storemapper .storemapper-iw-wrapper > * {
	visibility: hidden;
	opacity: 0;
}
.gm-style > div:first-child > div:nth-child(4) > div:nth-child(4).visible,
	#storemapper .storemapper-iw-wrapper.visible,
	#storemapper .storemapper-iw-wrapper.visible > * {
	visibility: visible;
	opacity: 1;
}
#storemapper .storemapper-iw-wrapper {
	transition: .3s ease;
}

Hiding the Info Window

Even though by default Google Maps removes the <div> containing the Info Window when it’s closed, meaning it won’t be displayed, we have to remove the .visible class we added to some elements previously that are still in the DOM.

This is done by calling the hideInfoWindow() function when a marker or the “View on map” button is clicked.

Was this article helpful?

Related Articles