【问题标题】:Nested divs with absolute positioning causing overflow problems绝对定位的嵌套 div 导致溢出问题
【发布时间】:2019-12-15 08:46:04
【问题描述】:

我有一个绝对定位的父 div,它包含一个标题 div 和一个可调整大小的主体 div,如下所示。 body div 包含一个内容 div 和一个绝对定位的子元素。

当body被调整大小时,我需要

  1. 溢出要隐藏的父 div 的内容
  2. body div 在其内容(内容 div 和子 div 的组合)超过 body 尺寸时显示滚动条。

示例展示了第一部分,但滚动条仅在 body 高度小于 content 高度时出现,而不是在子 div 的一部分被父边界隐藏时出现。

有没有纯 CSS 或涉及一些 javascript 的解决方案?

<div id="parent" style="overflow:hidden;position: absolute; left: 50px; top: 50px; border-width: 1px; border-color: black; border-style: solid;">
    <div id="header" style="border-color: red; border-width: 1px; border-style: solid;">
        <p>No scroll bars in header</p>
    </div>
    <div id="body" style="width: 300px; height: 250px; border-width: 1px; border-color: blue; border-style: solid; overflow: auto; resize: both;">
        <div id="content" style="border-width: 1px; border-color: grey; border-style: solid;">
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
        </div>
        <div id="child" style="position:absolute; top:200px;left:100px;width: 50px; height: 50px; border-width: 1px; border-color: green; border-style: solid;"
            <p>Child</p>
        </div>
    </div>
</div>

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    您需要将孩子的位置设置为relative。拥有absolute 位置意味着它不考虑html 中的任何内容。这有点像使用上帝模式。拥有relative 意味着它将考虑其父位置。在这种情况下,它是 div #body

    我还调整了顶部和左侧的值,因为它在将位置更改为相对位置后将子 200px 定位远离内容位置。

    这是工作代码。 请...使用 CSS 而不是属性 style=""
    这样,您将清除您的html 代码,它会更容易阅读、编写和调试。

    #parent {
      overflow: hidden;
      position: absolute;
      left: 50px;
      top: 50px;
      border-width: 1px;
      border-color: black;
      border-style: solid;
    }
    
    #header {
      border-color: red;
      border-width: 1px;
      border-style: solid;
    }
    
    #body {
      width: 200px;
      height: 170px;
      border-width: 1px;
      border-color: blue;
      border-style: solid;
      overflow: auto;
      resize: both;
    }
    
    #content {
      border-width: 1px;
      border-color: grey;
      border-style: solid;
    }
    
    #child {
      position: relative;
      top: 20px;
      left: 30px;
      width: 50px;
      height: 50px;
      border-width: 1px;
      border-color: green;
      border-style: solid;
    }
    <div id="parent">
      <div id="header">
        <p>No scroll bars in header</p>
      </div>
      <div id="body">
        <div id="content">
          <p>Content</p>
          <p>Content</p>
          <p>Content</p>
        </div>
        <div id="child">
          <p>Child</p>
        </div>
      </div>
    </div>

    【讨论】:

    • 感谢您的快速答复!使用相对定位会对实际代码产生其他影响,但我可以解决这个问题。至于您对使用 CSS 的评论,我发现如果一切都是内联的,那么简短的 sn-ps 代码更容易理解。但是,我同意您对生产代码的建议,并接受我在这种情况下使用 style 是个人喜好。
    • 哈!我说得太早了。我的真实代码使用jsplumb.github.io/jsplumb/dragging.html 实现对parentchild div 的拖动。并且“必需的 CSS”部分中的文档指出“您必须在您打算可拖动的元素上设置 position:absolute”。但是,您回答了所提出的问题,因此您的答案成立。我将研究提供我需要的所有功能的 jsplumb 替代方案。
    • 我在将解决方案应用于实际问题时发现了另一个缺陷:父 div 本身可能是另一个父级的子级,因此它需要position:relative。但是,这会弄乱父级的宽度。
    • 如果您需要帮助,我建议您发布另一个问题,同时保持原样,因为这可以帮助在父容器中遇到相同溢出问题的人。在另一个问题中,请确保您提供足够的代码来重现您的问题,就像您在此处所做的那样。它将确保您的问题不会太宽泛,最终会帮助更多的人。 :)
    【解决方案2】:

    当你给出绝对位置时,元素的定位是相对于它的第一个定位(非静态)祖先元素。在您的情况下,父级未定位或定位为静态。所以孩子将相对于视口定位。如果您希望孩子相对于父母(身体)定位,则必须使父母位置相对。

    <div id="body" style="position:relative; width: 300px; height: 250px; border-width: 1px; border-color: blue; border-style: solid; overflow: auto; resize: both;">
    

    【讨论】: