31

我想展示一系列未知数量的扑克牌。为此,如果太多,它们将不得不重叠。我无法说服弹性盒在不缩小卡片的情况下重叠卡片。下面的例子缩小了卡片。我试过了flex-shrink: 0,但max-width没有得到尊重。

.cards {
  display: flex;
  max-width: 300px;
}

.card {
  width: 50px;
  height: 90px;
  border: 1px solid black;
  border-radius: 3px;
  background-color: rgba(255, 0, 0, 0.4);
}
<div class='cards'>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
</div>

4

9 回答 9

38

下面是我如何使用 flexbox 来做到这一点。

.cards {
  display: flex;
  align-content: center;
  max-width: 35em;
}

.cardWrapper {
  overflow: hidden;
}

.cardWrapper:last-child, .cardWrapper:hover {
    overflow: visible;
}

.card {
    width: 10em;
    min-width: 10em;
    height: 6em;
    border-radius: 0.5em;
    border: solid #666 1px;
    background-color: #ccc;
    padding: 0.25em;
  
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
<div class="cards">
  <div class="cardWrapper">
    <div class="card">card 1 blah blah blah</div>
  </div>
  <div class="cardWrapper">
    <div class="card">card 2 blah blah blah</div>
  </div>
  <div class="cardWrapper">
    <div class="card">card 3 blah blah blah</div>
  </div>
  <div class="cardWrapper">
    <div class="card">card 4 blah blah blah</div>
  </div>
  <div class="cardWrapper">
    <div class="card">card 5 blah blah blah</div>
  </div>
</div>

请注意,从技术上讲,卡片没有重叠,它们只是被剪裁了。但它们看起来像是重叠的。诀窍是用溢出将每张卡片包装在另一个元素中:隐藏。

包装元素被缩小以适应可用空间,并且尽可能多的卡片显示在该空间中。

我包含 :hover 规则只是为了展示如何从“堆栈”中间完全显示一张卡片,但在实际项目中,我可能会为选定的卡片而不是悬停的卡片执行此操作。

于 2018-04-30T23:44:40.350 回答
26

您可以使用 使 flex 布局中的元素重叠transform: translateX(-10px),但这不会解决您尝试获取的布局。我认为你不能在 flexbox 中做到这一点。但是你可以很容易地用 JS 做到这一点。

var parentEl = document.getElementById("cards");

function sortCards() {
  var cards = document.getElementsByClassName("card"),
      cw = parentEl.clientWidth,
      sw = parentEl.scrollWidth,
      diff = sw - cw,
      offset = diff / (cards.length - 1);

  for (var i = 1; i < cards.length; i++) {
    cards[i].style.transform = "translateX(-" + offset * i + "px)";
  }
}

sortCards();

var b = document.getElementById("button");
b.addEventListener("click", function() {
  var div = document.createElement("div");
  div.classList.add("card");
  parentEl.appendChild(div);
  sortCards();
});
.cards {
  display: flex;
  max-width: 300px;
}

.card {
  height: 90px;
  border: 1px solid black;
  border-radius: 3px;
  background-color: rgba(255, 0, 0, 0.4);
  flex: 0 0 50px;
  background: red;
  transition: transform .25s;
}
<div><button id="button">addcards</button></div>
<div class='cards' id="cards">
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
</div>

于 2017-05-11T15:39:19.770 回答
20

您可以使用网格而不是 flex 仅使用 css 来完成它。

.hand{
  width: 50%;
  margin-left: auto;
  margin-right: auto;
  justify-content: center;
  display: grid;
  grid-template-columns: repeat(auto-fit,  minmax(10px, max-content)) ;
}
.card{
  width: 3em;
  height: 2.4em;
  padding: 3px;
  margin: 2px;
  background-color: lightgreen;
  border-style: solid;
  transform: rotate(3deg);  /*makes it easier to see the overlap*/
}
<div class="hand"> 
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
  <div class="card"> card </div>
</div>

于 2018-10-29T03:23:37.557 回答
9

flex 容器旨在沿 X 和 Y 轴对齐项目。

您正在询问沿 Z 轴对齐的问题。

Flexbox 不是为 z 轴对齐(重叠)而设计的。

任何重叠都必须来自负边距、绝对定位、CSS 网格布局、JavaScript 或其他东西。该z-index属性可能也需要发挥作用。

这是一个使用 CSS Grid 的基本示例:

.cards {
  display: grid;
  grid-template-columns: repeat(30, 10px);
  grid-template-rows: 90px;
  max-width: 300px;
}

.card {
  grid-row-start: 1;
  background-color: lightgreen; 
  border: 1px solid black;
}

.card:nth-child(1) { grid-column: 1 / 6; }
.card:nth-child(2) { grid-column: 4 / 9; }
.card:nth-child(3) { grid-column: 7 / 12; }
.card:nth-child(4) { grid-column: 10 / 15; }
.card:nth-child(5) { grid-column: 13 / 18; }
.card:nth-child(6) { grid-column: 16 / 21; }
.card:nth-child(7) { grid-column: 19 / 24; }
.card:nth-child(8) { grid-column: 22 / 27; }
.card:nth-child(9) { grid-column: 25 / 30; }
<div class='cards'>
  <div class='card'>1</div>
  <div class='card'>2</div>
  <div class='card'>3</div>
  <div class='card'>4</div>
  <div class='card'>5</div>
  <div class='card'>6</div>
  <div class='card'>7</div>
  <div class='card'>8</div>
  <div class='card'>9</div>
</div>

使用基于行的放置使卡片重叠。在这种情况下,该grid-column属性用于使列轨道重叠。

尽管如此,如果卡片的数量动态变化,则需要编写一些脚本,因为重叠量需要变化才能使所有卡片精确地适合固定宽度的容器。

于 2017-05-11T15:20:21.543 回答
5

聚会迟到了,但这是我对类似情况的解决方法:

有一个建议提到负边距,确实,当没有进行其他调整时,卡片将始终与以下内容重叠:(margin-left: -30px;选择的重叠宽度有些随意。您可以选择卡片的最大宽度。)

我在这里所做的更改是添加justify-content: space-evenly;到混合中。这会将卡片分散在 flex 容器中的可用空间上,并且只有在过于拥挤时才会让卡片重叠。如果您对卡片在不重叠时像那样散开没有问题,这可能是一个解决方案。

注意。由于负边距将卡片向左拉,我还以padding-left与负边距相同的宽度将卡片插入 flex 容器中。

NB2。我更改了原始示例的不透明度,否则卡片会变得透明。

    .cards {
      display: flex;
      max-width: 300px;
      padding-left: 30px;
      justify-content: space-evenly;
    }

    .card {
      width: 50px;
      height: 90px;
      border: 1px solid black;
      border-radius: 8px;
      background-color: rgb(255, 100, 100);
      margin-left: -30px;
    }
    <div class='cards'>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
      <div class='card'></div>
    </div>

于 2021-01-03T21:40:10.110 回答
2

我想出了一个通用的、基于 CSS 的解决方案。但是,有一些警告:

  1. 最后一张卡片溢出.cards容器。
  2. 需要一个子元素.card来产生重叠效果。

.cards {
  display: flex;
  max-width: 300px;
}

.card {
  position: relative;
  flex-basis: 50px;
  height: 90px;
}

.card::before {
  content: '';
  display: block;
  position: absolute;
  width: 50px;
  height: 100%;
  border: 1px solid black;
  border-radius: 3px;
  background-color: rgba(255, 0, 0, 0.4);
  box-sizing: border-box;
}
<div class='cards'>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
</div>

于 2018-03-28T13:52:40.407 回答
0

您可以使用 margin 属性并通过手动或 JS 应用到您想要的项目。

.cards {
  display: flex;
  max-width: 300px;
}

.overl {
margin-left:-10px;
}

.card {
  width: 50px;
  height: 90px;
  border: 1px solid black;
  border-radius: 3px;
  background-color: rgba(255, 0, 0, 0.4);
}
<div class='cards'>
  <div class='card'></div>
  <div class='card overl'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
  <div class='card'></div>
</div>

于 2017-05-11T15:42:52.603 回答
0

div.card-area
{
    height: 16vh; /* whatever */
    display: flex;
}
div.card-area > div
{
    flex: 1 0 0;
    overflow-x: hidden;
}
div.card-area > div:last-of-type
{
    flex: 0 0 auto;
}
div.card-area img
{
    height: 100%;
}
<div class="card-area N">
    <div><img src="img/cards/AH.png"></div>
    <div><img src="img/cards/KH.png"></div>
    <div><img src="img/cards/QH.png"></div>
    <div><img src="img/cards/JH.png"></div>
    <div><img src="img/cards/10H.png"></div>
    <div><img src="img/cards/9H.png"></div>
    <div><img src="img/cards/8H.png"></div>
    <div><img src="img/cards/7H.png"></div>
    <div><img src="img/cards/6H.png"></div>
    <div><img src="img/cards/5H.png"></div>
    <div><img src="img/cards/4H.png"></div>
    <div><img src="img/cards/3H.png"></div>
    <div><img src="img/cards/2H.png"></div>
</div>

于 2019-01-17T23:01:01.310 回答
0

这将右孩子重叠在左孩子之上,不包括第一个。

.overlapped {
  > * + * {
    postion: absolute;
    margin-left: -7px;
  }
}

你的容器也应该有 flex 和 flex-direction 行。

于 2019-12-24T19:37:37.217 回答