使用CSS可以为图像映射中的鼠标悬停样式添加样式吗?

58

我在网页上有一张需要链接的图片。我使用了一个图像映射来创建这些链接,我想知道是否有办法在鼠标悬停时为区域形状添加样式以实现轻微的交互效果。这可能吗?

我尝试过以下方法但没有成功:

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>

层叠样式表

area { border: 1px solid #d5d5d5; }

有什么建议吗?


我已经做过一次,但是我不得不使用JavaScript,我的区域都是高亮显示的图像,裁剪所有这些图像很麻烦,但它确实起作用。我不认为CSS有任何方法可以做到这一点。除非 map area:hover { border: 1px solid #d5d5d5; } 起作用... - jValdron
8个回答

54

仅使用CSS:

在去超市的路上思考,你当然也可以跳过整个图片映射的想法,而是利用图像上方的元素的:hover(将div更改为a块)。这使得事情变得简单得多,不需要jQuery...

简短的解释:

  • 图像位于底部
  • 2个a块具有display:block和absolute positioning + opacity:0
  • 悬停时将不透明度设置为0.2

示例:

.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" />

使用jQuery的原始答案

我刚刚用jQuery创建了类似的东西,我认为这不能仅通过CSS完成。

简短说明:

  • 图片在底部
  • 使用绝对定位和display:none的带有鼠标悬停效果(图片或颜色)的div
  • 透明gif与实际的#map重叠(绝对定位)(以防止当鼠标悬停效果出现时调用mouseout
  • 使用jQuery来显示/隐藏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>

希望能对您有所帮助。。

2
修复你的小提琴会很棒! - m1crdy
我个人喜欢纯CSS的解决方案。在我的情况下,我还将.area类的宽度参数移动到#area2块中,并创建了其他#areaX块(#area1、#area3、#area4等),具有不同的宽度值,以便我可以拥有多个不同宽度的悬停区域的图像(例如房间行地图的图像,每个房间都有不同的宽度,但高度相同)。 - Jeff Sereno

17

使用伪元素。

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>

一些 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/


5

可以的,参见Jason下面的回答。 - Brann
那很狡猾。 - SpaceBeers

4
这里有一个纯CSS的方法,使用了“+”相邻选择器、:hover和pointer-events。它并没有使用图像映射技术,但是rect概念完全可用:

.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>


谢谢!我没有想到可以使用兄弟连接器来实现这个。这是一个好主意! - Brann

3

您可以通过更改HTML来实现此目的。以下是一个示例:

<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>

1
在某些浏览器(如Chrome、Edge),支持Area::hover::after CSS。 类似这样的代码应该可以工作:
<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" />

看这个 fiddle:https://jsfiddle.net/6z2w9trL/4/

0

很抱歉晚来回答这个问题,但我有一个关于不规则(非矩形)形状的答案。我使用SVG生成遮罩来确定我想要附加事件的位置。

这个想法是将事件附加到内联SVG上,非常便宜,甚至用户友好,因为有很多用于生成SVG的程序。SVG可以作为背景具有图像的一层。

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


链接返回403禁止错误。 - OXiGEN

0
你可以使用Canvas。
在HTML中,只需添加一个画布。
<canvas id="locations" width="400" height="300" style="border:1px solid #d3d3d3;">
Your browser can't read canvas</canvas>

在JavaScript中(仅作为一个例子,将在图片上绘制一个矩形)

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();
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接