允许元素在内容之后和之前覆盖父溢出限制

时间:2015-06-30 16:29:05

标签: javascript jquery html css css3

我有一个div overflow属性设置为scroll,以便查看所有包含的字段而不占用太多的页面空间。每个字段都有一个span(字段标题)和输入相关联。我提供了用户悬停在跨度上的可能性,并将一些有用的信息作为工具提示。我在跨度悬停上使用跨度afterbefore伪元素,以便添加自定义工具提示。但是,工具提示显示受父div溢出限制的限制。

以下是呈现HTML的示例:

<div id="ContentPlaceHolder1_leftDiv" class="l-custom-left">     
    <div class="personalizedFields">
        <table>
            <tr>
                <td>
                    <span title="Champ associé: Prenom" class="tooltip">Prénom</span>
                </td>
            </tr>
            <tr>
                <td>
                    <input name="ctl00$ContentPlaceHolder1$ucPF$ucCustomField36$field36" type="text" id="field36" />

                </td>
            </tr>

            <tr>
                <td>
                    <span title="Champ associé: Nom" class="tooltip">Nom</span>
                </td>
            </tr>
            <tr>
                <td>
                    <input name="ctl00$ContentPlaceHolder1$ucPF$ucCustomField37$field37" type="text" id="field37" />

                </td>
            </tr>
        </table>
    </div>
</div>

父div和跨度的css:

.l-custom-left
{
    overflow-x: hidden;
    width: 250px;
    height: 50vh;
}

.tooltip:hover:after{
    background: #333;
    background: rgba(0,0,0,.8);
    border-radius: 5px;
    bottom: 26px;
    color: #fff;
    content: attr(title);
    left: 20%;
    padding: 5px 10px;
    position: absolute;
    z-index: 98;
}

.tooltip:hover:before{
    border: solid;
    border-color: #333 transparent;
    border-width: 6px 6px 0 6px;
    bottom: 20px;
    content: "";
    left: 50%;
    position: absolute;
    z-index: 99;
}

如何在内容之前和之后允许我的跨度&#34;覆盖&#34; div父溢出限制?

JSfiddle

2 个答案:

答案 0 :(得分:3)

如果你真的希望这个有用,有两种方法。第一种是使用JavaScript(我不会介绍)将元素放在容器外部的元素位置。这是一个讨厌的修复,我必须在CSS3出现之前实现它太多次计数。

第二个更优雅,但确实打破了HTML的语义。您的:before:after伪不会从滚动容器中弹出的原因是它们被视为.tooltip元素的子元素,因此是文档流的一部分滚动容器,即使它们绝对定位。

那我们该如何处理呢?我们作弊,简单明了。

span之后添加第二个元素:

<span class="tooltip">Prénom</span>
<span title="Champ associé: Prenom" class="tooltip-hovershim">Prénom</span>

我们保留相同的内容,以便元素大小相同。

然后,像这样改变你的CSS:

.tooltip, .tooltip-hovershim
{
    display: inline;
}

.tooltip:hover:after, .tooltip-hovershim:hover:after{
    background: #333;
    background: rgba(0,0,0,.8);
    border-radius: 5px;
    bottom: 26px;
    color: #fff;
    content: attr(title);
    left: 20%;
    padding: 5px 10px;
    position: absolute;
    z-index: 98;
}
.tooltip-hovershim { 
    position: absolute;
    transform: translateX(-100%);
    color: transparent;
}

.tooltip:hover:before, .tooltip-hovershim:hover:before {
    border: solid;
    border-color: #333 transparent;
    border-width: 6px 6px 0 6px;
    bottom: 20px;
    content: "";
    left: 50%;
    position: absolute;
    z-index: 99;
}

瞧瞧! Vous avezvotreélémentflottant。就这么简单。

JSFiddle Example

为了简洁起见,仅适用于前两个元素。

只是为了吵架和咯咯笑,这是Javascript变种

JSFiddle with the JS variant

这是Javascript的关键部分:

var span_labels = document.querySelectorAll('.personalizedFields td span'),
    label_house = document.createElement('div');

document.body.appendChild(label_house);
label_house.setAttribute('class', 'tooltip-hoverer');

for (var i=0,l=span_labels.length;i<l;i++){
  var curr_label = span_labels[i];
    curr_label.addEventListener('mouseover', function(e) {
       e.preventDefault();
       label_house.innerHTML = e.target.getAttribute('title');
       var xy = getOffset(e.target);
       label_house.style.top = (xy.top - 26) + 'px';
       label_house.style.left = (xy.left) + 'px';
       label_house.style.display = 'block';
    });
    curr_label.addEventListener('mouseout', function() {
       label_house.style.display = 'none'; 
    });
}

function getOffset(el) {
    var elementRectangle = el.getBoundingClientRect();
    var _x = elementRectangle.left;
    var _y = elementRectangle.top + el.offsetParent.scrollTop;
    return { top: _y, left: _x };
}

答案 1 :(得分:1)

由于我只想用CSS做的事情是不可行的,所以我决定使用Josh Burgess的JS解决方案,灵感来自JavaScript和JQuery。因此,如果您正在寻找更多面向JQuery的解决方案,那么它就是:

var tooltip;

$(document).ready(function() {
    $('span.tooltip').on({
        mouseenter: function (e) {
            tooltip = document.createElement('div');
            document.body.appendChild(tooltip);
            $(tooltip).addClass('tooltip-hoverer');
            $(tooltip).text($(this).attr('data-tooltip'));
            var x = e.clientX - (($(tooltip).outerWidth()) / 2); // "($(tooltip).outerWidth() / 2)" is required to show the tooltip's down arrow next to the mouse's left position
            var y = this.getBoundingClientRect().top + this.offsetParent.scrollTop;
            $(tooltip).css({
                top: y - 32,
                left: x,
                display: 'block'
            });
        },
        mouseleave: function () {
            document.body.removeChild(tooltip);
        }
    });                       
});

请注意,与Josh的解决方案不同,我不会在加载时创建所有工具提示,但每次跨度悬停时只会创建一个,然后在光标离开跨度时将其删除。

JSFiddle can be found here