CSS div 定位帮助

8
我需要一些关于每个#box的悬停事件中div位置的帮助。隐藏的div应该以以下方式出现在悬停的框上方:
  1. 每个#tooltip div覆盖被悬停的框以及旁边的框
  2. 框1和2的工具提示应覆盖右侧的框
  3. 框3和4的工具提示应覆盖它们左侧的框

    (为了更好地理解,请参见附图)
  4. 将有几行框,因此定位应相对而非固定于页面尺寸(我想)

到目前为止,我还没有成功地得到#tooltip的正确定位(我知道一个应该是绝对的,另一个应该是相对的,但无论我如何努力,我还没有做到)。

这里是一个jsfiddle可供参考的链接,这是我想要的结果:

enter image description here

3个回答

3
我已经准备了一个Fiddle,我认为它可以实现您所描述的内容。
其背后的想法是,我在盒子和提示框周围包裹了一个包装器。然后,我监听包装器上的鼠标悬停事件,而不是单独监听盒子和提示框。这样,当显示提示框并覆盖最初悬停的元素时,我们避免了闪烁问题。
使包装器的位置相对位置,使得可能将提示框绝对地定位于其上。通过jQuery悬停回调中的一个小if语句,我们可以确定提示框是否应与该框的左侧或右侧对齐。
如果出现某些原因导致Fiddle消失,可以在答案中附加来自Fiddle的代码。 标记:
<div class="container">
    <div class="boxwrapper">
       <div id="box1" class="box">Box 1</div>
       <div id="tooltip1" class="tooltip">Description 1</div>
    </div>
    <div class="boxwrapper">
       <div id="box2" class="box">Box 2</div>
       <div id="tooltip2" class="tooltip">Description 2</div>
    </div>
    <div class="boxwrapper">
       <div id="box3" class="box">Box 3</div>
       <div id="tooltip3" class="tooltip">Description 3</div>
    </div>

    <div class="boxwrapper">
       <div id="box4" class="box">Box 4</div>
       <div id="tooltip4" class="tooltip">Description 4</div>
    </div>
    <div class="clearfix"></div>
</div>

CSS:

.container {
    width: 450px;
    height: auto;
}

.box {
    background: #CCC;
    padding: 20px;
    float: left;
    height: 60px;
    width: 60px;
    list-style-type: none;
    margin: 5px;
    z-index: 1;
}
.tooltip {
    background: rgba(153,153,153,0.7);
    padding: 20px;
    height: 60px;
    width: 170px;
    margin: 5px;
    display:none;
    position: absolute;
    z-index: 2;
}
.clearfix {
    clear: both;
    float: none;
    height: 1px;
}
.boxwrapper {
    position: relative;
    float: left;
}

jQuery:

$(document).ready(function() {

    $(".boxwrapper").mouseenter(function() {
        var tooltip = $(".tooltip", this);
        tooltip.show();
        if ($(".boxwrapper").index(this) < 2) {
            tooltip.css("left", 0);
        } else {
            tooltip.css("right", 0);
        }
    });

    $(".boxwrapper").mouseleave(function(event) {
        $(".tooltip", this).hide();
    });

});  ​

更新:

如果您要在多个盒子行上使用它,则需要稍微改进if语句以考虑这一点。


尽管你的解决方案几乎完美,但还存在一个小问题。当你从box1到box2时,box1的工具提示仍然可见,而box2的悬停并没有被触发。不过我会点赞你的答案,它非常好。非常感谢。 - bikey77

3

是的!这正是我想要的!能否给我们提供创建它的见解?我知道代码本身已经很清楚了,但我也想听听逻辑。非常感谢! - bikey77
1
主要问题是,“取消悬停”(mouseleave或其他)事件会在您离开工具提示区域时立即触发。如果显示来自框1的工具提示并将光标移动到框2,则不会发生这种情况。光标仍然位于工具提示上方。要将鼠标事件传递给下面的元素(框),您需要将pointer-events:none添加到工具提示中。 - Mark
盒子周围的包装器用于定位工具提示。 它具有position: relative,因此工具提示可以在该容器内进行绝对定位。 向右展开的工具提示具有样式“left: 0”,而向左展开的工具提示具有样式“right: 0”。 - Mark
感谢您解释这个逻辑,非常简单但又巧妙。我在IE9中浏览时遇到了一个问题,提示框div闪烁很多。也许在IE中有一个类似pointer-events的等效属性吗? - bikey77
1
你说得对,pointer-events在IE9中不被支持。 你可以像这样制作一个解决方法:http://jsfiddle.net/xnrdp/3/ 鼠标悬停在框上仅用于显示工具提示。如果鼠标离开工具提示区域,则工具提示关闭。在鼠标移动时,它会检查光标是否仍在“buddy”上方。为了更容易理解,我添加了tooltips的“for”属性,但您也可以找到匹配的框。哦,还需要重新启用tooltips的pointer-events;) - Mark

