Html 使弹性项目重叠

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43919067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:38:56  来源:igfitidea点击:

Make flex items overlap

htmlcssflexboxcss-grid

提问by Michael Arrison

I'd like to show a horizontal series of a unknown number of playing cards. To do this, they will have to overlap if there are too many. I'm having trouble convincing a flex box to overlap the cards without shrinking them. The example below shrinks the cards. I tried flex-shrink: 0, but then max-widthwasn't respected.

我想展示一组未知数量的扑克牌。为此,如果数量太多,它们将不得不重叠。我很难说服一个 flex box 在不缩小它们的情况下重叠卡片。下面的例子缩小了卡片。我试过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>

回答by FTWinston

Here's how I'd do this using flexbox.

下面是我如何使用 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>

Note that technically speaking, the cards aren't overlapping, they're just being clipped. But they looklike they're overlapping. The trick is to wrap each card in another element with overflow: hidden.

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

The wrapping elements are shrunk to fit the available space, and as much of the cards as is possible is displayed in that space.

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

I include the :hover rule just to show how you could fully display a card from the middle of the "stack", but in a real project I'd probably do this for selected cards instead of hovered ones.

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

回答by Michael Coker

You can make elements in a flex layout overlap using transform: translateX(-10px), but that won't address the layout you're trying to get. I don't think you can do that in flexbox. But you could easily do this with JS.

您可以使用 使 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>

回答by Max Garber

You can do it using only css by using grid instead of flex.

您可以通过使用 grid 而不是 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>

回答by Michael Benjamin

A flex container is designed to align items along the X and Y axes.

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

You're asking about alignment along the Z axis.

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

Flexbox is not designed for z-axis alignment (overlapping).

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

Any overlapping would have to come from negative margins, absolute positioning, CSS Grid Layout, JavaScript or something else. The z-indexproperty may also need to play a role.

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

Here's a basic example using CSS Grid:

这是一个使用 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>

Cards are made to overlap using line-based placement. In this case, the grid-columnproperty is used to make column tracks overlap.

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

Still, some scripting would be necessary if the number of cards varies dynamically, as the overlap amount would need to vary in order for all cards to fit precisely in the fixed-width container.

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

回答by Nate Whittaker

I came up with a generic, CSS-based solution. However, with a few caveats:

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

  1. The last card overflows the .cardscontainer.
  2. A child element of .cardis needed to produce the overlapping effect.
  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>

回答by Sam

You can do it using margin property and apply to the items you desire by manual or JS.

您可以使用 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>

回答by Cuse70

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>

回答by 1P0

This overlaps a right child over a left child, excluding the first.

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

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

Your container should also have flex and flex-direction row.

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