如何考虑 CSS 网格设置中的动态行?



我的主仪表板有一个div元素堆叠在一起的一般结构(每个元素都是屏幕范围的,并提供不同类型的信息(。

我通过 CSS Grid 管理块的高度:整个应用程序是min-height: 100vh;的,行是auto的,除了一个是1fr的。效果很好。

我现在面临其中一条线动态存在或不存在的情况。这是因为它实际上是一个 Vue 组件,有条件地显示v-if.问题是CSS部分不知道它的存在,grid-template-rows是固定的。这会导致在切换时auto1fr错误的行。

如何解决?

我能想到的一种方法是强制组件的存在,其中 CSS 将其计为一行。现在,当它关闭时,我看到此元素在开发工具中<!----> == $0

另一个是"描述"列模板,而不是有一个固定的列表。类似于"尽可能多地使用auto,然后1frauto">


下面的两个代码片段模拟了我的问题。

第一种是所有元素都可见的情况

#app {
display: grid;
min-height: 100vh;
grid-template-rows: auto auto 1fr;
}
#footer {
align-self: end;
}
div {
border-style: dashed;
border-width: 1px;
}
<div id="app">
<div>this line is always visible</div>
<div>this one is toggled - here it is visible</div>
<div id="footer">this is the footer</div>
</div>

下面的代码相同,但切换了第二行(此处注释掉,在实际代码中通过v-if禁用(。看看它如何影响不再位于底部的页脚,因为 CSS 没有改变(= 没有适应消失的行(

#app {
display: grid;
min-height: 100vh;
grid-template-rows: auto auto 1fr;
}
#footer {
align-self: end;
}
div {
border-style: dashed;
border-width: 1px;
}
<div id="app">
<div>this line is always visible</div>
<!-- <div>this one is toggled - here it is not visible anymore </div> -->
<div id="footer">this is the footer</div>
</div>

一个想法是明确定义页脚的行,使其始终使用最后一个行:

#app {
display: grid;
min-height: 100vh;
grid-template-rows: auto auto 1fr;
}
#footer {
align-self: end;
grid-row:-1;
}
div {
border-style: dashed;
border-width: 1px;
}
<div id="app">
<div>this line is always visible</div>
<div>this one is toggled - here it is visible</div>
<div id="footer">this is the footer</div>
</div>
<div id="app">
<div>this line is always visible</div>
<!--<div>this one is toggled - here it is visible</div>-->
<div id="footer">this is the footer</div>
</div>

CSS grid系统不是动态行/列的最佳选择。当您提前知道布局时,它处于最佳状态。

但是,您可以做一些事情。

选项 1

您可以使用内联样式(在父元素内(定义grid-template-rows: auto auto 1fr;,并使用javascript进行控制。

因此,在这种情况下:

<div id="app" style="grid-template-rows: auto auto 1fr;">

随着行数的变化,样式的值也会发生变化。

<div id="app" style="grid-template-rows: auto 1fr;">

选项 2

提前定义多个类,并根据行数切换到适当的类:

.rows-2
grid-template-rows: auto 1fr;
}
.rows-3
grid-template-rows: auto auto 1fr;
}
<div id="app" class="rows-2/3">

这两种解决方案都需要一些 JavaScript 来调整所需的网格布局。

最新更新