将 div 放在另一个 div 的下面 属性 display:grid
Place div below another div with property display:grid
我在尝试将 div 放在另一个带有 diplay:grid 的 div 下方时遇到问题。 div 被放置在另一个上面而不是下面。
“app-bm-payment-card-item”是自定义 Angular 组件。
HTML 文件
//div wrapper
<div *ngIf="pageReady && myProfiles" class="ion-padding">
//div showing the cards stacked or collapsed
<div *ngIf="!inEditMode" class="card_container_stacked_main">
<app-bm-payment-card-item *ngFor="let card of myProfiles" [card]="card" [editMode]="inEditMode"
(onDeleteClick)="removeCard(card)" (onSelect)="selectCard(card)" (onEditClick)="editCardInfo(card)">
</app-bm-payment-card-item>
</div>
//div showing the cards expanded
<div *ngIf="inEditMode" class="card_container_expanded_main">
<app-bm-payment-card-item *ngFor="let card of myProfiles" [card]="card" [editMode]="inEditMode"
(onDeleteClick)="removeCard(card)" (onSelect)="selectCard(card)" (onEditClick)="editCardInfo(card)">
</app-bm-payment-card-item>
</div>
//div to be placed below the other one(s)
<div class="div">
TEXT
</div>
</div>
SCSS 文件:
.card_container_stacked_main {
display:grid;
position: relative;
grid-auto-rows:30px; /* a fixed height to create an overflow */
}
.card_container_expanded_main {
position: relative;
max-width: 400px !important;
//margin-bottom: 15px;
}
.div {
position: relative;
}
所以,基本功能是当点击任何卡片时,卡片列表应该显示为堆叠或折叠。这就是为什么我使用 inEditMode 布尔值来了解应该显示哪个 div 以及隐藏哪个。当显示展开的卡片列表时,div (TEXT) 被正确地放置在列表下方,但是当激活堆叠卡片列表时,div 被放置在列表顶部,这是错误的, 它应该放在 stacked/collapsed 卡列表下面。见下图。
这应该将文本移到最后一张卡片下。我测试了它并为我工作:
设置 属性 stackedContainerHeight 或类似的东西并计算容器高度 ->
stackedContainerHeight = height of a stacked card in pixels * (lenght of card/profile array -1) + full card height + adjustments like margins etc.
例如:
stackedContainerHeight = 30 * (this.myProfiles.length-1) + 50 +15;
动态设置容器元素的堆叠容器高度
[style.height.px]="stackedContainerHeight"
原问题是什么:grid-auto-rows裁剪了容器高度,最后满卡的一部分流过容器。此解决方案计算出正确的高度,文本 div 将在容器正确呈现后呈现。
有趣的问题,因为“钱包”中的卡片数量可以是 1、2 或 N
,而且 grid-auto-rows
and/or grid-template-rows
需要在 CSS.
中明确指定 跟踪大小
多种解决方案可用(保留网格的使用)
#1 简单但丑陋的
只需将 margin-top: 200px;
设置为 TEXT div。仅当卡片堆叠时才应用此方法。
我不是这个解决方案的忠实粉丝,因为它更像是一个“修复”而不是一个合适的设计。
function expandStackCards() {
var wrapper = document.getElementById("wrapper");
if (wrapper.classList.contains("stacked")) {
wrapper.classList.remove("stacked");
} else {
wrapper.classList.add("stacked");
}
}
button {
width: 400px;
margin-bottom: 10px;
}
#wrapper {
display: grid;
grid-template-columns: 400px;
gap: 10px;
}
#wrapper.stacked {
grid-auto-rows: 30px;
gap: 0px;
}
.card {
width: 100%;
height: 200px;
background-color: grey;
border-radius: 20px;
padding: 6px 20px;
box-sizing: border-box;
}
.card span {
font-family: sans-serif;
text-transform: uppercase;
color: white;
}
.card.green {
background-color: green;
}
.card.blue {
background-color: blue;
}
.my-text {
margin: 10px;
}
.stacked .my-text {
margin-top: 200px;
}
<button onclick="expandStackCards()">Expand / Stack</button>
<div id="wrapper" class="stacked">
<div class="card green"><span>Card #1</span></div>
<div class="card blue"><span>Card #2</span></div>
<div class="my-text">TEXT</div>
</div>
#2 使用 JavaScript 检测并正确设置 grid-auto-rows
值
我认为最好的解决方案,因为没有 margin
技巧,只有 pur 网格 CSS.
为此,您需要一些 JS 来检测钱包中卡的数量,然后设置值。
function stackedCards() {
var wrapper = document.querySelector('#wrapper.stacked');
if (wrapper) {
var num_cards = wrapper.querySelectorAll(':scope .card').length;
let style = getComputedStyle(wrapper);
row_height_str = style.gridAutoRows;
var new_grid_auto_rows = row_height_str.concat(' ').repeat(num_cards - 1);
new_grid_auto_rows = new_grid_auto_rows.concat('auto');
wrapper.style.gridAutoRows = new_grid_auto_rows;
}
}
// This function is only for the DEMO button
function expandStackCards() {
var wrapper = document.getElementById("wrapper");
if (wrapper.classList.contains("stacked")) {
wrapper.classList.remove("stacked");
wrapper.style.removeProperty("grid-auto-rows");
} else {
wrapper.classList.add("stacked");
stackedCards();
}
}
stackedCards();
button {
width: 400px;
margin-bottom: 10px;
}
#wrapper {
display: grid;
grid-template-columns: 400px;
gap: 10px;
}
#wrapper.stacked {
grid-auto-rows: 30px;
gap: 0px;
}
.card {
width: 100%;
height: 200px;
background-color: grey;
border-radius: 20px;
padding: 6px 20px;
box-sizing: border-box;
}
.card span {
font-family: sans-serif;
text-transform: uppercase;
color: white;
}
.card.green {
background-color: green;
}
.card.blue {
background-color: blue;
}
.my-text {
margin: 10px;
}
<button onclick="expandStackCards()">Expand / Stack</button>
<div id="wrapper" class="stacked">
<div class="card green"><span>Card #1</span></div>
<div class="card blue"><span>Card #2</span></div>
<div class="my-text">TEXT</div>
</div>
#3 使用 JavaScript 将 class 设置为 #wrapper
也可以用JS检测出牌数,然后把右边的class应用到格子上(#wrapper
)。
它有点像之前的解决方案,但没有通过 JS 应用 CSS 样式,但是当然为此你需要在你的 CSS 文件中有这样的东西:
.wallet-1-cards {
grid-auto-rows: auto;
}
.wallet-2-cards {
grid-auto-rows: 30px auto;
}
.wallet-3-cards {
grid-auto-rows: 30px 30px auto;
}
.wallet-4-cards {
grid-auto-rows: 30px 30px 30px auto;
}
// etc...
使用第三种解决方案,您可以避免在 JS 代码中执行 CSS(您只需将 class 设置为 div),只有当您知道时,这才是一个不错的解决方案不可能有超过 5 或 6 张卡片,因为用几十个无用的定义污染你的 CSS 不是一件好事。
我在尝试将 div 放在另一个带有 diplay:grid 的 div 下方时遇到问题。 div 被放置在另一个上面而不是下面。
“app-bm-payment-card-item”是自定义 Angular 组件。
HTML 文件
//div wrapper
<div *ngIf="pageReady && myProfiles" class="ion-padding">
//div showing the cards stacked or collapsed
<div *ngIf="!inEditMode" class="card_container_stacked_main">
<app-bm-payment-card-item *ngFor="let card of myProfiles" [card]="card" [editMode]="inEditMode"
(onDeleteClick)="removeCard(card)" (onSelect)="selectCard(card)" (onEditClick)="editCardInfo(card)">
</app-bm-payment-card-item>
</div>
//div showing the cards expanded
<div *ngIf="inEditMode" class="card_container_expanded_main">
<app-bm-payment-card-item *ngFor="let card of myProfiles" [card]="card" [editMode]="inEditMode"
(onDeleteClick)="removeCard(card)" (onSelect)="selectCard(card)" (onEditClick)="editCardInfo(card)">
</app-bm-payment-card-item>
</div>
//div to be placed below the other one(s)
<div class="div">
TEXT
</div>
</div>
SCSS 文件:
.card_container_stacked_main {
display:grid;
position: relative;
grid-auto-rows:30px; /* a fixed height to create an overflow */
}
.card_container_expanded_main {
position: relative;
max-width: 400px !important;
//margin-bottom: 15px;
}
.div {
position: relative;
}
所以,基本功能是当点击任何卡片时,卡片列表应该显示为堆叠或折叠。这就是为什么我使用 inEditMode 布尔值来了解应该显示哪个 div 以及隐藏哪个。当显示展开的卡片列表时,div (TEXT) 被正确地放置在列表下方,但是当激活堆叠卡片列表时,div 被放置在列表顶部,这是错误的, 它应该放在 stacked/collapsed 卡列表下面。见下图。
这应该将文本移到最后一张卡片下。我测试了它并为我工作:
设置 属性 stackedContainerHeight 或类似的东西并计算容器高度 ->
stackedContainerHeight = height of a stacked card in pixels * (lenght of card/profile array -1) + full card height + adjustments like margins etc.
例如:
stackedContainerHeight = 30 * (this.myProfiles.length-1) + 50 +15;
动态设置容器元素的堆叠容器高度
[style.height.px]="stackedContainerHeight"
原问题是什么:grid-auto-rows裁剪了容器高度,最后满卡的一部分流过容器。此解决方案计算出正确的高度,文本 div 将在容器正确呈现后呈现。
有趣的问题,因为“钱包”中的卡片数量可以是 1、2 或 N
,而且 grid-auto-rows
and/or grid-template-rows
需要在 CSS.
多种解决方案可用(保留网格的使用)
#1 简单但丑陋的
只需将 margin-top: 200px;
设置为 TEXT div。仅当卡片堆叠时才应用此方法。
我不是这个解决方案的忠实粉丝,因为它更像是一个“修复”而不是一个合适的设计。
function expandStackCards() {
var wrapper = document.getElementById("wrapper");
if (wrapper.classList.contains("stacked")) {
wrapper.classList.remove("stacked");
} else {
wrapper.classList.add("stacked");
}
}
button {
width: 400px;
margin-bottom: 10px;
}
#wrapper {
display: grid;
grid-template-columns: 400px;
gap: 10px;
}
#wrapper.stacked {
grid-auto-rows: 30px;
gap: 0px;
}
.card {
width: 100%;
height: 200px;
background-color: grey;
border-radius: 20px;
padding: 6px 20px;
box-sizing: border-box;
}
.card span {
font-family: sans-serif;
text-transform: uppercase;
color: white;
}
.card.green {
background-color: green;
}
.card.blue {
background-color: blue;
}
.my-text {
margin: 10px;
}
.stacked .my-text {
margin-top: 200px;
}
<button onclick="expandStackCards()">Expand / Stack</button>
<div id="wrapper" class="stacked">
<div class="card green"><span>Card #1</span></div>
<div class="card blue"><span>Card #2</span></div>
<div class="my-text">TEXT</div>
</div>
#2 使用 JavaScript 检测并正确设置 grid-auto-rows
值
我认为最好的解决方案,因为没有 margin
技巧,只有 pur 网格 CSS.
为此,您需要一些 JS 来检测钱包中卡的数量,然后设置值。
function stackedCards() {
var wrapper = document.querySelector('#wrapper.stacked');
if (wrapper) {
var num_cards = wrapper.querySelectorAll(':scope .card').length;
let style = getComputedStyle(wrapper);
row_height_str = style.gridAutoRows;
var new_grid_auto_rows = row_height_str.concat(' ').repeat(num_cards - 1);
new_grid_auto_rows = new_grid_auto_rows.concat('auto');
wrapper.style.gridAutoRows = new_grid_auto_rows;
}
}
// This function is only for the DEMO button
function expandStackCards() {
var wrapper = document.getElementById("wrapper");
if (wrapper.classList.contains("stacked")) {
wrapper.classList.remove("stacked");
wrapper.style.removeProperty("grid-auto-rows");
} else {
wrapper.classList.add("stacked");
stackedCards();
}
}
stackedCards();
button {
width: 400px;
margin-bottom: 10px;
}
#wrapper {
display: grid;
grid-template-columns: 400px;
gap: 10px;
}
#wrapper.stacked {
grid-auto-rows: 30px;
gap: 0px;
}
.card {
width: 100%;
height: 200px;
background-color: grey;
border-radius: 20px;
padding: 6px 20px;
box-sizing: border-box;
}
.card span {
font-family: sans-serif;
text-transform: uppercase;
color: white;
}
.card.green {
background-color: green;
}
.card.blue {
background-color: blue;
}
.my-text {
margin: 10px;
}
<button onclick="expandStackCards()">Expand / Stack</button>
<div id="wrapper" class="stacked">
<div class="card green"><span>Card #1</span></div>
<div class="card blue"><span>Card #2</span></div>
<div class="my-text">TEXT</div>
</div>
#3 使用 JavaScript 将 class 设置为 #wrapper
也可以用JS检测出牌数,然后把右边的class应用到格子上(#wrapper
)。
它有点像之前的解决方案,但没有通过 JS 应用 CSS 样式,但是当然为此你需要在你的 CSS 文件中有这样的东西:
.wallet-1-cards {
grid-auto-rows: auto;
}
.wallet-2-cards {
grid-auto-rows: 30px auto;
}
.wallet-3-cards {
grid-auto-rows: 30px 30px auto;
}
.wallet-4-cards {
grid-auto-rows: 30px 30px 30px auto;
}
// etc...
使用第三种解决方案,您可以避免在 JS 代码中执行 CSS(您只需将 class 设置为 div),只有当您知道时,这才是一个不错的解决方案不可能有超过 5 或 6 张卡片,因为用几十个无用的定义污染你的 CSS 不是一件好事。