Blog: Web Design
Stylized Google Maps

Adding Custom Styles To Google Maps

Avatar for John Locke

John Locke is a SEO consultant from Sacramento, CA. He helps manufacturing businesses rank higher through his web agency, Lockedown Design & SEO.

You may have seen examples of stylized Google Maps before. These Google Maps look different than the default styles that come with Google Maps.

There is an example of one of these stylized maps at the bottom of my Contact page.

You may be wondering “How do I get my own Google Map to look like those other maps that I’ ve seen?”

Google does have a documentation page on Styled Maps. But what I’d like to do is show you how I created mine, and walk you through what each line means.

Hopefully this will give you a better understanding of how you can use the Google Maps API to style your map to fit your needs.

The Raw Code

Before we begin, here’s the raw code I’m using on my Contact page to created the stylized map. This is a HTML page that I am using on a separate domain name.

The HTML page is embedded on the page using an iframe. I also wrap this iframein a responsive, FitVids-style div, so it expands at certain page dimensions.

Here’s the HTML code that makes up the iframe.


<!DOCTYPE html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html lang="en" class="no-js" data-ng-app="App" style="width: 100%; height: 100%;">  
  <head>
  <title>Lockedown Design: Sacramento Web Design Company</title>
  <style>
    #google_map {
        height:1200px;
        width:1600px;
    }
    .gm-style-iw * {
        display: block;
        width: 100%;
    }
    .gm-style .gm-style-iw {
      max-width: 230px !important;
    }
    .gm-style-iw h4, .gm-style-iw p {
        margin: 0;
        padding: 0;
    }
    .gm-style-iw a {
        color: #4272db;
    }
</style>
<!-- The following API key is placeholder data. You must replace this with your own API key -->
<script src='https://maps.googleapis.com/maps/api/js?key=aBcdefghijk9876543-LMno-Qrstuvxyz012345&sensor=false&extension=.js'></script> 
 
<script> 
    google.maps.event.addDomListener(window, 'load', init);
    var map;
    function init() {
        var mapOptions = {
            center: new google.maps.LatLng(38.4826180,-121.3380410),
            zoom: 11,
            zoomControl: false,
            disableDoubleClickZoom: true,
            mapTypeControl: false,
            scaleControl: false,
            scrollwheel: false,
            panControl: false,
            streetViewControl: false,
            draggable : true,
            overviewMapControl: true,
            overviewMapControlOptions: {
                opened: false,
            },
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            styles: [{
              "featureType": "water",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#1c4f54" }] 
              },{
              "featureType": "landscape",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#436775" }] 
              },{
              "featureType": "road",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#318c94" 
                },{ 
                "lightness": -37 }]
              },{
              "featureType": "poi",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#49717f" }] 
              },{
              "featureType": "transit",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#49717f" }] 
              },{
              "elementType": "labels.text.stroke",
              "stylers": [{ 
                "visibility": "on" 
                },{ 
                "color": "#226166" 
                },{ 
                "weight": 2 
                },{ 
                "gamma": 0.84 }]
              },{
              "elementType": "labels.text.fill",
              "stylers": [{ 
                "color": "#ffffff" }]
              },{
              "featureType": "administrative",
              "elementType": "geometry",
              "stylers": [{ 
                "weight": 0.6 
                },{ 
                "color": "#1c4f54" }]
              },{
              "elementType": "labels.icon",
              "stylers": [{ 
                "visibility": "off" }]
              },{
              "featureType": "poi.park",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#436775" }] 
              },{
              "featureType": "administrative.locality",
              "elementType": "labels",
              "stylers": [{
                "visibility": "on"}]
              },{
              "featureType": "administrative.neighborhood",
              "elementType": "labels",
              "stylers": [{
                "visibility": "off"}]
              },{
              "featureType": "administrative.land_parcel",
              "elementType": "labels",
              "stylers": [{
                "visibility": "off"}]
              },{
            }],
        }
        var mapElement = document.getElementById('google_map');
        var map = new google.maps.Map(mapElement, mapOptions);
        var locations = [
['Lockedown Design', '9635 Gerber Rd<br>Sacramento Ca 95829', '(916) 747-2198', '[email protected]', 'https://www.lockedownseo.com/', 38.4826180, -121.3380410, 'http://www.gmap.sacramentowebdesigns.com/img/default.png']
        ];
        for (i = 0; i < locations.length; i++) {
			if (locations[i][1] =='undefined'){ description ='9635 Gerber Rd<br>Sacramento Ca 95829';} else { description = locations[i][1];}
			if (locations[i][2] =='undefined'){ telephone ='(916) 747-2198';} else { telephone = locations[i][2];}
			if (locations[i][3] =='undefined'){ email ='[email protected]';} else { email = locations[i][3];}
           if (locations[i][4] =='undefined'){ web ='https://www.lockedownseo.com/';} else { web = locations[i][4];}
           if (locations[i][7] =='undefined'){ markericon ='';} else { markericon = locations[i][7];}
            marker = new google.maps.Marker({
                icon: markericon,
                position: new google.maps.LatLng(locations[i][5], locations[i][6]),
                map: map,
                title: locations[i][0],
                desc: description,
                tel: telephone,
                email: email,
                web: web
            });
link = '';  bindInfoWindow(marker, map, locations[i][0], description, telephone, email, web, link);
     }
 function bindInfoWindow(marker, map, title, desc, telephone, email, web, link) {
      var infoWindowVisible = (function () {
              var currentlyVisible = false;
              return function (visible) {
                  if (visible !== undefined) {
                      currentlyVisible = visible;
                  }
                  return currentlyVisible;
               };
           }());
           iw = new google.maps.InfoWindow();
           google.maps.event.addListener(marker, 'click', function() {
               if (infoWindowVisible()) {
                   iw.close();
                   infoWindowVisible(false);
               } else {
                   var html= "<div style='color:#000;background-color:#fff;padding:5px;width:150px;'><h4>"+title+"</h4><p>9635 Gerber Rd<br>Sacramento Ca 95829</p><p>(916) 747-2198</p><a href='https://www.lockedownseo.com/' target=_parent'>https://www.lockedownseo.com/</a></div>";
                   iw = new google.maps.InfoWindow({content:html});
                   iw.open(map,marker);
                   infoWindowVisible(true);
               }
        });
        google.maps.event.addListener(iw, 'closeclick', function () {
            infoWindowVisible(false);
        });
 }
}
</script>

