代码之家  ›  专栏  ›  技术社区  ›  Leron

如何设置元素的样式以重叠滚动

  •  -6
  • Leron  · 技术社区  · 6 年前

    我正在做一个已经存在的项目,前端相当复杂。我想介绍一个新的元素,它应该是下拉列表的替代品。基本上是 div 绑定 knockout 收藏。

    我遇到的问题是,在一个页面上有几个div,其中每个div呈现一个更复杂的结构,其中一个div是我的自定义下拉列表。问题是,当我试图展开下拉列表(使用jquery绑定到click事件的类)时, "dropdown" 因为内容太多,为了保持整个页面的外观和外观,没有好的方法可以使用 overflow: visible .

    很好地介绍了我的问题的一个片段是 HERE :

    $('.show-dropdown').click(function() {
    if ($(this).next('.render-this').hasClass('hide-me')) {
    	$(this).next('.render-this').removeClass('hide-me');
      } else {
      $(this).next('.render-this').addClass('hide-me');
      }
    
    })
    td {
      position: relative;
    }
    
    #top-div {
      width: 500px;
      max-width: 500px;
    border: 1px solid black;
      max-height: 100px;
      overflow-y: auto;
    white-space: nowrap;
    }
    
    #bottom-div {
      width: 500px;
      max-width: 500px;
    border: 1px solid black;
      max-height: 100px;
        overflow-y: auto;
    
    }
    
    .show-dropdown {
      width: 120px;
      height: 40px;
      background-color: green;
    }
    
    .render-this {
      position: absolute;
      bottom: 10px;
      z-index: 5;
      width: 20px;
      height: 150px;
      background-color: red;
    }
    .hide-me {
      display: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="top-div">
    <p>
    lorem ipsum lorem ipsum lorem ipsum lorem ipsumlorem ipsumlorem ipsum lorem ipsum lorem ipsum
    </p>
    </div>
    <div id="bottom-div">
    <table class="w3-table">
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
      <th>Column 4</th>
      <th>Column 5</th>
      <th>Column 6</th>
    </tr>
    <tr>
      <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
      <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
      <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
      <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
      <td><div class="show-dropdown">></div><div class="render-this hide-me"></div></td>
      <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
    </tr>
    </table>

    关于这个话题我读了很多。到目前为止,我的结论是,如果你有溢出,这几乎是游戏结束了。然而从这个问题 HERE 我看到了 transform 也许还有其他的 CSS 也许仍然有可能取得一些成就。另外,我需要的是完全呈现我的下拉列表,我也在考虑使用 溢出:可见 还有一些 JS 创造了卷轴,但还没有深入挖掘。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Devansh J    6 年前

    演示

    https://jsfiddle.net/mg8zbr41/172/

    (我希望这是我想要的行为)

    解释

    如果允许我们 overflow-x: auto overflow-y: visible 一起。但我们不能那样做 this 回答)所以我们使用以下解决方法。

    1. 如果你想让红色的div弹出,你不能 position: relative 起源。所以我们先把它去掉
    2. 现在bottom变为相对于父相对元素body,但我们不希望这样,所以我们也删除了 bottom
    3. 现在我们有 top , right , 底部 , left 都是 auto . 所以元素被放在绿色盒子下面 static . 唯一的区别是它从底部的盒子里跳出来
    4. 现在我们希望它比我们使用的绿色盒子高10像素 translateY(calc(100% + 10px) * -1)
    5. 现在这个工作,直到没有滚动。当div被滚动时,红色框会保持在那里,并且不会随着绿色框一起移动,我们需要修复这个问题。
    6. 如果我们知道div滚动多少钱,这个问题很容易解决。假设div向左滚动100px,我们将红色框向左移动100px
    7. 我们找不到 scrollLeft 没有JS。我个人不喜欢js的风格干预。我们无法避免它,但至少我们可以使用css变量在js和css之间进行通信,使它更具语义。
    8. 我们使用js更新 --scroll-left css变量打开 #bottom-div 向左滚动 价值
    9. 一旦我们拥有 --向左滚动 我们现在可以添加 translateX(calc(var(--scroll-left,0px) * -1))
    10. 我们也不希望红色的盒子水平弹出。我们不能通过 overflow: hidden 因为那需要 位置:相对 . 所以我们使用 clip-path: inset(-999px 0px -999px 0px) .
    11. 我们终于实现了我们想要的。呸。

    Demerits:

    1. 水平重新定位在firefox中将是滞后的,因为 Scroll Lined Effects . 同样的问题也可能出现在移动浏览器中

    参见:

    https://css-tricks.com/popping-hidden-overflow/ 我的答案的灵感来源,但两者(本文中的解决方案和我的解决方案)都是完全不同但相同的核心方法

        2
  •  1
  •   Gregor Ojstersek    6 年前

    您可以在可滚动容器周围添加一个具有相对位置的包装div,然后您的绝对位置下拉列表将绑定到该元素。你可以从中看到 example .

    CSS:

    .position-relative {
        position: relative;
    }
    
    #top-div {
        width: 500px;
        max-width: 500px;
        border: 1px solid black;
        max-height: 100px;
        overflow-y: auto;
        white-space: nowrap;
    }
    
    #bottom-div {
        width: 500px;
        max-width: 500px;
        border: 1px solid black;
        max-height: 100px;
        overflow-y: auto;
    
    }
    
    .show-dropdown {
        width: 120px;
        height: 40px;
        background-color: green;
    }
    
    .render-this {
        position: absolute;
        bottom: 10px;
        z-index: 5;
        width: 20px;
        height: 150px;
        background-color: red;
    }
    .hide-me {
        display: none;
    }
    

    HTML:

    <div class="position-relative">
        <div id="bottom-div">
            <table class="w3-table">
                <tr>
                    <th>Column 1</th>
                    <th>Column 2</th>
                    <th>Column 3</th>
                    <th>Column 4</th>
                    <th>Column 5</th>
                    <th>Column 6</th>
                </tr>
                <tr>
                    <td>
                        <div class="show-dropdown"></div>
                        <div class="render-this hide-me"></div>
                    </td>
                    <td>
                        <div class="show-dropdown"></div>
                        <div class="render-this hide-me"></div>
                    </td>
                    <td>
                        <div class="show-dropdown"></div>
                        <div class="render-this hide-me"></div>
                    </td>
                    <td>
                        <div class="show-dropdown"></div>
                        <div class="render-this hide-me"></div>
                    </td>
                    <td>
                        <div class="show-dropdown">></div>
                        <div class="render-this hide-me"></div>
                    </td>
                    <td>
                        <div class="show-dropdown"></div>
                        <div class="render-this hide-me"></div>
                    </td>
                </tr>
            </table>
        </div>
    </div>
    

    JS

    $('.show-dropdown').click(function() {
        if ($(this).next('.render-this').hasClass('hide-me')) {
            $(this).next('.render-this').removeClass('hide-me');
        } else {
            $(this).next('.render-this').addClass('hide-me');
        }
    })
    

    然后可以根据需要调整顶部、左侧、右侧和底部属性。

        3
  •  1
  •   Or A. araqnid    6 年前

    如果您按如下方式更改css,则可以按您的意愿执行此操作:

    • 移除 position:relative; 从你 td .
    • 使用不同的方法 #bottom-div 使用 display: table; ,并应用 位置:相对; 对它。
    • 所有其他css规则保持不变。

    这是你的新css:

    #top-div {
      width: 500px;
      max-width: 500px;
    border: 1px solid black;
      max-height: 100px;
      overflow-y: auto;
    white-space: nowrap;
    }
    
    #bottom-div {
      width: 500px;
      max-width: 500px;
      border: 1px solid black;
      max-height: 100px;
      position: relative;
      display: table;
    }
    
    .show-dropdown {
      width: 120px;
      height: 40px;
      background-color: green;
    }
    
    .render-this {
      position: absolute;
      bottom: 10px;
      z-index: 5;
      width: 20px;
      height: 150px;
      background-color: red;
    }
    .hide-me {
      display: none;
    }
    

    这里有一个指向 Fiddle 使用新的css。