ネストされたflexboxレイアウトで作業していますが、次のように動作するはずです。
最も外側のレベル(ul#main
)は水平リストであり、さらに項目が追加されると右に展開する必要があります。大きくなりすぎる場合は、水平スクロールバーが必要です。
#main {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
/* ...and more... */
}
このリストの各項目(ul#main > li
)には、ヘッダー(ul#main > li > h2
)と内部リスト(ul#main > li > ul.tasks
)があります。この内部リストは垂直であり、必要に応じて列に折り返す必要があります。より多くの列に折り返す場合、より多くの項目のためのスペースを確保するために幅を広げる必要があります。この幅の増加は、外側のリストの包含アイテムにも適用する必要があります。
.tasks {
flex-direction: column;
flex-wrap: wrap;
/* ...and more... */
}
私の問題は、ウィンドウの高さが小さくなりすぎると、内部リストが折り返されないことです。 CSS-Tricks のガイドラインに細心の注意を払って試してみましたが、運はありませんでした。
この JSFiddle は、私がこれまでに持っているものを示しています。
期待される結果(欲しいもの):
実際の結果(得られるもの):
以前の結果(2015年に得たもの):
いくつかの調査の後、これはより大きな問題のように見え始めています。 すべての主要なブラウザは同じように動作します。これは、flexboxのネストされたデザインとは関係ありません。さらに単純なflexbox列レイアウトは、アイテムが折り返されるときにリストの幅を広げることを拒否します。
この 他のJSFiddle は問題を明確に示しています。 Chrome、Firefox、IE11の現在のバージョンでは、すべてのアイテムが正しくラップされます。リストの高さはrow
モードでは増加しますが、幅はcolumn
モードでは増加しません。また、column
モードの高さを変更する場合、エレメントの即時リフローはありませんが、row
モードにはあります。
ただし、 公式仕様(例5を具体的に見てください) は、私がやりたいことが可能であるべきであることを示しているようです。
誰かがこの問題の回避策を思いつくことができますか?
サイズ変更イベント中にさまざまな要素の高さと幅を更新するためにJavaScriptを使用して多くの実験を行った後、そのように解決しようとすると複雑すぎて面倒すぎるという結論に達しました。また、JavaScriptを追加するとflexboxモデルが確実に破損します。これは可能な限りクリーンに保つ必要があります。
今のところ、overflow-y: auto
ではなくflex-wrap: wrap
にフォールバックしているため、必要に応じて内部コンテナーが垂直にスクロールします。見た目はきれいではありませんが、少なくとも使いやすさを損なうことはありません。
これは、フレックスレイアウトの根本的な欠陥のようです。
列方向のフレックスコンテナは、追加の列を収容するために拡張されません。 (これはflex-direction: row
の問題ではありません。)
この質問は何度も聞かれていますが(下のリストを参照)、CSSには明確な答えはありません。
この問題はすべての主要なブラウザーで発生するため、これをバグとして特定するのは困難です。しかし、それは疑問を提起します:
すべての主要なブラウザがフレックスコンテナを取得して、列方向ではなく行方向にラップして展開することはどのように可能ですか?
そのうちの少なくとも1つが正しいと思うでしょう。その理由だけを推測できます。技術的に困難な実装であり、この反復のために棚上げされた可能性があります。
UPDATE:この問題はEdge v16で解決されたようです。
OPは問題を説明する便利なデモを作成しました。ここにコピーしています: http://jsfiddle.net/nwccdwLw/1/
Stack Overflowコミュニティのハッキングソリューション:
パーティーに遅れたが、まだこの問題にYEARS後に実行されていました。グリッドを使用してソリューションを見つけることになりました。コンテナ上で使用できます
display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(6, auto);
flexboxの問題とグリッドの修正を切り替えるCodePenの例があります。 https://codepen.io/MandeeD/pen/JVLdLd
解決策または適切な回避策がまだ提案されていないため、要求された動作を少し異なるアプローチで取得できました。レイアウトを3つの異なるdivに分割する代わりに、すべてのアイテムを1つのdivに追加し、さらにいくつかのdivを挟んで分割を作成します。
提案されたソリューションは、3つのセクションがあると仮定してハードコーディングされていますが、一般的なものに拡張することができます。主なアイデアは、このレイアウトを実現する方法を説明することです。
:before
を使用すると、各セクションのタイトルを見つけることができます。space
を使用すると、セクション間にギャップが生じますspace
はセクションの全高をカバーしないため、セクションに:after
を追加して、絶対位置と白い背景で配置します。z-index: -1
を持ちます。function calcWidth() {
var size = $(document).width();
var end = $(".end").offset().left;
var todoWidth = $(".doing-first").offset().left;
$(".bg-todo").css("width", todoWidth);
var doingWidth = $(".done-first").offset().left - todoWidth;
$(".bg-doing").css("width", doingWidth);
var doneWidth = $(".end").offset().left - $(".done-first").offset().left;
$(".bg-done").css("width", doneWidth + 20);
}
calcWidth();
$(window).resize(function() {
calcWidth();
});
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 120px;
align-content: flex-start;
padding-top: 30px;
overflow-x: auto;
overflow-y: hidden;
}
.item {
width: 200px;
background-color: #e5e5e5;
border-radius: 5px;
height: 20px;
margin: 5px;
position: relative;
box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75);
padding: 5px;
}
.space {
height: 150px;
width: 10px;
background-color: #fff;
margin: 10px;
}
.todo-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "To Do (2)";
font-weight: bold;
}
.doing-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "Doing (5)";
font-weight: bold;
}
.doing-first:after,
.done-first:after {
position: absolute;
top: -35px;
left: -25px;
width: 10px;
height: 180px;
z-index: 10;
background-color: #fff;
content: "";
}
.done-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "Done (3)";
font-weight: bold;
}
.bg-todo {
position: absolute;
background-color: #FFEFD3;
width: 100vw;
height: 150px;
top: -30px;
left: -10px;
z-index: -1;
}
.bg-doing {
position: absolute;
background-color: #EFDCFF;
width: 100vw;
height: 150px;
top: -30px;
left: -15px;
z-index: -1;
}
.bg-done {
position: absolute;
background-color: #DCFFEE;
width: 10vw;
height: 150px;
top: -30px;
left: -15px;
z-index: -1;
}
.end {
height: 150px;
width: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item todo-first">
<div class="bg-todo"></div>
Drink coffee
</div>
<div class="item">Go to work</div>
<div class="space"></div>
<div class="item doing-first">
<div class="bg-doing"></div>
1
</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="space"></div>
<div class="item done-first">
<div class="bg-done"></div>
1
</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="end"></div>
</div>
可能なJSソリューション..
var ul = $("ul.ul-to-fix");
if(ul.find("li").length>{max_possible_rows)){
if(!ul.hasClass("width-calculated")){
ul.width(ul.find("li").eq(0).width()*ul.css("columns"));
ul.addClass("width-calculated");
}
}