Is it possible to style a mouseover on an image map using CSS?

HtmlCss

Html Problem Overview


I have an image on a web page that also requires links. I am using an image map to create the links and I am wondering if there is a way to style the area shape on mouseover for a minor touch of interactivity. Is this possible?

I tried this without success:

html

<img src="{main_photo}" alt="locations map"  usemap="#location-map" />
<map name="location-map">
	<area shape="rect" coords="208,230,290,245" href="{site_url}locations/grand_bay_al" />
	<area shape="rect" coords="307,214,364,226" href="{site_url}locations/mobile_al" />
	<area shape="rect" coords="317,276,375,290" href="{site_url}locations/loxley_al" />
</map>

css

area { border: 1px solid #d5d5d5; }

Any suggestions?

Html Solutions


Solution 1 - Html

CSS Only:

Thinking about it on my way to the supermarket, you could of course also skip the entire image map idea, and make use of :hover on the elements on top of the image (changed the divs to a-blocks). Which makes things hell of a lot simpler, no jQuery needed...

Short explanation:

  • Image is in the bottom
  • 2 x a with display:block and absolute positioning + opacity:0
  • Set opacity to 0.2 on hover

Example:

.area {
    background:#fff;
    display:block;
    height:475px;
    opacity:0;
    position:absolute;
    width:320px;
}
#area2 {
    left:320px;
}
#area1:hover, #area2:hover {
    opacity:0.2;
}

<a id="area1" class="area" href="#"></a>
<a id="area2" class="area" href="#"></a>
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Saimiri_sciureus-1_Luc_Viatour.jpg/640px-Saimiri_sciureus-1_Luc_Viatour.jpg" width="640" height="475" />

Original Answer using jQuery

I just created something similar with jQuery, I don't think it can be done with CSS only.

Short explanation:

  • Image is in the bottom
  • Divs with rollover (image or color) with absolute positioning + display:none
  • Transparent gif with the actual #map is on top (absolute position) (to prevent call to mouseout when the rollovers appear)
  • jQuery is used to show/hide the divs

$(document).ready(function() {
  if ($('#location-map')) {
    $('#location-map area').each(function() {
      var id = $(this).attr('id');
      $(this).mouseover(function() {
        $('#overlay' + id).show();

      });

      $(this).mouseout(function() {
        var id = $(this).attr('id');
        $('#overlay' + id).hide();
      });

    });
  }
});

body,
html {
  margin: 0;
}

#emptygif {
  position: absolute;
  z-index: 200;
}

#overlayr1 {
  position: absolute;
  background: #fff;
  opacity: 0.2;
  width: 300px;
  height: 160px;
  z-index: 100;
  display: none;
}

#overlayr2 {
  position: absolute;
  background: #fff;
  opacity: 0.2;
  width: 300px;
  height: 160px;
  top: 160px;
  z-index: 100;
  display: none;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="http://www.tfo.be/jobs/axa/premiumplus/img/empty.gif" width="300" height="350" border="0" usemap="#location-map" id="emptygif" />
<div id="overlayr1">&nbsp;</div>
<div id="overlayr2">&nbsp;</div>
<img src="http://2.bp.blogspot.com/_nP6ESfPiKIw/SlOGugKqaoI/AAAAAAAAACs/6jnPl85TYDg/s1600-R/monkey300.jpg" width="300" height="350" border="0" />
<map name="location-map" id="location-map">
  <area shape="rect" coords="0,0,300,160" href="#" id="r1" />
  <area shape="rect" coords="0,161,300,350" href="#" id="r2"/>
</map>

Hope it helps..

Solution 2 - Html

With pseudo elements.

HTML:

<div class="image-map-container">
    <img src="https://upload.wikimedia.org/wikipedia/commons/8/83/FibonacciBlocks.png" alt="" usemap="#image-map" />
    <div class="map-selector"></div>
</div>

<map name="image-map" id="image-map">
    <area alt="" title="" href="#" shape="rect" coords="54,36,66,49" />
    <area alt="" title="" href="#" shape="rect" coords="72,38,83,48" />
    <area alt="" title="" href="#" shape="rect" coords="56,4,80,28" />
    <area alt="" title="" href="#" shape="rect" coords="7,7,45,46" />
    <area alt="" title="" href="#" shape="rect" coords="10,59,76,125" />
    <area alt="" title="" href="#" shape="rect" coords="93,9,199,122" />
</map>

some CSS:

.image-map-container {
    position: relative;
    display:inline-block;
}
.image-map-container img {
    display:block;
}
.image-map-container .map-selector {
    left:0;top:0;right:0;bottom:0;
    color:#546E7A00;
    transition-duration: .3s;
    transition-timing-function: ease-out;
    transition-property: top, left, right, bottom, color;
}
.image-map-container .map-selector.hover {
    color:#546E7A80;
}

.map-selector:after {
    content: '';
    position: absolute;
    top: inherit;right: inherit;bottom: inherit;left: inherit;
    background: currentColor;
    transition-duration: .3s;
    transition-timing-function: ease-out;
    transition-property: top, left, right, bottom, background;
    pointer-events: none;
}

JS:

$('#image-map area').hover(
    function () { 
        var coords = $(this).attr('coords').split(','),
            width = $('.image-map-container').width(),
            height = $('.image-map-container').height();
        $('.image-map-container .map-selector').addClass('hover').css({
            'left': coords[0]+'px',
            'top': coords[1] + 'px',
            'right': width - coords[2],
            'bottom': height - coords[3]
        })
    },
    function () { 
        $('.image-map-container .map-selector').removeClass('hover').attr('style','');
    }
)

