如何相对于父元素定位工具提示?

8
我正在尝试制作一个小型图库。当鼠标悬停在每张图片上时,图片左侧应该出现一个工具提示。我的HTML代码如下:

.gallery {
  right: 247px;
  width: 220px;
}

.gallery li {
  display: inline;
  width: 100px;
  height: 100px;
  position: relative;
}

.gallery img {
  float: right;
  margin: 10px;
  box-shadow: 0 0 0 8px rgba(0, 0, 0, 0.3);
  -webkit-background-clip: padding-box;
  /* for Safari */
  background-clip: padding-box;
  /* for IE9+, Firefox 4+, Opera, Chrome */
}

.tooltip {
  width: 300px;
  height: 100px;
  display: none;
  position: absolute;
  right: -108px;
  top: 222px;
  z-index: 70;
  background-color: rgba(0, 0, 0, 0.4);
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=40)";
}

.gallery li:hover>.tooltip {
  display: inline;
  z-index: 70;
}

.gallery li:hover {
  background: #fff;
}

.gallery li:hover img {
  box-shadow: 0 0 0 8px rgba(255, 255, 255, 1);
}
<ul class="gallery">
  <li>
    <a href="#" class="thumb"><img src="img/pillow.jpg" alt=""></a>
    <div class="tooltip"></div>
  </li>
  <li>
    <a href="#" class="thumb"><img src="" alt=""></a>
    <div class="tooltip"></div>
  </li>
  <li>
    <a href="#" class="thumb"><img src="" alt=""></a>
    <div class="tooltip"></div>
  </li>
  <li>
    <a href="#" class="thumb "><img src="" alt=""></a>
    <div class="tooltip"></div>
  </li>
  <li>
    <a href="#" class="thumb"><img src="" alt=""></a>
    <div class="tooltip"></div>
  </li>
</ul>

