Google wrote some code to assist with this. Here are some examples: Example using InfoBubble, Styled markers and Info Window Custom (using OverlayView).
The code in the links above take different routes to achieve similar results. The gist of it is that it is not easy to style InfoWindows directly, and it might be easier to use the additional InfoBubble class instead of InfoWindow, or to override GOverlay. Another option would be to modify the elements of the InfoWindow using javascript (or jQuery), like later ATOzTOA suggested.
Possibly the simplest of these examples is using InfoBubble instead of InfoWindow. InfoBubble is available by importing this file (which you should host yourself): http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobubble/src/infobubble.js
InfoBubble's Github project page.
InfoBubble is very stylable, compared to InfoWindow:
infoBubble = new InfoBubble({
map: map,
content: '<div class="mylabel">The label</div>',
position: new google.maps.LatLng(-32.0, 149.0),
shadowStyle: 1,
padding: 0,
backgroundColor: 'rgb(57,57,57)',
borderRadius: 5,
arrowSize: 10,
borderWidth: 1,
borderColor: '#2c2c2c',
disableAutoPan: true,
hideCloseButton: true,
arrowPosition: 30,
backgroundClassName: 'transparent',
arrowStyle: 2
});
infoBubble.open();
You can also call it with a given map and marker to open on:
infoBubble.open(map, marker);
As another example, the Info Window Custom example extends the GOverlay class from the Google Maps API and uses this as a base for creating a more flexible info window. It first creates the class:
/* An InfoBox is like an info window, but it displays
* under the marker, opens quicker, and has flexible styling.
* @param {GLatLng} latlng Point to place bar at
* @param {Map} map The map on which to display this InfoBox.
* @param {Object} opts Passes configuration options - content,
* offsetVertical, offsetHorizontal, className, height, width
*/
function InfoBox(opts) {
google.maps.OverlayView.call(this);
this.latlng_ = opts.latlng;
this.map_ = opts.map;
this.offsetVertical_ = -195;
this.offsetHorizontal_ = 0;
this.height_ = 165;
this.width_ = 266;
var me = this;
this.boundsChangedListener_ =
google.maps.event.addListener(this.map_, "bounds_changed", function() {
return me.panMap.apply(me);
});
// Once the properties of this OverlayView are initialized, set its map so
// that we can display it. This will trigger calls to panes_changed and
// draw.
this.setMap(this.map_);
}
after which it proceeds to override GOverlay:
InfoBox.prototype = new google.maps.OverlayView();
You should then override the methods you need: createElement
, draw
, remove
and panMap
. It gets rather involved, but in theory you are just drawing a div on the map yourself now, instead of using a normal Info Window.