如何以固定宽度重叠弹性项目?

问题描述 投票:0回答:1

我想要的最终结果是this,而我能够得到的结果是this

基本上,当卡片溢出其父级时,我希望卡片以固定宽度重叠。 当它没有溢出时,我希望它们根据纵横比保留宽度。 我已经固定了高度,所以宽度也应该是恒定的。

您可以点击每张卡片,它将在每个链接中删除。但是在第二个/不工作的链接中,卡变得太大,这也是一个问题。

我该如何解决这个问题?

<div class="container">
  <div class="player player-1"> p1 </div>
  <div class="card_area card_area-1">card-1</div>

  <div class="player player-2">p2</div>
  <div class="card_area card_area-2">card-2</div>

  <div class="player player-3">p3</div>
  <div class="card_area card_area-3">card-3</div>

  <div class="player player-4">p4</div>
  <div id="render_cards" class="card_area  card_area-4">
    <div class="card card-odd card-1">card-1</div>
    <div class="card card-even card-2">card-2</div>
    <div class="card card-odd card-3">card-3</div>
    <div class="card card-even card-4">card-4</div>
    <div class="card card-odd card-5">card-5</div>
    <div class="card card-even card-6">card-6</div>
    <div class="card card-odd card-7">card-7</div>
    <div class="card card-even card-8">card-8</div>
    <div class="card card-odd card-9">card-9</div>
    <div class="card card-even card-10">card-10</div>
    <div class="card card-odd card-11">card-11</div>
    <div class="card card-even card-12">card-12</div>
    <div class="card card-odd card-13">card-13</div>

  </div>
</div>
.container {
  width: 60%;
  margin: 5px auto;
  border: 2px solid green;
  aspect-ratio: 3/2;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(6, minmax(0, 1fr));
}

.player {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: bisque;
}

.player-1 {
  grid-row: 1;
  grid-column: 3;
}

.card_area-1 {
  grid-row: 1;
  grid-column: 4;
}

.player-2 {
  grid-row: 4;
  grid-column: 6;
}
.card_area-2 {
  grid-row: 3;
  grid-column: 6;
}

.player-3 {
  grid-row: 3;
  grid-column: 1;
}
.card_area-3 {
  grid-row: 4;
  grid-column: 1;
}

.player-4 {
  grid-row: 6;
  grid-column: 2;
}
.card_area-4 {
  grid-row: 6;
  grid-column: 3/6;
}
.card_area {
  background-color: rgb(232, 127, 127);
}

.card:hover {
  background-color: aqua;
}

.card-odd {
  background-color: gray;
}
.card-even {
  background-color: darkkhaki;
}

.card_area-4 {
  width: 100%;
}
.card:last-child {
  flex: 0 0 auto;
}

.card {
  flex: 1;

  aspect-ratio: 2/3;
  text-align: center;

  height: 110%;
  transform: translateY(-10%);
  flex-start: start;
  min-width: 100px;
  max-width: auto;
}
.card {
  display: flex;
  justify-content: center;
  align-items: center;
} 

.card_area-4 {
  
  display: flex;
  justify-content: center;
}
let cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
const card_els = Array.from(document.getElementsByClassName("card"));
console.log(cards)
card_els.forEach((card) => {
  card.addEventListener("click", (e) => {
    e.target.remove();
    console.log("haha")
  });
});
html css flexbox css-grid
1个回答
0
投票

通过为每张卡片使用额外的包装元素,您可以获得一个非常好的 CSS 解决方案。每张卡的外部元素都通过 Flexbox 进行定位和收缩;内部元素绝对定位并具有固定宽度,从而导致重叠(这就是您想要的)。

卡片大约适合容器,但不完全适合。我向容器添加了 50 像素的右填充(一张卡片宽度的三分之二),以便卡片适合大多数情况。要获得精确的配合,我们需要根据容器中的卡片数量计算正确的填充; 这在 CSS 中是不可能的。但近似拟合可能足以满足您的目的。

enter image description here

body {
  background: #888;
}

.cards {
  display: flex;
  margin-bottom: 1em;
  border: 3px dashed white;
  width: 250px;
  color: white;
  justify-content: start;
  padding-right: 50px;
}

