将div放置在另一个带有属性显示的div下方:栅格

2022-04-03 00:00:00 html css ionic-framework angular css-grid

我尝试使用diplay:grid将一个div放在另一个div之下时遇到了问题。该div被放置在另一个div的上面,而不是下面。

&qot;APP-BM-Payment-Card-Item&qot;是一个自定义角度组件。

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。当显示展开的卡列表时,div(文本)被正确地放置在列表下方,但是当堆叠的卡列表被激活时,div被放置在列表的顶部,这是错误的,它应该被放置在堆叠/折叠的卡列表的下方。请参见下图。


解决方案

有趣的问题,因为钱包中的卡数可以是1、2或N,并且grid-auto-rows和/或grid-template-rows需要在css中显式指定跟踪大小。

多种解决方案可用(节省网格使用)

#1简单但难看的那个

只需将margin-top: 200px;设置为文本div。仅当卡片堆叠时才应用此选项。

我不太喜欢此解决方案,因为它与其说是正确的设计,不如说是修复(&Q;)。

数据-lang="js"数据-隐藏="真"数据-控制台="假"数据-巴贝尔="假">
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>

或查找here the Codepen code

#2使用JavaScript检测并正确设置grid-auto-rows

在我看来,最好的解决方案是没有margin技巧,只有清除网格css。

为此,您需要一点JS来检测钱包中的卡数,然后设置值。

数据-lang="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>

或查找here the Codepen code

#3使用JavaScript将类设置为#wrapper

您还可以使用JS来检测卡片的数量,然后将正确的类应用到网格(#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(您只将一个类设置为div),这是一个不错的解决方案,但前提是您知道不可能拥有超过5或6张卡,因为用几十个无用的定义污染您的css不是一件好事。

相关文章