フレックスボックスである<ul>
とフレックスアイテムである<li>
sの束があります。
<li>
に柔軟な幅を持たせようとしていますが、これはmin-widthとmax-widthを使用して2つのサイズの間に留まります。それらが同じライン上にある限り、うまく機能します。ただし、折り返すと、新しい行の<li>
sはできるだけ多くのスペースを使用します。つまり、最初の行では小さく、2、3の行がある場合は2番目の行で大きくなります。
flexbox柔軟な幅を維持しながら、折り返し後のアイテムの幅を維持するように指示する方法はありますか?
ラッピングデモ:
私のコードは次のようになります。
<ul>
<li>
<figure>
<img src="http://placekitten.com/g/250/250">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/100/100">
</figure>
</li>
<!-- ... -->
</ul>
そしてCSS:
ul {
display: flex;
flex-wrap: wrap;
}
li {
min-width: 40px;
max-width: 100px;
flex: 1 0 0;
}
追加のコメント付きのコードペンのライブ例、折り返されるようにウィンドウのサイズを変更します。
これはsolution自体とは呼ばないものですが、メディアクエリのみを使用する比較的エレガントな回避策であり、さらに重要なのはJavaScriptを使用しないことです!
@mixin flex-wrap-fix($flex-basis, $max-viewport-width: 2000px) {
flex-grow: 1;
flex-basis: $flex-basis;
max-width: 100%;
$multiplier: 1;
$current-width: 0px;
@while $current-width < $max-viewport-width {
$current-width: $current-width + $flex-basis;
$multiplier: $multiplier + 1;
@media(min-width: $flex-basis * $multiplier) {
max-width: percentage(1/$multiplier);
}
}
}
フレックスアイテムにミックスインを適用します。
.flex-item {
@include flex-wrap-fix(100px)
}
OPの例の場合のように、フレックスコンテナの幅がビューポートのサイズと一致している限り、上記のmixinはトリックを行う必要があります。メディアクエリは、ビューポートの幅に常に基づいているため、そうしないと役に立ちません。ただし、ブラウザメディアクエリの代わりに css-element-queries
ライブラリとその要素クエリを使用できます。 flexcontainerに適用できるmixinは次のとおりです。
@mixin flex-container-wrap-items($flex-basis, $max-expected-width: 2000px) {
display: flex;
flex-wrap: wrap;
> * {
max-width: 100%;
flex-grow: 1;
flex-basis: $flex-basis;
}
$multiplier: 1;
$current-width: 0px;
@while $current-width < $max-expected-width {
$current-width: $current-width + $flex-basis;
$multiplier: $multiplier + 1;
&[min-width~="#{$flex-basis * $multiplier}"] > * {
max-width: percentage(1/$multiplier);
}
}
}
OPの例に従って、各アイテムに100px
の最大幅を持たせたいので、ブラウザの幅が100px
の場合、行ごとに1つのアイテムを収めることができることを知っています。 :
| Viewport Width | Max Item Count Per Row | Item Width (min-max) |
|----------------|------------------------|----------------------|
| <= 100 | 1 | 0px - 100px |
| <= 200 | 2 | 50px - 100px |
| <= 300 | 3 | 50px - 100px |
| <= 400 | 4 | 50px - 100px |
| <= 500 | 5 | 50px - 100px |
| <= 600 | 6 | 50px - 100px |
メディアクエリを記述して、次のルールを作成できます。
| Viewport Width | Max Item Count Per Row | Item Max Width | Calculation |
|------------------------------------------------------------------------|
| <= 100px | 1 | 100% | (100/1) |
| <= 200px | 2 | 50% | (100/2) |
| <= 300px | 3 | 33.33333% | (100/3) |
| <= 400px | 4 | 25% | (100/4) |
| <= 500px | 5 | 20% | (100/5) |
| <= 600px | 6 | 16.66666% | (100/6) |
このような:
li {
flex: 1 0 0
max-width: 100%;
}
@media(min-width: 200px) {
li { max-width: 50%; }
}
@media(min-width: 300px) {
li { max-width: 33.33333%; }
}
@media(min-width: 400px) {
li { max-width: 25%; }
}
@media(min-width: 500px) {
li { max-width: 20%; }
}
@media(min-width: 600px) {
li { max-width: 16.66666%; }
}
もちろん、それは反復的ですが、ほとんどの場合、何らかのプリプロセッサを使用しているので、反復性の面倒を見ることができます。それがまさに上記のTL; DRセクションのmixinが行うことです。
あとは、100px
をflex-basis
として指定し、オプションでブラウザーウィンドウの最大幅(デフォルトは2000px
)を指定するだけです次のメディアクエリを作成します。
@include flex-wrap-fix(100px)
最後に、上記のmixinを使用して、目的の出力を持つ元のCodePenサンプルの分岐バージョン:
私はあなたのコードペンで実験しており、flex: 0 1 10%
もちろん、フレックスベーシスは任意に設定できますが、ポイントを証明したかったのです。フレックスベーシスを設定して縮小できるようにすると、この場合はずっとうまく動作します。
これがあなたが必要とするものだと思います。プレビューは次のとおりです。 http://codepen.io/anon/pen/bwqNEZ
乾杯
私はそれを得たと思う...しかしそれはハッキーだ。その結果、複数の行であっても、それぞれ幅100ピクセルから40ピクセルまでスケーリングする14個の画像が得られます。
<li>
sの複製セットを追加し、フレックス<ul>
に追加しました。次に、2番目のセットが非表示になりました。
li:nth-of-type(n + 15) {
visibility: hidden;
}
均一な柔軟性を維持するために、各<li>
に次の変更を加えます。
li {
min-width: 40px;
max-width: 10%;
flex: 1 0 100px;
}
確認してくださいCodePen
および/またはSnippetFull Pageモードで。
ul {
display: flex;
flex-wrap: wrap;
max-height: 258px;
}
li {
min-width: 40px;
max-width: 10%;
flex: 1 0 100px;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
ul {
background-color: tomato;
}
li {
margin: 0.5em;
background-color: darkgreen;
}
li img {
width: 100%;
opacity: 0.5;
}
li figure,
li img {
margin: 0;
padding: 0;
}
li:nth-of-type(n + 15) {
visibility: hidden;
}
<ul>
<li>
<figure>
<img src="http://placekitten.com/g/250/250">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/101/101">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/201/201">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/150/150">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/80/80">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/111/111">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/40/40">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/110/110">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/75/75">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/89/89">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/150/150">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/32/32">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/61/61">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/320/320">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/250/250">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/101/101">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/201/201">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/150/150">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/80/80">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/111/111">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/40/40">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/110/110">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/75/75">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/89/89">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/150/150">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/32/32">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/61/61">
</figure>
</li>
<li>
<figure>
<img src="http://placekitten.com/g/320/320">
</figure>
</li>
</ul>
min-width
およびmax-width
パーセンテージとして、すべての画像が次の行に分割されたときに同じ幅を維持できるようにしました。それは理想的ではありませんが、あなたが望んでいるものに近いですか?
li {
min-width: 15%;
max-width: 15%;
}
うまく機能しませんが、列を使用してこの方向で何かを達成できます。
column-gap: 10px;
column-width: 150px;
スタイラスでは、このミックスインを使用できます: https://codepen.io/anon/pen/Epjwjq
flex-wrap-fix($basis, $max) {
flex-grow: 1
flex-basis: $basis
max-width: 100%
$multiplier = ceil($max / $basis)
for i in (1..$multiplier) {
@media(min-width: ($basis * i)) {
max-width: percentage(1/i)
}
}
}
私のソリューションは、JQueryに依存しているため、理想的ではありません。 http://codepen.io/BigWillie/pen/WwyEXX
CSS
ul {
display: flex;
flex-wrap: wrap;
}
li {
min-width: 40px;
max-width: 100px;
flex: 1;
}
JavaScript
var eqRowFlexItem = function(elem) {
var w;
var $elem = $(elem);
// Clear out max-width on elements
$elem.css('max-width', '');
w = $(elem).eq(0).width();
$(elem).css('max-width', w);
}
eqRowFlexItem('li');
$(window).resize(function() {
eqRowFlexItem('li');
});
それが問題に答えているかどうかは完全にはわかりません。タイトルが私が抱えていた問題と一致していたので、私はこの投稿を見つけました。大きな画面では行ごとの要素数が多くなり、小さな画面では行ごとの要素数が少なくなるという効果がありました。どちらの場合も、これらの要素はデバイスに合わせて拡張する必要がありました。
ただし、最後の行のこれらの浮遊要素は、常に残りのスペースを埋めるように拡大します。
JQueryは最初の要素の幅を取得し、すべての要素に最大幅として適用します。 OPは、ブロックを最小幅/最大幅の範囲内に収めることを望んでいました。 CSSでmax-widthを設定するとうまくいくようです。要素のmax-widthをクリアするため、CSSのmax-widthがデフォルトになり、実際の幅が取得されます。
私は同じ問題を抱えていたので、非常に小さなJqueryを使用してボックスの幅を制御し、折り返した後でもすべて同じ幅にしました。
私のデモはCodePenにあります フレックスラップ、新しい行に等しい幅で
function resize(){
var colWidth;
var screen = $(window).width();
if(screen < 576){
colWidth = Math.round(screen / 2) - 31;
$(".item").width(colWidth);
}
if(screen > 575 && screen < 768){
colWidth = Math.round(screen / 3) - 31;
$(".item").width(colWidth);
}
else if (screen > 767 && screen < 992){
colWidth = Math.round(screen / 4) -31;
$(".item").width(colWidth);
}
else if (screen > 991 ){
colWidth = Math.round(screen / 6) -31;
$(".item").width(colWidth);
}
}
window.onresize = function() {
resize();
}
resize();
html,
body{
padding:0;
margin:0;
}
.flex-container {
padding: 0;
margin: 0;
list-style: none;
-ms-box-orient: horizontal;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -moz-flex;
display: -webkit-flex;
display: flex;
justify-content: left;
background-color:#ddd;
}
.wrap {
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
.item {
background: tomato;
height: 100px;
margin:0 15px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
margin-top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="flex-container wrap">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<li class="item">4</li>
<li class="item">5</li>
<li class="item">6</li>
<li class="item">7</li>
<li class="item">8</li>
<li class="item">9</li>
</ul>
これは完璧ではありませんが、試してみる価値があります。 http://codepen.io/anon/pen/MKmXpV
変更点は
li
width: 7.1428%
flex: 0 0 auto
figure
margin: 0 auto
background-color: darkgreen
min-width: 40px
max-width: 100px