就像之前所说的那样,这个想法是.tooltip拥有position:absolute,应该出现在被悬停的

  • 标签的左侧,但是不知何故它每次都出现在相同的位置。这可能是什么原因呢?


  • 2
    任何 position:absolute; 元素的父元素需要声明自己的位置不是静态的,才能相对于该父元素定位。尝试在你的 .thumb 链接中添加 position:relative; - PlantTheIdea
    可能是重复的问题:绝对定位但相对于父元素 - bjb568
    如果我将position:relative设置为锚点(或图像),工具提示会更改出现的位置,但主要问题仍然存在:无论聚焦哪个li/img/a,工具提示都会出现在完全相同的位置。 - vitalym
    这是我非常简单且轻量级的软件包(https://github.com/yairEO/position)。 - vsync
    5个回答

    1
    你需要将 li 设置为 position:relative,而不是 a 或者 img,因为 li 是实际的祖先元素,而其他两个是兄弟元素。

    实际上,在原始代码中li被设置为相对定位。 - vitalym

    0
    .gallery li {
        display: inline;
        width: 100px;
        height: 100px;
        position: relative;
    }
    

    这种样式不正确,内联元素没有 height 和实际上也没有 width,尝试使用 display: inline-block

    此外,您为 position: absolute 的元素设置了 display: inline,更正确的做法是使用 display: block|inline-block

    .gallery img {
        float: right;
        margin: 10px;
        box-shadow: 0 0 0 8px rgba(0, 0, 0, 0.3);
        -webkit-background-clip: padding-box; /* for Safari */
        background-clip: padding-box; /* for IE9+, Firefox 4+, Opera, Chrome */
    }
    

    上面的代码看起来也很奇怪,为什么你需要将 float: right 应用于图片呢?也许你想将这个样式应用于 li 元素,但是那样的话就不要使用 display: inline or inline-block 了。

    0

    尝试 -

    .tooltip {
      display: inline;
      position: relative;
    }
    
    .tooltip:hover:after {
      background: #333;
      background: rgba(0, 0, 0, .4);
      border-radius: 5px;
      bottom: 26px;
      color: #fff;
      content: attr(tooltip);
      right: -180px;
      top: 222px;
      padding: 5px 15px;
      position: absolute;
      z-index: 98;
      width: 300px;
      height: 100px;
    }
    <img src="https://via.placeholder.com/100" tooltip="This is a tooltip" alter="alternative text" />


    0
    尝试一下这个:

    .gallery {
            right: 247px;
            width: 220px;
          }
    
          .gallery li {
            display: block;
            padding: 10px;
            background-color: red;
            margin-top: 10px;
            position: relative;
          }
    
          .gallery li:hover {
            background: #fff;
            background-color: navy;
          }
    
          .gallery img {
            margin: 10px;
            box-shadow: 0 0 0 8px navy;
          }
          .tooltip {
            width: 300px;
            height: 100px;
            display: none;
            position: absolute;
            right: -308px;
            z-index: 3;
            background-color: green;
          }
    
          .gallery li:hover > .tooltip {
            display: inline;
            z-index: 70;
          }
    
          .gallery li:hover img {
            box-shadow: 0 0 0 8px red;
          }
     <ul class="gallery">
          <li>
            <a href="#" class="thumb"><img src="img/pillow.jpg" alt="" /></a>
            <div class="tooltip"></div>
          </li>
          <li>
            <a href="#" class="thumb"><img src="" alt="" /></a>
            <div class="tooltip"></div>
          </li>
          <li>
            <a href="#" class="thumb"><img src="" alt="" /></a>
            <div class="tooltip"></div>
          </li>
          <li>
            <a href="#" class="thumb"><img src="" alt="" /></a>
            <div class="tooltip"></div>
          </li>
          <li>
            <a href="#" class="thumb"><img src="" alt="" /></a>
            <div class="tooltip"></div>
          </li>
        </ul>


    0
    即使您的定位问题已解决,您的方法也无法在平板电脑和手机等触摸屏上使用。但是这种方法可以利用一些Javascript解决您的问题:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Light-weight Tooltip by FC</title>
    <style>
    h2 {
        text-align: center;
        margin-bottom: 2em;
    }
    span.tool {
        position: relative;
        display: inline-block;
        border-bottom: 1px dotted black;
    }
    span.tool:hover {
        cursor: help;
    }
    span.tip {
        position: absolute;
        bottom: 20px;
        left: 0px;
        display: block;
        width: auto;
        white-space: nowrap;
        font-size: .9em;
        border: 0px solid black; /* change as desired */
        border-radius: 6px;
        padding: 1px 5px;
        background: #eee;
        background: linear-gradient(top, #eee, #ccc);
        background: -moz-linear-gradient(top, #eee, #ccc);
        background: -o-linear-gradient(top, #eee, #ccc);
        background: -webkit-linear-gradient(top, #eee, #ccc);
        background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ccc));
        background: -ms-linear-gradient(top, #eee, #ccc);
        filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#eeeeee,EndColorStr=#cccccc);
        zoom: 1;
        visibility: hidden;
    }
    </style>
    </head>
    <body>
    
        <h2>Light-weight Tooltip by FC</h2>
    
        <p>The <span class="tool">WHO<span class="tip">World Health Organization</span></span> was established in 1948.</p>
    
        <p>
            It is part of the
            <span class="tool">UN
                <span class="tip">United Nations, <br>the successor of the <br>League of Nations</span>
            </span>,
            which was established in 1945.
        </p>
    
        <hr>
    
        <p>Explanation and notes:</p>
    
        <ul>
            <li>The method consists of local nested spans ('tools' with 'tips' inside), positioned relative-absolute.</li>
            <li>If the same tips are to be used several times throughout the page or website, the tip spans can be populated centrally with Javascript or server-side scripting.</li>
            <li>In the current code the width of the tips is set to <i>auto</i>, and controlled with &lt;br&gt;s in the tip text. Change to fixed width as desired.</li>
            <li>With the current code, tablet users must tap (= <i>onclick</i>) rather than press-hold (= <i>onmousedown</i>). It is assumed that that is the intuitive thing most tablet users do, but it can be changed to press-hold.</li>
            <li>The HTML is valid and the code works in IE8+ as well.</li>
            <li>For the sake of completeness: IE9 does not form a border-radius when the element has no declared border, or a border-width of 0.</li>
        </ul>
    
    <script>
        var tools = document.querySelectorAll('.tool'); // mind the dot
        var nrOfTools = tools.length;
        for (var i=0; i<nrOfTools; i++) {
            if ('ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch)) {
                tools[i].onclick = function() {
                    if (this.children[0].style.visibility == '' || this.children[0].style.visibility == 'hidden')
                        this.children[0].style.visibility = 'visible';
                    else
                        this.children[0].style.visibility = 'hidden';
                }
            }
            else {
                tools[i].onmouseover = function() {
                    this.children[0].style.visibility = 'visible';
                }
                tools[i].onmouseout = function() {
                    this.children[0].style.visibility = 'hidden';
                }
            }
        }
    </script>
    </body>
    </html>
    

    http://jsbin.com/nerul/6/edit?html,output上查看实时演示。


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