</head>
<body ng-class="{home:'home', app:'app'}[$root.page]" cz-shortcut-listen="true" style="width: 100%; height: 100%; margin:0;">
  
  <ng-view class="ng-scope">
    <div id="google_map" class="ng-scope" style="overflow: hidden; transform: translateZ(0px); width: 100%; height: 100%; background-color: rgb(229, 227, 223);">
      <div class="gm-style" style="position: absolute; left: 0px; top: 0px; overflow: hidden; width: 100%; height: 100%; z-index: 0;"></div>
    </div>
  </ng-view>
  </body>
</html>

Let’s break this down into steps.

Getting A Google Maps JavaScript API Key

Before we do anything else, we’ll need our own Google Developer API key. The API key supplied in the code sample above is placeholder data, meant for illustrative purposes only.

Google lists instructions for signing up for their Google Maps Javascript API on their site.

  1. 1. Sign up for a Google Account, if you don’t already have one, and sign in.
  2. 2. Go to the Google Developers Console.
  3. 3. Click Create Project.
  4. 4. Give your New Project a name, and click Create.
  5. 5. You will be taken to a Project Overview dashboard. We want to enable the Google Maps JavaScript API for our stylized map. Click Enable Google APIs for use in your apps.
  6. 6. You’ll be taken to the API Library selection screen. Click Google Maps JavaScript API.
  7. 7. On the next screen, click Enable API.
  8. 8. On the left hand navigation, click on APIs & auth > Credentials.
  9. 9. The next screen will prompt you to Add Credentials. For your custom styled Google Map, all you need is an API key. Click the API Key option in the drop-down menu.
  10. 10. Google will prompt you to choose a server key, browser key, iOS key, or Android key. Click Browser key.
  11. 11. Under Accept requests from these HTTP referrers (web sites) , leave this blank, and click Create.
  12. 12. A modal will appear, giving you the API key you will use for your Google Map. Copy and save this for later use. If you lose your API key, you can still access it from your personal Google Developers Console.

Understanding The Code In Our Custom Styled Map

Now that we have our API key for customizing our map, let’s start looking at the code we’re using to build it. Remember that we’re saving this as an HTML page and using that web page as an embedded iframe.

Most of the action is going on in the head of our HTML document. The body just contains the container where the map is rendered. Here’s the entirety of the body below.


