【问题标题】:CSS Calc setting a new z-index value based on current z-index valueCSS Calc 根据当前 z-index 值设置新的 z-index 值
【发布时间】:2021-01-08 22:23:56
【问题描述】:

我有一张带有数百个地图标记的传单地图。 由于地图拥挤,其中一些地图标记位于其他标记下方。

用户希望某些类型或标准的标记出现在地图上标记“堆栈”的顶部。

这很容易通过调整每个标记元素的 Z-index 来完成。

标记元素目前在CSS下面有这个,这是由Leaflet.js在构建/填充阶段循环生成的:

/* Constructed by Leaflet 1.7 */
element {
    margin-left: -10px;
    margin-top: -20px;
    width: 25px;
    height: 30px;
    transform: translate3d(551px, 252px, 0px);
    z-index: 58;
    outline: currentcolor none medium;
}

z-index 的值是标记的计数器,所以这个标记是数字 58,而 next 标记,(无论它在地图上的位置如何)都有z-index: 59; 等。

这是一个示例差异,手动编辑的 z-index;


以上;一些红色引脚隐藏在蓝色引脚后面。这些需要被提升以更明显。


以上;红色引脚通过 z-index 编辑提升到其他引脚之上,但也保持它们彼此的堆叠(升序)

但是,由于标记的数量是可变的,z-index 的值也是可变的。我当然可以用 javascript 更新所有这些,而且我几乎可以肯定必须这样做,但我很好奇:

有没有办法使用 CSS(仅)根据其当前值相对更新 z-index 值?

例如; “提升”这个标记可以是z-index: calc(<current_value> + 200);

但是,我找不到一种纯 CSS 的方法来捕获 Z-index 的当前值;大多数“计算”当前值使用 100%,但 Z-index 不使用百分比。

为什么我们不能将它设置为一个较高的数字?
使用任意高的 catch-all 值不会给出理想的结果,因为例如,将 z-index 设置为 9999 意味着所有选定的标记元素将具有相同的 z-index。标记是从数据库数据中输出并以某种方式排序(在本例中,按日期),因此“提升”的标记组仍应彼此相对,同时被提升到他们的z-index 的附加值高于那些不在组中的人。

【问题讨论】:

    标签: css leaflet z-index css-calc


    【解决方案1】:

    一个想法可能是使用translateZ() 以相同的方式提升所有元素,但我看到您已经应用了变换。您可能可以将其应用于另一个包装器。

    这里是这个想法的一个例子:

    $('.box i').each(function() {
      var z = $(this).index();
      $(this).css('z-index',z);
    });
    .box{
      padding:20px;
      counter-reset:num;
      transform-style:preserve-3d; /* here */
    }
    .box i {
      display:inline-block;
      position:relative;
      margin:0 -5px;
      border-radius:50%;
      height:30px;
      width:30px;
      background:blue;
      border:2px solid green;
      color:#fff;
      font-size:25px;
    }
    .box i::before {
      content:counter(num);
      counter-increment:num;
    }
    .box i.red {
      background:red;
      transform:translateZ(1px); /* and here */
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="box">
    <i></i><i></i><i></i><i></i><i></i><i class="red"></i><i></i><i></i><i class="red"></i><i></i><i class="red"></i><i></i><i></i><i class="red"></i><i></i><i></i><i class="red"></i><i class="red"></i><i class="red"></i><i></i><i></i><i></i>
    </div>

    【讨论】:

    • 想知道您是否也不能为此使用counter-increment
    • @TylerH 还没有 (github.com/w3c/csswg-drafts/issues/1026) .. 计数器返回一个字符串,实际上只允许内部内容......也许在不久的将来。
    • 这是个好主意。 Leaflet 为 Z 轴生成的变换固定在0px,因此完全可以为这些元素进行变换。但是现在快速测试结果不起作用,因为我忘记了preserve-3d。我明天去探索。
    • @Martin 你在上面的元素上添加了transform-style:preserve-3d; 吗?这是强制性的
    • @TemaniAfif 我刚刚注意到疏忽,是的,更正了翻译似乎确实适用于地图标记。明天我会用新的眼光看,但为新的方法欢呼:-)
    【解决方案2】:

    你的这部分分析错了:

    z-index 的值是一个标记的计数器,所以这个标记是数字 58,而下一个标记,(不管它在地图上的位置)有z-index: 59;,等等。

    Leaflet 管理标记图标的zIndex,使更北(上)的标记具有比南(下)更大的zIndexwith this bit of code,设置一个稍后应用于CSS 属性的值图标的ImageHTMLElement:

    this._zIndex = pos.y + this.options.zIndexOffset;
    

    但传单标记有一个zIndexOffset option 来控制您面临的问题类型。 L.Markers 中还有 a setZIndexOffset method 可以更改此值,例如:

    marker1.setZIndexOffset(100);
    marker2.setZIndexOffset(0);
    

    假设您在L.LayerGroup(或L.FeatureGroupL.GeoJSON)中有标记,您可以利用its invoke method 在其所有标记上同时调用setZIndexOffset,例如

    groupWithRedMarkers.invoke("setZIndexOffset", 100);
    groupWithBlueMarkers.invoke("setZIndexOffset", 0);
    

    zIndexOffset 的值至少应该是标记图标的高度(以 CSS 像素为单位),因为 Leaflet 使用屏幕像素坐标来计算最终的zIndex 值。记得在需要时将zIndexOffsets 重置为零。


    另一种方法是利用map panes,假设在顶部/底部显示标记的标准不会随着时间而改变。

    tl;dr 版本是:

    map.createPane('topmarkers');
    map.getPane('topmarkers').style.zIndex = 650;
    marker = L.Marker(latlng, {pane: 'topmarkers'});
    

    有没有办法通过 CSS(仅)根据 z-index 的当前值相对更新 z-index 值?

    不,因为当用户平移和缩放地图时,Leaflet 会动态更改标记的 z-index。

    【讨论】:

    • 感谢您的反馈和澄清。我怀疑没有办法以这种方式调整 z-index,但认为这很有趣。干杯。
    • 使用 Leaflet 地图窗格系统正是我所需要的,谢谢。
    猜你喜欢
    • 2012-01-23
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 2011-03-13
    • 2013-05-22
    • 1970-01-01
    相关资源
    最近更新 更多