Rob*_*bie 10 html css css-grid
我遇到了CSS网格元素的高度问题.我使用的代码是:
.gridContainer {
border: thin solid black;
background: rgba(255, 0, 0, 0.5);
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
width: 100px;
height: 100px;
grid-template-areas: 'windowContentHolder';
}
.gridItem {
grid-area: windowContentHolder;
background: rgba(255, 255, 0, 0.5);
width: 200%;
height: 200%;
}
.content {
background: rgba(255, 0, 0, 0.5);
}Run Code Online (Sandbox Code Playgroud)
<div class="gridContainer">
<div class="gridItem">
<div class="content">hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
如您所见,gridItem设置为height:200%,预期结果不符合预期.它应该是200px父(100px)的两倍(),滚动条隐藏任何额外的高度,而高度属性似乎根本没有设置.
似乎百分比正在考虑子高度而不是父高度,因为如果我们仔细检查元素,我们将看到它的高度是子元素高度的两倍.
带有'hi'的元素没有像预期的那样溢出.更改gridContainer为'block'确实可以正常工作,但不能使用'grid':
.gridContainer {
border: thin solid black;
background: rgba(255, 0, 0, 0.5);
display: block;
width: 100px;
height: 100px;
}
.gridItem {
grid-area: windowContentHolder;
background: rgba(255, 255, 0, 0.5);
width: 200%;
height: 200%;
overflow: auto;
}
.content {
background: rgba(255, 0, 0, 0.5);
}Run Code Online (Sandbox Code Playgroud)
<div class="gridContainer">
<div class="gridItem">
<div class="content">hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
Mic*_*l_B 12
网格容器的高度固定为100px.
网格项的高度设置为200%.
轨道内存在网格项,它存在于容器内.
您可以将网格项视为从容器中向下存在的两个级别.
换句话说,网格项的父级是轨道,而不是容器.
由于您的行高既不是固定的,也不是真正的长度单位 - 它设置为1fr- 网格项的百分比高度失败,并且可以根据需要自由扩展行(height: auto).
无论您在容器上设置固定高度,还要将其设置在行上.
.gridContainer {
border: thin solid black;
background: rgba(255, 0, 0, 0.5);
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px; /* adjustment; value was 1fr */
width: 100px;
height: 100px;
grid-template-areas: 'windowContentHolder';
}
.gridItem {
grid-area: windowContentHolder;
background: rgba(255, 255, 0, 0.5);
width: 200%;
height: 200%;
overflow: auto;
}
.content {
background: rgba(255, 0, 0, 0.5);
}Run Code Online (Sandbox Code Playgroud)
<div class="gridContainer">
<div class="gridItem">
<div class="content">hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
新答案
终于找到了对这种行为的逻辑解释。
首先,我们需要了解它的行为1fr等于minmax(auto,1fr)并且如本问题所述,它将默认为最小内容,这就是为什么我们的网格区域大于定义的height:100px
如果我们将其替换为minmax(0,1fr)将使我们的网格面积等于容器高度,那么我们的项目仍然会大两倍。
.gridContainer {
border: thin solid black;
background: rgba(255, 0, 0, 0.5);
display: grid;
grid-template-columns: 1fr;
grid-template-rows: minmax(0,1fr);
width: 100px;
height: 100px;
grid-template-areas: 'windowContentHolder';
}
.gridItem {
grid-area: windowContentHolder;
background: rgba(255, 255, 0, 0.5);
width: 200%;
height: 200%;
}
.content {
background: rgba(255, 0, 0, 0.5);
}Run Code Online (Sandbox Code Playgroud)
<div class="gridContainer">
<div class="gridItem">
<div class="content">hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>hi<br/>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
对于第二个行为 (the height:200%),我们需要参考规范我们可以阅读:
一旦确定了每个网格区域的大小,网格项目就会被布置到它们各自的包含块中。为此目的,网格区域的宽度和高度被认为是确定的。
所以网格区域首先是根据内容定义的,如果我们使用,1fr或者根据容器的高度,如果我们使用minmax(0,1fr)。然后将该高度用作我们百分比高度的参考。
这就是为什么在所有情况下,网格项最终会比网格区域大两倍,而在您的情况下,内容定义了该高度。
旧答案
首先,让我们从定义百分比高度的工作原理开始:
指定百分比高度。百分比是相对于生成的框的包含块的高度计算的。如果未明确指定包含块的高度(即,它取决于内容高度),并且该元素不是绝对定位的,则该值计算为 'auto'。参考
有时,百分比大小的框的包含块的大小取决于框本身的内在大小贡献,从而产生循环依赖。在计算这样一个盒子的内在大小贡献时,一个循环百分比——也就是说,一个百分比值将解决一个包含块大小,它本身取决于该百分比——是专门解决的...... (然后是很多规则)
在某些特定情况下,即使未明确指定包含块的高度,浏览器也能够解析百分比值。
正如 Michael_B 所说,元素存在于容器内的轨道内,所以这里的包含块不再是容器而是轨道。
网格轨道是网格列或网格行的通称——换句话说,它是两条相邻网格线之间的空间。每个网格轨道都分配了一个大小函数,该函数控制列或行可以增长的宽度或高度,从而控制其边界网格线相距多远。相邻的网格轨道可以被排水沟隔开,但否则会紧紧地挤在一起。参考
这些元素的大小如何?
网格的轨道(行和列)通过显式网格属性显式声明和调整大小,或者在项目放置在显式网格之外时隐式创建。grid 简写及其子属性定义了 grid ref的参数
我们还可以在此处阅读更多信息:6.2。网格项目大小调整,这里:6.6。网格项目的自动最小尺寸和这里7.2。显式轨道大小
所有这些规范都很难遵循,所以这里是我自己的简化解释,以了解正在发生的事情。
浏览器首先考虑内容和网格属性计算轨道的大小,然后将此高度用作百分比值的参考。
这是另一个示例,可以更好地显示正在发生的事情:
.box {
display: grid;
height: 100px;
width: 200px;
grid-template-columns: 1fr 1fr;
grid-gap:5px;
background: red;
}
.box>div {
background: rgba(0, 0, 0, 0.4);
height: 200%;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div class="first">
lorem<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br>
</div>
<div class="second">
lorem<br> lorem
<br> lorem
<br> lorem
<br>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
我们有一个包含display:grid和 2 列的容器,第一列包含比第二列更多的内容,并且我们已应用到两个height:200%. 令人惊讶的是,两者的高度都是第一个内容高度的两倍!
如果我们检查开发工具,我们可以看到:
虚线框定义了我们的轨道大小,里面有两个网格单元。由于它是一个网格,轨道的高度将由最高的内容定义,这也将使两个单元格具有相同的高度。所以height:200%不完全是内容的高度,而是最初由内容定义的轨道的高度。
如果我们再次检查 Micheal_B 的答案,明确定义轨道高度也会给我们一个合乎逻辑的和微不足道的结果,因为计算很容易,而且我们没有复杂的循环。
.box {
display: grid;
height: 100px;/*this will not be considered*/
width: 200px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 150px;/* this will be considered*/
grid-gap: 5px;
background: red;
}
.box>div {
background: rgba(0, 0, 0, 0.4);
height: 200%;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div class="first">
lorem<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br>
</div>
<div class="second">
lorem<br> lorem
<br> lorem
<br> lorem
<br>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,我指定了轨道,150px因此height:200%等于300px。
这不是唯一的情况。我还发现了 flexbox 的另一个案例,我们可以在包含块上使用百分比高度而没有任何明确的高度。
.container {
height:200px;
background:red;
display:flex;
}
.box {
width:100px;
background:blue;
}
.box > div {
background:yellow;
height:50%;
}Run Code Online (Sandbox Code Playgroud)
<div class="container">
<div class="box">
<div></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
正如我们所看到的 height:50%,工作正常,使黄色框占其父元素(蓝色框)的 50%。
解释与flexbox的默认拉伸行为有关。默认情况下,弹性项目没有由内容定义的高度,但它的高度被拉伸以填充父容器的高度,因此浏览器将计算一个新的高度,使子项的百分比值相对于该高度。
如果 flex 项目有
align-self: stretch,重做其内容的布局,将此使用的大小视为其确定的交叉大小,以便可以解析百分比大小的子项。参考
这是另一个示例,显示了网格示例的类似行为:
.box {
display: flex;
width: 200px;
background: red;
}
.box>div {
background: rgba(0, 0, 0, 0.4);
}
.second >div {
height:200%;
background:yellow;
width:50px;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div class="first">
lorem<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br>
</div>
<div class="second">
<div></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
父元素的高度由最高的元素定义,即 second元素被拉伸到那个高度,黄色元素的高度是相同高度的两倍。
换句话说,我们所拥有的在某种程度上是合乎逻辑的,因为即使我们没有指定明确的高度,浏览器也能够首先计算包含块的高度,然后使用计算值解析百分比。
更新
这是另一个有趣的结果,考虑top属性。我们也知道百分比值top也是指元素的包含块的高度,这个高度需要定义。
这是一个插图:
.box {
border:5px solid;
}
.box > div {
position:relative;
top:100%;
height:100px;
background:red;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div>This div won't move because the parent has no height specified</div>
</div>
<div class="box" style="height:100px;">
<div>This div will move because the parent has a height specified</div>
</div>Run Code Online (Sandbox Code Playgroud)
现在如果我们考虑我们之前的案例, top将使用百分比值,例如 height 正在做的事情。
使用 CSS 网格
.box {
display: grid;
height: 100px;/*this will not be considered*/
width: 200px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 150px;/* this will be considered*/
grid-gap: 5px;
background: red;
}
.box>div {
position:relative;
top:100%;
background: rgba(0, 0, 0, 0.4);
height: 200%;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div class="first">
lorem<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br>
</div>
<div class="second">
lorem<br> lorem
<br> lorem
<br> lorem
<br>
</div>
</div>
<div class="b">
<div class="a">
</div>
</div>Run Code Online (Sandbox Code Playgroud)
使用弹性盒:
.box {
display: flex;
width: 200px;
background: red;
}
.box>div {
background: rgba(0, 0, 0, 0.4);
}
.second >div {
position:relative;
top:100%;
height:200%;
background:yellow;
width:50px;
}Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div class="first">
lorem<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br> lorem
<br>
</div>
<div class="second">
<div></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
596 次 |
| 最近记录: |