Enhanced Keyboard-accessible Google Maps
Patrick H. Lauke wrote an excellent article about keyboard-accessible Google Maps on the Opera Developer website. Still I was able to improve it slightly when I implemented an accessible map myself. I would like to share these modifications with you:
- A link to Google Maps when JavaScript is disabled.
- Support for the Google AJAX API Loader.
- Using the small map control.
- Keyboard accessibility for all control elements within the map.
As a fallback without JavaScript — because people disable it, because their mobile device doesn’t support it, or because it gets filtered by corporate proxies — Patrick used the little known Google Static Maps API, but for some reason he missed adding the link to Google. Here is the fix:
<div id="map">
<a href="http://maps.google.com/maps ?f=q&output=html &q=50.110950+8.684666" title="Google Maps">
- <img src="http://maps.google.com/staticmap?hl=en &center=50.112267,8.678384 &markers=50.110950,8.684666,red &zoom=15&size=500x300 &key=[Your API Key]" alt="City map of Frankfurt" width="500" height="300" />
</a>
</div>
Then I changed how the map is embedded. As it seems that the API loader is more current, I preferred that way:
<script type="text/javascript" src="http://www.google.com/jsapi?key=[Your API Key]"></script>
<script type="text/javascript" src="/js/accgmap.js"></script>
<script type="text/javascript">
google.load( 'maps', '2', { 'language' : 'en' } );
google.setOnLoadCallback( GMAP.initMap );
</script>
Using the small control elements is trivial: SmallMapControl()
. The next thing I wanted to change was keyboard access to all controls, in particular for the map type, i.e. Map | Satellite | Hybrid
. Patrick refers to an id
, but I found that all relevant controls have a title
, so I just checked for that attribute. I also dropped setting the style
attribute in JavaScript as that belongs in the CSS file. His original function GKeyboardPatch()
now looks like this (note the while
loop for a slightly better performance):
GKeyboardPatch: function( map ) {
var
button, divs = map.getContainer().getElementsByTagName( 'div' );var
i = 0;while
( divs[i] ) {if ( divs[i].getAttribute( 'log' ) || ( divs[i].getAttribute( 'title' ) && divs[i].getAttribute( 'title' ) != '' ) ) {
- button = document.createElement( 'button' );
- button.setAttribute( 'value', divs[i].getAttribute( 'title' ));
- divs[i].appendChild( button );
- if ( divs[i].getAttribute( 'log' )) {
// only control buttons
// override the IE opacity filter that Google annoyingly sets
- divs[i].style.filter = '';
// should really set to 'transparent'
- divs[i].style.background = 'url( http://www.google.com/ intl/en_ALL/mapfiles/transparent.png )';
- }
- }
- i++;
- }
- }
Now remember I said I’d rather separate style and behaviour, so here are a some lines of CSS with the setting of width
and height
for the #map
being most relevant, otherwise it will collapse:
#map {
- height: 300px;
- overflow: hidden;
- position: relative;
- width: 500px;
}
#maps-static, #maps-static img {
- display: block;
}
#map span.note {
- display: none;
}
#map button {
- background: transparent;
- border-style: solid;
- border-width: 0;
- cursor: pointer;
- height: 100%;
- left: -2px;
- margin: 2px;
- overflow: hidden;
- padding: 2px;
- position: absolute;
- text-indent: -100em;
- top: -2px;
- width: 100%;
}
#map a:focus, #map a:active, #map button:focus, #map button:active {
- outline: 2px dashed #61bf1a;
}
And that’s it, thanks again to Patrick for the solid foundation I built upon. Now download the JavaScript code and try to tab through the map below.
Actually on the other website I extracted hCard microformats from the page as well and displayed the addresses on the map, but I was lazy and used jQuery. I thought it doesn’t look well here mixed with Patrick’s clean DOM scripting, but feel free to take it from the original website.
Nice one… darn, I must get around to doing my follow-up article at last. One small note: I didn’t originally have the link to Google Maps itself in the fallback, because I thought if the users have JavaScript disabled, going to the Maps site itself won’t help them much more either… but I see what you did there linking to the half-interactive HTML variant. Very neat indeed.