为什么内盒不能扩展到外盒的宽度?

时间:2017-12-11 13:57:29

标签: html css

这不是一个学术问题。它在工作期间出现了。我把它归结为一个简单的问题。

我把一个div放在另一个里面。我希望内部div占据外部div的宽度。最初,就是这样。

然后,如果我在外部div中放入一堆文本,使其比视口宽,告诉外部div不要包装文本,并告诉外部div滚动,情况会发生变化。

内部div采用视口的宽度。您可以来回滚动外部div,并看到外部div是文本的宽度,但内部div是视口的宽度。

这里发生了什么?我会说内部div占据外部div的宽度,期间。

https://plnkr.co/edit/XaysEo?p=preview

  <body>
    <my-app>
    loading...
  </my-app>
  <div>
    This is after the angular part.
  </div>
  <div id="outerDiv" style="background-color:blue;white-space:nowrap;overflow-x:scroll;">
    This is a bunch of text.  It is here to make the outer box wider than the viewport.  Today, Bette and I had lunch at Outback.  Outback's steak was good.
    <div id="innerDiv" style="background-color:red;">
      Just some text to make it appear.
    </div>
  </div>
  <div>
    &nbsp;
  </div>
  <div id="outerDivWidth">
    Hello?
  </div>
  <div id="innerDivWidth">
    Hello?
  </div>
  <script>
    let od = document.getElementById('outerDiv');
    console.log(od);
    let ow = od.offsetWidth;
    console.log(ow);
    let odw = document.getElementById('outerDivWidth')
    odw.textContent = ow;

    let id = document.getElementById('innerDiv');
    let iw = id.offsetWidth;
    let idw = document.getElementById('innerDivWidth')
    idw.textContent = iw;
  </script>
  </body>

3 个答案:

答案 0 :(得分:2)

根据我对浏览器处理和渲染块级元素的理解,我将逐步解释。

块级元素的宽度 Ref

<div>的宽度(默认为块级元素)将等于其父级生成的包含块计算宽度

这意味着#innerDiv将展开以匹配#outerDiv计算宽度#outerDiv将展开以匹配计算的宽度 <body>。在您的情况下,这意味着它们或多或少等于视口宽度。

匿名阻止框 Ref

当块容器框(如#outerDiv)包含另一个块级框(#innerDiv)时,它将被强制包含块级框。< / p>

在您的情况下,您在#outerDiv内也有文字,但在#innerDiv之外。此文本将呈现为好像是匿名块级别框的内容。就好像你的第一行文字被包裹在一个不可见的<div>

抑制换行

white-space:nowrap应用于#outerDiv会阻止匿名阻止级别框中的文本突破到第二行。它的内容将忽略其父元素的右边距,并最终流过#outerDiv的右边缘。结合overflow-x:scroll,这将强制执行水平滚动条。

结果

正如你描述的那样; &#34;内部div占据视口的宽度。您可以来回滚动外部div。这里发生了什么?我会说内部div占据外部div的宽度,期间&#34;

你是正确的#innerDiv实际上 的宽度为#outerDiv。由于#outerDiv的宽度取决于其父级,因此它不会受到其中匿名块级别框的宽度的影响。

我们所看到的更像是一种视错觉。它实际上是匿名阻止框#innerDiv在由#outerDiv生成的块容器内滚动。

如果您将背景图像应用于#outerDiv,则会显示此信息。滚动时,您将看到保留的背景图像:

&#13;
&#13;
// You'll see .outer and .inner have equal widths
let o = document.querySelector('.outer'),
    i = o.querySelector('.inner');
console.log(o.clientWidth, i.clientWidth);
&#13;
body {
  /*Only for this test*/
  max-width: 500px;
}

.outer {
  background-color: blue;
  white-space: nowrap;
  overflow-x: scroll;
  background: url(https://www.google.com/logos/doodles/2017/kenya-independence-day-2017-5686012280832000-2x.png) 50% 50%;
}

.inner {
  display: block;
  background-color: red;
}
&#13;
<div class="outer">
  This is a bunch of text. It is here to make the outer box wider than the viewport. Today, Bette and I had lunch at Outback. Outback's steak was good.
  <div class="inner">
    Just some text to make it appear.
  </div>
</div>
&#13;
&#13;
&#13;

网格救援?

如果您正在寻找解决方案,可以在其他答案中提出几种方法。另一种方法是将display:grid应用于#outerDiv。我仍然不太熟悉CSS网格,但我的理解是这将强制#innerDiv匹配#outerDiv其余内容的宽度。这可能不适用于所有情况,但它会使结果更像您所描述的结果。

请注意控制台中.inner宽于.outer的元素宽度。

&#13;
&#13;
// You'll see .inner is wider than .outer
let o = document.querySelector('.outer'),
    i = o.querySelector('.inner');
console.log(o.clientWidth, i.clientWidth);
&#13;
body {
  /*Only for this test*/
  max-width: 500px;
}

.outer {
  display: grid;
  background-color: blue;
  white-space: nowrap;
  overflow-x: scroll;
}

.inner {
  display: block;
  background-color: red;
}
&#13;
<div class="outer">
  This is a bunch of text. It is here to make the outer box wider than the viewport. Today, Bette and I had lunch at Outback. Outback's steak was good.
  <div class="inner">
    Just some text to make it appear.
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

width的标准div设置为100%,与其父div相关。因此,outerDiv的{​​{1}}跨度100%。现在,当您允许viewport时,overflow的{​​{3}}不会更改,仍然是div的{​​{1}}。更改的是 内容的 100% *。

我认为,问题的结果是因为viewport仍然与width的{​​{1}}有关,而与扩展内容的innerDiv无关(可能是轻微的疏忽) W3C)。我希望这个比较清楚吗?

*因此,您实际上是在width的边框内滚动内容。不是outerDiv边框内的width

可能的解决方案:

您可以获取元素的offsetWidth(等于内容的div)。因此,使用div,您可以相应地设置body的{​​{1}}:

width

scrollWidth帖子可能有帮助。

答案 2 :(得分:0)

您可以在display: table;上使用#outerDiv。不理想的表格(甚至CSS表格)不适用于布局,但它有效。可能会引入一些副作用。

This相关问题对于更详细地解释非常有用。

编辑:根据MrLister的要求更详细地解释。我相信,除非明确说明,否则对于块元素,宽度将默认为父元素的100%。但是,由于父级未指定宽度,因此默认为视口的100%,因为它是根元素。 (尝试在#outerDiv上将宽度设置为1000px,#innerDiv也会拉伸)。使用display: table重置此项,因为所有块子元素都会延伸到表格的宽度。