複数列形式でユーザーに表示されるメニューシステムを構築しています。 CSS3のcolumn-countプロパティを使用すると、そこまでの道の90%を取得できますが、Chromeでの配置に問題があります。
メニューは比較的シンプルです:
私が抱えている配置の問題は、一番上の境界線と各リスト項目の背景色で最も顕著です。 Firefoxでは、リストアイテムは常に各列にきれいに配置され、前/次の列に流れ込むことはありません。 Chromeでの配置は、存在するリストアイテムの数とパディング/マージンのプロパティによって異なります。
ここに簡単なテストケースのコードを投稿しました: http://Pastebin.com/Ede3JwdG
問題はすぐに明らかになるはずです。Chromeでは、2番目の列の最初のリスト項目が最初の列に戻ります。リストアイテムを削除する(クリックする)と、配置がさらに崩れることがわかります。
リストアイテムのパディング/マージンを調整してみました:Chromeは、複数列レイアウトでコンテンツをフローするためのアルゴリズムに欠陥があるようです。
列カウントを完全に捨てていない主な理由は(手動生成/ Columnizerなどを支持)、メニューシステムには複数のサブメニューにまたがるドラッグアンドドロップ機能が含まれており、メニューデータがレイアウトされているためです。凝集したリストベースの階層がきれいなコードを作成します。
Chromeでアライメントの問題を修正する方法はありますか、それともcolumn-countをあきらめる必要がありますか?
追加:
列内の各アイテムを「インラインブロック」として表示する必要があります。これにより、jQueryを使用せずに問題を解決できます。
さらに、各要素にwidth: 100%
を指定して、行の全幅を使用できるようにすることができます。
これが実際の例です:
$(document).ready(function() {
for( var i = 0; i < 24; i++ ) {
$("ul.newslist").append("<li><a href='#'>Item</a></li>");
}
$("ul.newslist > li").click(function() {
$(this).remove();
})
});
ul.newslist {
columns: 5;
background-color: #ccc;
padding: 16px 0;
list-style: none;
}
ul.newslist > li {
display: inline-block;
width: 100%;
border-top: 1px solid #000;
}
ul.newslist > li > a {
display: block;
padding: 4px;
background-color: #f6b;
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="newslist"></ul>
margin-*
プロパティは、マルチカラム化されたコンテナ内の要素へ。
.content {
column-width: 15em; /* or could be column-count, however you want to set up multi columns */
}
.content > section {
-webkit-margin-before: 0;
-webkit-margin-after: 0;
}
私も遊んでみましたが、オンラインで見たいくつかのソースは、Webkitの既知の問題のようです。良い内訳はここにあります: http://zomigi.com/blog/deal-breaker-problems-with-css3-multi-columns/
いつか、CSS 3!
http://welcome.totheinter.net/columnizer-jquery-plugin/ のようなjQueryプラグインを試してみてください。
垂直マージンの漏れについて。マージンを擬似要素に置き換えることができます。次に、その高さを希望のマージン値に設定します。また、疑似要素を含む要素に-webkit-column-break-inside: avoid;
を設定して、別の列に移動しないようにする必要があります。 css-hack(非推奨)または js-detection (最良の方法)の助けを借りて、Webkitに対してのみこれを行ってください。 CSSは次のとおりです。
.element {
-webkit-column-break-inside: avoid;
}
.element:after {
content: '';
display: block;
height: 20px;
}
複数列のリストで垂直方向の配置に問題がありました。問題は、リストliで下のパディングを使用していることであることが判明しました。代わりに、下の余白を使用するようにliスタイルを変更し、列を再び上に揃えました。
これを解決するには、子要素の垂直方向の余白を削除してから、子の行の高さを増やして目的の間隔を複製します。
また、子の余白を削除し、それを孫のパディングに変換することで、この垂直方向の配置の問題を修正できることに気付きました。
望ましい結果は、3つの列に表示するリンクの大きなリストを取得することでした。単にcolumn-break-inside:avoid;
を使用するだけではWebkitで機能しませんでした。
HTML
<div class="links">
<ol>
<li><a>link</a></li> <!-- x 50 -->
</ol>
</div>
css:
.links ol {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
}
.links li {
display: block;
border: 1px solid $background-colour; //to appear invisible
-moz-column-break-inside:avoid;
-webkit-column-break-inside:avoid;
column-break-inside:avoid;
}
.links a {
display: block;
margin-bottom: 10px;
}
解決策(必要な場合は気になる)
リストアイテムの周囲に1pxの境界線を追加しました。これには、その子のマージンが含まれているように見え、各列が上に揃えられました。
編集:これは、グローバルborder-box
を使用している場合にのみ必要と思われます
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
私はこれにも苦労しています。多くのデータとタイトルにパディング/マージンがあるレポートシステムの場合、画面を広げるためにいくつかの列にフローする必要があります。
:first-child
擬似クラスを使用して、最初のタイトル要素のパディングである最初の大きな問題を回避しました(これは、ここに示されていないワイドスクリーンの@mediaルールに含まれています)。
列の定義:
.dimSlider .multicol {
-moz-columns: 4;
-webkit-columns: 4;
columns: 4;
}
.multicol
のときに上部のパディングをキャンセルする
.dimSlider .multicol h3 {
padding-top: 0;
}
最初の要素のパディングとマージンをキャンセルする(color: blue;
は、ルールがキャッチされるかどうかを確認するためです):
.dimSlider .multicol .criteria:first-child h3 {
padding: 0 2%;
margin: 0;
color: blue;
}
これまでのところ、これは私のFirefoxではずっときれいに見えます。もっとやる必要があるかどうかを確認しますが、現在Firefoxではテキストが一番上に揃えられているように見えます。これが最も重要なことです。
編集:問題は実際にWebkitベースのブラウザではかなり悪いようです。それを完全に解決するために、タイトルの先頭ではなくdivの末尾にパディング/マージンを追加できるように、すべてのタイトル付きセクションの周りに<div></div>
が含まれるようにテンプレートを変更しました。現在、Webkitブラウザーでも問題なく見えます。
ところで、複数列でパーセンテージ測定を使用すると、パーセンテージは親要素のグローバル幅ではなく列の幅に対して計算されるように見えるため、非常に注意が必要です。これを変更するには、列の親要素にパディングを追加しました。
しかし最大の難点は、Firefoxが列スパンまたはブレークインサイドプロパティをサポートしていないことです。そのため、コンテンツが非常に少ない場合でも、それぞれ1行または2行のように列全体に広がります。繰り返しますが、Smartyは救助に乗り出します。
{if $element|@count <= 10}
<div class="nocol">
{/if}
これまでのところ、それは私のために今働いています...