.cards > div {
  height: 100px;
  flex-basis: 75px;
  position: relative;
  border: 3px solid black;
  box-sizing: border-box;
}

.cards > div > div {
  position: absolute;
  top: 0;
  left: 0;
  width: 75px;
  height: 100%;
  transform: rotate(-5deg);
  padding: 5px;
  box-sizing: border-box;
}

.cards > div:nth-child(odd) > div {
  background: #ff0000df;
}

.cards > div:nth-child(even) > div {
  background: #0000ffdf;
}

.wider {
  width: 350px;
}
<!-- 5 cards -->
<div class="cards">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<!-- 5 cards -->
<div class="cards">
  <div><div>1</div></div>
  <div><div>2</div></div>
  <div><div>3</div></div>
  <div><div>4</div></div>
  <div><div>5</div></div>
</div>

<!-- 8 cards -->
<div class="cards">
  <div><div>1</div></div>
  <div><div>2</div></div>
  <div><div>3</div></div>
  <div><div>4</div></div>
  <div><div>5</div></div>
  <div><div>6</div></div>
  <div><div>7</div></div>
  <div><div>8</div></div>
</div>

<!-- 11 cards -->
<div class="cards">
  <div><div>1</div></div>
  <div><div>2</div></div>
  <div><div>3</div></div>
  <div><div>4</div></div>
  <div><div>5</div></div>
  <div><div>6</div></div>
  <div><div>7</div></div>
  <div><div>8</div></div>
  <div><div>9</div></div>
  <div><div>10</div></div>
  <div><div>11</div></div>
</div>

<!-- 8 cards in a wider container -->
<div class="cards wider">
  <div><div>1</div></div>
  <div><div>2</div></div>
  <div><div>3</div></div>
  <div><div>4</div></div>
  <div><div>5</div></div>
  <div><div>6</div></div>
  <div><div>7</div></div>
  <div><div>8</div></div>
</div>

<!-- 4 cards in a wider container -->
<div class="cards wider">
  <div><div>1</div></div>
  <div><div>2</div></div>
  <div><div>3</div></div>
  <div><div>4</div></div>
</div>

为了获得完全准确的结果,您可以使用 Javascript 来确定每个容器中有多少张卡片,并计算每张卡片的精确偏移量。

enter image description here

document.querySelectorAll('.contained').forEach(c => {
  const cards = Array.from(c.children)
  // calculate the total width of the cards, assuming they are all same width
  const widthOfCards = cards[0].clientWidth * cards.length
  // calculate the offset as the difference between the total width of the cards and the width of the container, divided by one less than the number of cards
  const offset = (widthOfCards - c.clientWidth) / (cards.length - 1)
  c.insertAdjacentHTML('afterbegin', `<span>container: ${c.clientWidth}<br>cards: ${widthOfCards}<br>offset: ${offset > 0 ? Math.round(offset * 1000) / 1000 : 'none'}</span>`)
  // if the container is wider than the cards, no adjustment is necessary
  if (offset <= 0) return
  for (i = 0; i < cards.length; i++) {
    const x = cards[i]
    x.style.left = `${-1 * i * offset}px`
  }
})
body {
  background: #888;
}

.cards {
  display: flex;
  margin-bottom: 1em;
  border: 3px dashed white;
  width: 250px;
  color: white;
  position: relative;
}

.cards > div {
  width: 75px;
  height: 100px;
  transform: rotate(-5deg);
  flex-shrink: 0;
  padding: 5px;
  box-sizing: border-box;
}

.cards > div:nth-child(odd) {
  background: #ff0000df;  
}

.cards > div:nth-child(even) {
  background: #0000ffdf;  
}

.contained > div {
  position: relative;
}

.wider {
  width: 350px;
}

.cards > span {
  font-size: 0.8em;
  position: absolute;
  left: 1em;
  bottom: 1em;
  z-index: 1;
}
<!-- normal scenario, cards overflow container -->
<div class="cards">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>

<!-- 5 cards contained -->
<div class="cards contained">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>

<!-- 8 cards contained -->
<div class="cards contained">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
</div>

<!-- 8 cards contained in a wider container -->
<div class="cards contained wider">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
</div>

<!-- 4 cards contained in a wider container -->
<div class="cards contained wider">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.