【问题标题】:Fill 100% of viewport with ignoring parent's side paddings but respecting the vertical scrollbar填充 100% 的视口,忽略父级的侧边距但尊重垂直滚动条
【发布时间】:2021-11-26 06:19:17
【问题描述】:

要求

  1. 尽管.Parent 有侧边距,.Child 必须填充 100% 的视口。
  2. 对于.Child.Parent 的侧边距提前未知(假设.Child 是一个可重复使用的组件,它不知道它使用的环境)
  3. 滚动条宽度取决于浏览器,因此它的宽度事先未知,无法硬编码
  4. .Child 的长度必须完全可见。

解决方案尝试

.Parent {
  background: #BBDEFB;
  padding: 0 20px;
}

.Child {
  width: 100vw;
  margin-left: calc(-0.5*(100vw - 100%));
  /* Child does not know that `Parent's` paddings are 20px */
  height: 40px;
  background: #FF8F00;
  border: 5px solid #283593;
}

.Dummy {
  height: 1000px;
  background: #E1BEE7;
}
<div class="Parent">
  <div class="Child"></div>
  <div class="Dummy"></div>
</div>

Child 的左右边框不可见。 我想原因是滚动条。

我们可以尊重滚动条吗?

【问题讨论】:

    标签: html css scrollbar


    【解决方案1】:

    我觉得可以通过这个来实现

    .Child {
        height: 40px;
        width: 100%;
        position: absolute;
        top: 0;
        left: 0;
        background: #FF8F00;
        border: 5px solid #283593;
        box-sizing: border-box
     }
    

    【讨论】:

      【解决方案2】:

      绝对位置解。

      1. 为高度定义一个变量并将body设置为position: relative;
      :root {
        --child-height: 40px;
      }
      body {
        position: relative;
      }
      
      1. 设置类.Child的绝对位置,使用left: 0right: 0,它将扩展到全宽。
      .Child {
        position: absolute;
        left: 0;
        right: 0;
        height: var(--child-height);
      }
      
      1. 使用变量添加到 .Dummy padding-top,以转换以获得完全可见性。
      .Dummy {
        padding-top: var(--child-height);
      }
      

      *,
      ::after,
      ::before {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      
      :root {
        --child-height: 40px;
      }
      
      body {
        position: relative;
      }
      
      .Parent {
        background: #8c9297;
        padding: 0 20px;
      }
      
      .Child {
        position: absolute;
        left: 0;
        right: 0;
        height: var(--child-height);
        background: #ff8f00;
        border: 5px solid #283593;
      }
      
      .Dummy {
        height: 1000px;
        padding-top: var(--child-height);
        background: #e1bee7;
      }
      <div class="Parent">
        <div class="Child"></div>
        <div class="Dummy"></div>
      </div>

      【讨论】:

        【解决方案3】:

        仅使用 CSS 无法完全解决此问题。您可以将其居中并使其成为视口宽度,但您无法确定没有 JS 的操作系统,因为滚动条相对于操作系统和浏览器会有所不同。

        以下是在每个浏览器中测试的滚动条尺寸:​​m>

        • OSX(Chrome、Safari、Firefox)- 15 像素
        • Windows XP(IE7、Chrome、Firefox)- 17 像素
        • Windows 7(IE10、IE11、Chrome、Firefox)- 17 像素
        • Windows 8.1(IE11、Chrome、Firefox)- 17 像素
        • Windows 10(IE11、Chrome、Firefox)- 17 像素
        • Windows 10(Edge 12/13)- 12 像素

        因此可能的解决方案是:

        1. 将子元素的宽度设置为(100vw - 滚动条宽度)
        2. 在页面上居中此元素。
        3. 检测操作系统并将相关类添加到正文元素
        4. 默认计算子元素的宽度和windows一样
        5. 在 Mac 和 Edge 浏览器中更改它

        if (navigator.appVersion.indexOf('Win') != -1) {
          document.body.classList.add('win');
        } else if (navigator.appVersion.indexOf('Mac') != -1) {
          document.body.classList.add('mac');
        }
        .Parent {
          background: #BBDEFB;
          padding: 0 20px;
        }
        .Child {
          box-sizing: border-box;
          width: calc(100vw - 17px);
          height: 50px;
          background: #FF8F00;
          border: 5px solid #283593;
          position: relative;
          left: 50%;
          transform: translateX(-50%);
        }
        /* MacOs */
        .mac .Child {
          width: calc(100vw - 15px);
        }
        /* Edge */
        @supports (-ms-ime-align:auto) {
         .Child {
            width: calc(100vw - 12px);
          }
        }
        .Dummy {
          height: 100vh;
          background: #E1BEE7;
        }
        <div class="Parent">
          <div class="Child"></div>
          <div class="Dummy"></div>
        </div>

        【讨论】:

          【解决方案4】:

          这可能不满足父级具有侧面“填充”的要求。我在这个答案中松散地解释了这一点。

          如果您不需要使用“vw”单位,则无需担心滚动条的宽度。就个人而言,我认为“100vw”和“100vh”现在是代码异味,因为滚动条和移动浏览器 chrome 存在所有潜在问题。

          * {
            box-sizing: border-box;
          }
          
          .Parent {
            display: grid;
            grid-template-columns: 20px 1fr 20px;
            background: lightblue;
          }
          
          .Child {
            grid-column: 1/-1;
            height: 40px;
            background: orange;
            border: 5px solid #283593;
          }
          
          .Dummy {
            grid-column: 2/3;
            height: 200px;
            background: pink;
          }
          <div class="Parent">
            <div class="Child"></div>
            <div class="Dummy"></div>
          </div>

          【讨论】:

          • 感谢您的回答!我选择了您的解决方案,因为它相对简单但灵活。尽管.Parent 在您的解决方案中没有填充,但您可以得到与grid-template-columns 相同的效果。主观上,这个解决方案可以在实际项目中使用。
          【解决方案5】:

          这个解决方案可能会有所帮助,我在 .child 中添加 "display:block" ,添加 width:auto 并删除 左边距

          .Parent {
            background: #BBDEFB;
            padding: 0 20px;
          }
          
          .Child {
            width: calc(100vw - 40px);
            margin:0 -20px;
          
            display: block;
            height: 40px;
            background: #FF8F00;
            border: 5px solid #283593;
          }
          
          .Dummy {
            height: 100vh;
            background: #E1BEE7;
          }
          <div class="Parent">
            <div class="Child"></div>
            <div class="Dummy"></div>
          </div>

          【讨论】:

          • 感谢您的回答!很抱歉,但在您的 sn-p 中,.Child 没有填满视口(第一个要求)。在Child 的左右两侧可以看到.Parent 的浅蓝色背景。您能否更正您的解决方案?
          • 抱歉,现在我知道您想要全角的橙色“div”。我更改了一些 CSS ".child" 类,你可以检查一下。
          • 非常抱歉两次拒绝您的帮助,但是现在您的解决方案不满足第二个要求,甚至仍然不满足第一个要求。在您建议的.Child 中:width: calc(100vw - 40px); margin:0 -20px;,这意味着我们知道.Parent 的填充是20px。但是根据第二个要求,我们事先不知道.Parent 的填充,因为.Child 作为可重用组件可以在任何其他父元素中使用。接下来,.Child 的右边框和视口的右边缘之间还有一个小间隙。这意味着.Child 没有填满视口。
          猜你喜欢
          • 1970-01-01
          • 2010-11-13
          • 1970-01-01
          • 1970-01-01
          • 2013-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-28
          相关资源
          最近更新 更多