如何正确定位 css 元素?

How to do the right positioning of css elements?

我正在做一个基于 noUi Slider 的滑块。试图实现这么说 "an elegant" 解决方案。由于我的 ui 句柄很大,我使 ui 基数稍大一些,并在基数中添加了额外的值。但是这些值是不允许的,句柄将跳回到允许的值。我决定将加号和减号按钮放在限制值所在的位置。

但问题是我无法实现当您将手柄移到控制符号 (plus/minus) 上时它们会隐藏在手柄后面的效果。就我而言,他们仍然处于领先地位。我很难解决这个问题。

一些 help/advice 会很棒。

这是我的代码(样式在 JSFiddle 上):

$(document).ready(function(){

    var sliders = document.getElementById('red'),
        input = document.getElementById('handle'),
        sliderPlus = document.getElementById('slider-amount-plus'),
        sliderMinus = document.getElementById('slider-amount-minus'),
        termCur = 500;

    noUiSlider.create(sliders, {
        start: termCur,
        step: 50,
        connect: "lower",
        range: {
            'min': 0,
            'max': 1100
        },
        pips: {
            mode: 'values',
            values: [100, 500, 1000],
            density: 4.5
        }
    });
    $('<div class="value">' + termCur + ' zł' + '</div>').appendTo($('.noUi-handle', sliders));


sliders.noUiSlider.on('change', function ( values, handle ) {
    if ( values[handle] < 100 ) {
        sliders.noUiSlider.set(100);
    } else if ( values[handle] > 1000 ) {
        sliders.noUiSlider.set(1000);
    }
});
sliders.noUiSlider.on('update', function( values ) {
    termCur = values;
    if( termCur >= 100 && termCur <= 1000 ) {
    $('.value', sliders).text(parseInt(termCur) + ' zł');}
});
sliderPlus.addEventListener('click', function(){
    if(termCur < 1000) {
        var setValue = parseInt(termCur) + 50;
        sliders.noUiSlider.set(setValue);
    }
}); 
sliderMinus.addEventListener('click', function(){
    if(termCur > 100) {
        var setValue = parseInt(termCur) - 50;
        sliders.noUiSlider.set(setValue);
    }
}); 

<div class="sliders" id="red">
        <a class="controls-symbols slider-minus" id="slider-amount-minus"><i class="fa fa-minus"></i></a>
        <a class="controls-symbols slider-plus" id="slider-amount-plus"><i class="fa fa-plus"></i></a>
    </div>

https://jsfiddle.net/o7Ly845j/

具有共同父元素的元素组在堆叠顺序中一起向前或向后移动,构成了所谓的堆叠上下文。 充分理解堆叠上下文是真正掌握 z-index 和堆叠顺序如何工作的关键。

每个堆叠上下文都有一个 HTML 元素作为其根元素。当在元素上形成新的堆叠上下文时,该堆叠上下文将其所有子元素限制在堆叠顺序中的特定位置。这意味着如果一个元素包含在堆叠顺序底部的堆叠上下文中,则无法让它出现在堆叠顺序更高的不同堆叠上下文中的另一个元素前面,即使使用十亿的 z-index!

New stacking contexts can be formed on an element in one of these ways:

  • When an element is the root element of a document (the element)

  • When an element has a position value other than static and a z-index value other than auto

  • When an element has an opacity value less than 1

  • In addition to opacity, several CSS properties also create stacking contexts. These include: transforms, filters, css-regions, paged media, and possibly others.


以下是确定单个堆叠上下文中堆叠顺序的基本规则(从后到前):

  • 堆叠上下文的根元素

  • 具有负 z-index 值的定位元素(及其子元素)(较高的值堆叠在较低的值前面;具有相同值的元素根据出现在 HTML)

  • 非定位元素(按出现在HTML中排序)

  • z-index 值为 auto 的定位元素(及其子元素)(按 HTML 中的外观排序)

  • 具有正 z-index 值的定位元素(及其子元素)(较高的值堆叠在较低的值前面;具有相同值的元素根据出现在 HTML)

注意: 具有负 z 索引的定位元素在堆叠上下文中排在第一位,这意味着它们出现在所有其他元素之后。因此,元素有可能出现在其父元素的后面,这通常是不可能的。这仅在元素的父元素位于相同的堆叠上下文中并且不是该堆叠上下文的根元素时才有效。


我创建了一个 "hackish" 方法来使用 jQuery 执行此操作,您可以 view the Fiddle here。这不是一个永久的解决方案,我正在努力抽象定位,因为它使用静态值。我还将弄清楚为什么 CSS 不正常,post 不正常。

     $(document).mousemove(function (e) {
         var newpos = $(".noUi-handle").offset().left;

         if (newpos < 0) {
             $(".slider-minus").hide();
         } else { 
             $(".slider-minus").show();
         }

         if (newpos > 830) {
             $(".slider-plus").hide();  
         } else {  
             $(".slider-plus").show();
         }     
    });

更新 Here is a better version,现在正在研究为什么 CSS 不会为您做这件事。

所以,考虑到最后的@zgood fiddle,我猜问题不再是 z 顺序,这是因为滑块和 plus/minus 元素都得到了事件,当 plus/minus 事件掌握它时,滑块已经在 1100 或 0。所以我改变了周围的事件,所以 plus/minus 先得到事件并阻止它继续到酒吧。我真的只需要停止 mousedown,大部分问题就会自行解决。在那之后,我可以取出所有 > 100 和 < 1000 的支票,因为柱子会自动运行。

我还注意到,当您达到 50/1050 时,滑块按钮会覆盖 plus/minus。所以我将 plus/minus 更改为 z-index:13 而不是 fiddle 中的 3。我不确定哪个更好,所以请尝试 3 和 13 并做出您自己的决定。

https://jsfiddle.net/guyschalnat/radpjf47/2/

$(document).ready(function(){

    var sliders = document.getElementById('red'),
        input = document.getElementById('handle'),
        termCur = 500;

    noUiSlider.create(sliders, {
        start: termCur,
        step: 50,
        connect: "lower",
        range: {
            'min': 0,
            'max': 1100
        },
        pips: {
            mode: 'values',
            values: [100, 500, 1000],
            density: 4.5
        }
    });
    $('<div class="value">' + termCur + ' zł' + '</div>').appendTo($('.noUi-handle', sliders));

    var c = $('#red > span').clone(true);
    $('#red > span').remove();
    $('.noUi-base').prepend(c);

    sliders.noUiSlider.on('update', function( values ) {
        var val = parseInt(values);
        termCur = val;
        $('.value', sliders).text(termCur + ' zł');
    });
    $('#slider-amount-plus').click(function(e){
        if(termCur < 1100) {
            termCur = termCur + 50;
            sliders.noUiSlider.set(termCur);
            $('.value', sliders).text(termCur + ' zł');
        }
       e.stopPropagation();
    }).mousedown(function(e){
       e.stopPropagation();
    });     
    $('#slider-amount-minus').click(function(e){ 
        if(termCur > 0) {
            termCur = termCur - 50;
            sliders.noUiSlider.set(termCur);
            $('.value', sliders).text(termCur + ' zł');
        }
    }).mousedown(function(e){
       e.stopPropagation();
    }); 

});