这不是一个学术问题。它在工作期间出现了。我把它归结为一个简单的问题。
我把一个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>
</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>
答案 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
,则会显示此信息。滚动时,您将看到保留的背景图像:
// 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;
网格救援?
如果您正在寻找解决方案,可以在其他答案中提出几种方法。另一种方法是将display:grid
应用于#outerDiv
。我仍然不太熟悉CSS网格,但我的理解是这将强制#innerDiv
匹配#outerDiv
其余内容的宽度。这可能不适用于所有情况,但它会使结果更像您所描述的结果。
请注意控制台中.inner
宽于.outer
的元素宽度。
// 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;
答案 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
重置此项,因为所有块子元素都会延伸到表格的宽度。