未知の数のトランプの横のシリーズを表示したいと思います。これを行うには、数が多すぎる場合、それらをオーバーラップさせる必要があります。フレックスボックスを縮小せずにカードを重ねるように説得するのに問題があります。次の例では、カードを縮小します。私は試した 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>
これが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>
技術的に言えば、カードは重なっておらず、切り取られているだけです。しかし、それらは重複しているようにlookです。トリックは、各カードをオーバーフローで別の要素にラップすることです:隠し。
ラッピング要素は利用可能なスペースに合わせて縮小され、可能な限り多くのカードがそのスペースに表示されます。
「スタック」の真ん中からカードを完全に表示する方法を示すためだけに:hoverルールを含めていますが、実際のプロジェクトでは、ホバーされたカードではなく、選択されたカードに対しておそらくこれを行います。
transform: translateX(-10px)
を使用してフレックスレイアウトの要素をオーバーラップさせることができますが、これは取得しようとしているレイアウトには対応していません。フレックスボックスではそれができないと思います。しかし、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 = 0; i < cards.length; i++) {
i != 0 && (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>
フレックスコンテナは、X軸とY軸に沿って項目を整列するように設計されています。
Z軸に沿った配置について質問しています。
Flexboxはz軸の位置合わせ(重複)用に設計されていません。
オーバーラップは、負のマージン、絶対位置、CSSグリッドレイアウト、JavaScriptなどから発生する必要があります。 z-index
プロパティも役割を果たす必要がある場合があります。
CSSグリッドを使用した基本的な例を次に示します。
.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
プロパティは、列トラックをオーバーラップさせるために使用されます。
それでも、カードの数が動的に変化する場合、すべてのカードが固定幅のコンテナーに正確に収まるようにオーバーラップの量を変化させる必要があるため、いくつかのスクリプトが必要になります。
私は汎用的なCSSベースのソリューションを思いつきました。ただし、いくつかの注意点があります。
.cards
コンテナーをオーバーフローします。.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>
フレックスの代わりにグリッドを使用することにより、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>
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>
これは、最初の子を除いて、左の子の上に右の子を重ねます。
.overlapped {
> * + * {
postion: absolute;
margin-left: -7px;
}
}
コンテナにはflexとflex-direction行も必要です。