<body ng-class="{home:'home', app:'app'}[$root.page]" cz-shortcut-listen="true" style="width: 100%; height: 100%; margin:0;">
  
  <ng-view class="ng-scope">
    <div id="google_map" class="ng-scope" style="overflow: hidden; transform: translateZ(0px); width: 100%; height: 100%; background-color: rgb(229, 227, 223);">
      <div class="gm-style" style="position: absolute; left: 0px; top: 0px; overflow: hidden; width: 100%; height: 100%; z-index: 0;"></div>
    </div>
  </ng-view>
  </body>
</html>

Nothing too crazy going on here. We have an absolutely positioned div inside of a relatively positioned one, both set to 100% width and height. This is where the map will render.

Let’s look at the top of the document.


<!DOCTYPE html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html lang="en" class="no-js" data-ng-app="App" style="width: 100%; height: 100%;">  
  <head>
  <title>Lockedown Design: Sacramento Web Design Company</title>
  <style>
    #google_map {
        height:1200px;
        width:1600px;
    }
    .gm-style-iw * {
        display: block;
        width: 100%;
    }
    .gm-style .gm-style-iw {
      max-width: 230px !important;
    }
    .gm-style-iw h4, .gm-style-iw p {
        margin: 0;
        padding: 0;
    }
    .gm-style-iw a {
        color: #4272db;
    }
</style>
<!-- The following API key is placeholder data. You must replace this with your own API key -->
<script src='https://maps.googleapis.com/maps/api/js?key=aBcdefghijk9876543-LMno-Qrstuvxyz012345&sensor=false&extension=.js'></script> 

The html element sees this is an application with an API. The gm-style-iw inline styles are for the tooltip that appears when you click on the map cursor.

The API key you generated earlier should replace the placeholder key, right in between where it says key= and &sensor.


<script> 
    google.maps.event.addDomListener(window, 'load', init);
    var map;
    function init() {
        var mapOptions = {
            center: new google.maps.LatLng(38.4826180,-121.3380410),
            zoom: 11,
            zoomControl: false,
            disableDoubleClickZoom: true,
            mapTypeControl: false,
            scaleControl: false,
            scrollwheel: false,
            panControl: false,
            streetViewControl: false,
            draggable : true,
            overviewMapControl: true,
            overviewMapControlOptions: {
                opened: false,
            },

This is the beginning of the JavaScript call to build your map. This first section deals with what map controls to display. There is a complete list of Google Map Controls on the Documentation page, but let me explain a few choices I made here.

The center of the map is the latitude and longitude of your business. If you don’t know this, there are online tools to help you find the latitude and longitude of your business location.

Zoom controls how close or far away the map is. Zoom control determines whether or not to display a zoom slider on your map.

On my map, I disabled most of the controls that appear on a full sized map, since the embed will show on differnt sized devices. I left the ability to drag the map enabled, but that was all.


mapTypeId: google.maps.MapTypeId.ROADMAP,
            styles: [{
              "featureType": "water",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#1c4f54" }] 
              },{
              "featureType": "landscape",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#436775" }] 
              },{
              "featureType": "road",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#318c94" 
                },{ 
                "lightness": -37 }]
              },{
              "featureType": "poi",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#49717f" }] 
              },{
              "featureType": "transit",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#49717f" }] 
              },{
              "elementType": "labels.text.stroke",
              "stylers": [{ 
                "visibility": "on" 
                },{ 
                "color": "#226166" 
                },{ 
                "weight": 2 
                },{ 
                "gamma": 0.84 }]
              },{
              "elementType": "labels.text.fill",
              "stylers": [{ 
                "color": "#ffffff" }]
              },{
              "featureType": "administrative",
              "elementType": "geometry",
              "stylers": [{ 
                "weight": 0.6 
                },{ 
                "color": "#1c4f54" }]
              },{
              "elementType": "labels.icon",
              "stylers": [{ 
                "visibility": "off" }]
              },{
              "featureType": "poi.park",
              "elementType": "geometry",
              "stylers": [{ 
                "color": "#436775" }] 
              },{
              "featureType": "administrative.locality",
              "elementType": "labels",
              "stylers": [{
                "visibility": "on"}]
              },{
              "featureType": "administrative.neighborhood",
              "elementType": "labels",
              "stylers": [{
                "visibility": "off"}]
              },{
              "featureType": "administrative.land_parcel",
              "elementType": "labels",
              "stylers": [{
                "visibility": "off"}]
              },{
            }],
        }

Here’s the heart of our custom map styles. We’re using a traditional ROADMAP style map. The rest of the styles deal mostly with color and visibility.

Landscape is undeveloped land. Water is any body of water. Road controls all roads.