https://jsfiddle.net/79ebt32x/1/

Solution 3 - Html

I don't think this is possible just using CSS (not cross browser at least) but the jQuery plugin ImageMapster will do what you're after. You can outline, colour in or use an alternative image for hover/active states on an image map.

http://www.outsharked.com/imagemapster/examples/usa.html

Solution 4 - Html

Here's one that is pure css that uses the + next sibling selector, :hover, and pointer-events. It doesn't use an imagemap, technically, but the rect concept totally carries over:

.hotspot {
    position: absolute;
    border: 1px solid blue;
}
.hotspot + * {
    pointer-events: none;
    opacity: 0;
}
.hotspot:hover + * {
    opacity: 1.0;
}
.wash {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: rgba(255, 255, 255, 0.6);
}

<div style="position: relative; height: 188px; width: 300px;">
    <img src="http://demo.cloudimg.io/s/width/300/sample.li/boat.jpg">
        
    <div class="hotspot" style="top: 50px; left: 50px; height: 30px; width: 30px;"></div>
    <div>
        <div class="wash"></div>
        <div style="position: absolute; top: 0; left: 0;">A</div>
    </div>
        
    <div class="hotspot" style="top: 100px; left: 120px; height: 30px; width: 30px;"></div>
    <div>
        <div class="wash"></div>
        <div style="position: absolute; top: 0; left: 0;">B</div>
    </div>
</div>

Solution 5 - Html

You can do this by just changing the html. Here's an example:

<hmtl>
  <head>
    <title>Some title</title>
  </head>
  <body> 
  <map name="navigatemap">
    <area shape="rect"  
          coords="166,4,319,41" 
          href="WII.htm"  
          onMouseOut="navbar.src='Assets/NavigationBar(OnHome).png'" 
          onMouseOver="navbar.src='Assets/NavigationBar(OnHome,MouseOverWII).png'" 
    />
    <area shape="rect"
          coords="330,4,483,41" 
          href="OT.htm"  
          onMouseOut="navbar.src='Assets/NavigationBar(OnHome).png'" 
          onMouseOver="navbar.src='Assets/NavigationBar(OnHome,MouseOverOT).png'" 
    />

    <area shape="rect" 
          coords="491,3,645,41" 
          href="OP.htm"  
          onMouseOut="navbar.src='Assets/NavigationBar(OnHome).png'" 
          onMouseOver="navbar.src='Assets/NavigationBar(OnHome,MouseOverOP).png'" 
   />
  </map> 

  <img src="Assets/NavigationBar(OnHome).png" 
     name="navbar" 
     usemap="#navigatemap" />
  </body>
</html>

Solution 6 - Html

Sorry to jump on this question late in the game but I have an answer for irregular (non-rectangular) shapes. I solved it using SVGs to generate masks of where I want to have the event attached.

The idea is to attach events to inlined SVGs, super cheap and even user friendly because there are plenty of programs for generating SVGs. The SVG can have a layer of the image as a background.

http://jcrogel.com/code/2015/03/18/mapping-images-using-javascript-events/

Solution 7 - Html

You could use Canvas

in HTML, simply add a canva

<canvas id="locations" width="400" height="300" style="border:1px solid #d3d3d3;">
Your browser can't read canvas</canvas>
       

And in Javascript (only an example, that will draw a rectangle on the picture)

var c = document.getElementById("locations");
var ctx = c.getContext("2d");
var img = new Image(); 
img.src = '{main_photo}';
img.onload = function() {    // after the pic is loaded
    ctx.drawImage(this,0,0); // add the picture
    ctx.beginPath();         // start the rectangle
    ctx.moveTo(50,50);
    ctx.lineTo(200,50);
    ctx.lineTo(200,200);
    ctx.lineTo(50,200);
    ctx.lineTo(50,50);
    
    ctx.strokeStyle = "sienna"; // set color
    ctx.stroke();               // apply color
    ctx.lineWidth = 5;
    // ctx.closePath();
};

Solution 8 - Html

In some browsers (chrome, edge) Area::hover::after css is supported.

Something like this should work:

<style>
   #a1::hover::after {
     position:absolute;
     display:block;
     content: ' ';
     border: 2px solid red;
     top: 10px;
     left: 10px;
     width: 20px;
     height: 20px;
   }
</style>
<map name="image-map" id="image-map">
  <area id="a1" alt="" title="" href="#" shape="rect" coords="10,10,20,20"> 
</map>
<img src="foo.png" usemap="#image-map" />

See this fiddle: https://jsfiddle.net/6z2w9trL/4/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionforrestView Question on Stackoverflow
Solution 1 - HtmlptriekView Answer on Stackoverflow
Solution 2 - HtmlclmView Answer on Stackoverflow
Solution 3 - HtmlSpaceBeersView Answer on Stackoverflow
Solution 4 - HtmlJason KlebanView Answer on Stackoverflow
Solution 5 - HtmlEternetikView Answer on Stackoverflow
Solution 6 - HtmlJuan Carlos MorenoView Answer on Stackoverflow
Solution 7 - HtmlRafikiView Answer on Stackoverflow
Solution 8 - HtmlrealbartView Answer on Stackoverflow