0

你可以在CSS中使用“hover”选择器和“nth-of-type”来实现这一点。

选择每三行中的元素:

:nth-of-type(3), :nth-of-type(7), :nth-of-type(13), :nth-of-type(15)

和第四行:

:nth-of-type(4), :nth-of-type(8), :nth-of-type(12), :nth-of-type(16)

并给它的弹出框添加必要的属性。

演示:http://dabblet.com/gist/3765761

标记:

<div class='box'>1
    <div class='fly-out'></div>
</div>

<div class='box'>2
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>3
    <div class='fly-out'></div>
</div>
<div class='box right-aligned'>4
    <div class='fly-out'></div>
</div>

<div class='box'>5
    <div class='fly-out'></div>
</div>

<div class='box'>6
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>7
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>8
    <div class='fly-out'></div>
</div>

<div class='box'>9
    <div class='fly-out'></div>
</div>

<div class='box'>10
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>11
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>12
    <div class='fly-out'></div>
</div>

<div class='box'>13
    <div class='fly-out'></div>
</div>

<div class='box'>14
    <div class='fly-out'></div>
</div>

<div class='box right-aligned'>15
    <div class='fly-out'></div>
</div>
<div class='box right-aligned'>16
    <div class='fly-out'></div>
</div>

CSS:

* {
margin: 0; 
padding: 0; 
box-sizing: border-box; /* paulirish.com/2012/box-sizing-border-box-ftw/ */
position: relative; 
}

body {
    width: 440px;
    margin: 0 auto;
    }

.box {
    width: 100px;
    height: 100px;
    border: 1px solid #999;
    float: left;
    margin: 5px;
    }
    .fly-out {
        position: absolute;
        top: 0;
        background: rgba(0,0,0,.4);
        opacity: 0;
        z-index: -1;
        }
    .box:hover .fly-out {
        z-index: 1;
        opacity: 1;
        height: 100%;
        width: 210px;
        }
    .box:nth-of-type(3):hover .fly-out,
    .box:nth-of-type(7):hover .fly-out,
    .box:nth-of-type(11):hover .fly-out,
    .box:nth-of-type(15):hover .fly-out,
    .box:nth-of-type(4):hover .fly-out,
    .box:nth-of-type(8):hover .fly-out,
    .box:nth-of-type(12):hover .fly-out,
    .box:nth-of-type(16):hover .fly-out,

    .right-aligned {
        left: -110px;
        right: 0;
        background: rgba(0,0,120,.7);
        }

在您的标记中,“工具提示”位于框外,并且具有“visibility: hidden”,这几乎就像给它“opacity: 0”。虽然看不见,但它仍然存在。要使其实际上无法使用布局,您需要“display: none”,但是这样您将无法使用CSS过渡正确地对其进行动画处理。
注意:如下面评论中所提到的Christofer Eliason,':nth-of-type'选择器支持不太好,因此您可以为要右对齐飞出的每个div添加一个类,或者查看使用“nth-of-type”的jquery版本:https://dev59.com/VHI95IYBdhLWcg3w7CjL#4761510
我使用了':nth-of-type'选择器,因为您可以从CSS本身控制飞出的对齐方式,而无需为新框添加类(如果它们是动态添加的),这可能对我来说有点复杂数学上的问题。
但是,如果您对此感到满意,我已经向第三行和第四行的框中添加了一个类'.right-aligned',您可以在CSS中删除此块,您仍然很好:
.box:nth-of-type(3):hover .fly-out,
.box:nth-of-type(7):hover .fly-out,
.box:nth-of-type(11):hover .fly-out,
.box:nth-of-type(15):hover .fly-out,
.box:nth-of-type(4):hover .fly-out,
.box:nth-of-type(8):hover .fly-out,
.box:nth-of-type(12):hover .fly-out,
.box:nth-of-type(16):hover .fly-out

1
最好提到:nth-of-type()选择器在IE浏览器中的支持非常有限(仅限于IE9+),而且在Opera浏览器中效果不佳。这里是一个参考链接:http://www.quirksmode.org/css/contents.html - Christofer Eliasson
对的,我使用它的原因是如果添加新的盒子,从CSS本身控制会更容易,而不是在HTML中每三个/四个盒子添加一个类,这可能会相当复杂。 - carpenumidium

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