Here’s a list of variations for major map elements.

  • Admnistrative. Variations: administrative.country, administrative.province, administrative.locality, administrative.neighborhood and administrative.land_parcel.
  • Landscape. Variations: landscape.natural and landscape.man_made.
  • POI (Point of Interest). Variations: poi.attraction, poi.business, poi.government, poi.medical, poi.park, poi.place_of_worship, poi.school, and poi.sports_complex.
  • Road. Variations: road.highway, road.arterial, and road.local.
  • Transit. Variations: transist.line and transit.station.

One question a lot of people seem to ask is, “How do you show only cities above a certain population threshold?”

There doesn’t seem to be a good way to do this. According the Google Geocoding API page, there are five different administrative levels in the Maps API.

administrative_area_level_1 are countries, administrative_area_level_2 are states or provinces. Turning visibility off on administrative_area_level_3, administrative_area_level_4, or administrative_area_level_5 all seemed to have the same effect on my map, which is to turn labels for cities of all sizes invisible.

Back to our custom map code.


  var mapElement = document.getElementById('google_map');
  var map = new google.maps.Map(mapElement, mapOptions);
  var locations = [
['Lockedown Design', '9635 Gerber Rd<br>Sacramento Ca 95829', '(916) 747-2198', '[email protected]', 'https://www.lockedownseo.com/', 38.4826180, -121.3380410, 'http://www.gmap.sacramentowebdesigns.com/img/default.png']
        ];
        for (i = 0; i < locations.length; i++) {
	    if (locations[i][1] =='undefined'){ description ='9635 Gerber Rd<br>Sacramento Ca 95829';} else { description = locations[i][1];}
	    if (locations[i][2] =='undefined'){ telephone ='(916) 747-2198';} else { telephone = locations[i][2];}
	    if (locations[i][3] =='undefined'){ email ='[email protected]';} else { email = locations[i][3];}
            if (locations[i][4] =='undefined'){ web ='https://www.lockedownseo.com/';} else { web = locations[i][4];}
            if (locations[i][7] =='undefined'){ markericon ='';} else { markericon = locations[i][7];}
            marker = new google.maps.Marker({
                icon: markericon,
                position: new google.maps.LatLng(locations[i][5], locations[i][6]),
                map: map,
                title: locations[i][0],
                desc: description,
                tel: telephone,
                email: email,
                web: web
            });
link = '';  bindInfoWindow(marker, map, locations[i][0], description, telephone, email, web, link);
     }
 function bindInfoWindow(marker, map, title, desc, telephone, email, web, link) {
      var infoWindowVisible = (function () {
              var currentlyVisible = false;
              return function (visible) {
                  if (visible !== undefined) {
                      currentlyVisible = visible;
                  }
                  return currentlyVisible;
               };
           }());
           iw = new google.maps.InfoWindow();
           google.maps.event.addListener(marker, 'click', function() {
               if (infoWindowVisible()) {
                   iw.close();
                   infoWindowVisible(false);
               } else {
                   var html= "<div style='color:#000;background-color:#fff;padding:5px;width:150px;'><h4>"+title+"</h4><p>9635 Gerber Rd<br>Sacramento Ca 95829</p><p>(916) 747-2198</p><a href='https://www.lockedownseo.com/' target=_parent'>https://www.lockedownseo.com/</a></div>";
                   iw = new google.maps.InfoWindow({content:html});
                   iw.open(map,marker);
                   infoWindowVisible(true);
               }
        });
        google.maps.event.addListener(iw, 'closeclick', function () {
            infoWindowVisible(false);
        });
 }
}
</script>
</head>

The first two lines are saying, “Find this element in the page, and draw a new Google Map inside that element, using the Options that were passed previously.

Then we create a variable, locations, which has an array of information about our map marker. The last item in the array is the URL of your map marker. If you want to create and use a custom marker, pass that information here.

We only have one location on this map, so the for statement just passes the array values to the corresponding variables. The fifth and sixth values in the array are the lattitide and longitude, which are used to create a new Map Marker. The other values in the array make up the information in the tooltip (InfoWindow), which appears when we click the marker, and disappears when we click it again.

I hope this gives you tons of ideas for creating your own custom styles for embedded Google Maps!

Avatar for John Locke

John Locke is a SEO consultant from Sacramento, CA. He helps manufacturing businesses rank higher through his web agency, Lockedown Design & SEO.

Join the Conversation

Your email address will be kept private. Required fields marked *.