忽略父级的侧边距但尊重垂直滚动条,填充 100% 的视口

Fill 100% of viewport with ignoring parent's side paddings but respecting the vertical scrollbar

要求

  1. .Child 必须填充 100% 的视口,尽管 .Parent 有边距。
  2. .Parent 的侧边距 事先未知 .Child(假设 .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的左右边框不可见。 我想原因是滚动条。

我们可以尊重滚动条吗?

这个解决方案可能会有帮助,我在 .child 中添加 "display:block" ,添加 width: auto & 删除 margin-left.

.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>

这可能无法满足父级具有边“填充”的要求。我在这个答案中对此进行了松散的解释。

如果您不需要使用“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>

仅用CSS是无法完全解决的。您可以将它居中并使其成为视口宽度,但是如果没有 JS 则无法确定 OS,因为滚动条相对于 OS 和浏览器会有所不同。

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

  • OSX(Chrome、Safari、Firefox)- 15px
  • Windows XP(IE7、Chrome、Firefox)- 17px
  • Windows 7(IE10、IE11、Chrome、火狐)- 17px
  • Windows 8.1(IE11、Chrome、火狐)- 17px
  • Windows 10(IE11、Chrome、火狐)- 17px
  • Windows 10(边缘 12/13)- 12px

所以pos可行的解可以是:

  1. 设置子元素的宽度为(100vw - 滚动条宽度)
  2. 将此元素置于页面中央。
  3. 检测OS并将相对class添加到正文元素
  4. 默认计算子元素宽度为windowsos
  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>

具有绝对位置的解决方案。

  1. 为高度定义一个变量并将body设置为position: relative;
:root {
  --child-height: 40px;
}
body {
  position: relative;
}
  1. 设置 class .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>

我觉得可以这样实现

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