48

更新と要約

賞金が付いているので、この質問をより明確にする義務があると感じています。

(また、 CSS3ユニット値がサポートされている場合、これは子供の遊びになると確信しています。たとえば、その時点でインターネットを閲覧していると思いますがcalc()width: calc(25% - 5px)

私は、設計要件を共有するいくつかのプロジェクトのCSSフレームワークに取り組んでいます。つまり、流動的な12列のレイアウトです。パーセント幅のフロート.column要素を使用すると(100% / 12) x col_size、これはかなり簡単です。ただし、この問題には、列間に固定マージン(または任意の形式の間隔)が追加されることがあります。

私の最初の試みでは、説明したように流体カラムを使用し、.panelそれぞれに子をネストしました。HTML / CSSスニペットは次のとおりです(簡潔にするために縮小):

.column{
    float: left;
    display: inline-block;
}

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */

.panel{
    width: 100%;
    padding: 5px;
    box-sizing: border-box; /* so padding doesn't increase width */
}
<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-03">
    <div class="panel">Width-03</div>
</div>
<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-05">
    <div class="panel">Width-05</div>
</div>

このスニペットは、下の画像のようなレイアウトを生成しますが、すべての.panel要素5pxのすべての側面にパディングがあります。外側の列のコンテンツエッジをビューポート(またはその場合は親コンテナのエッジと同じ高さにしようとしています。もう1つのアプローチは、.panelクラスを完全に削除し、列を使用することです。

.column{
    float: left;
    display: inline-block;
    padding-left: 10px;
    box-sizing: border-box;
}

.column:first-child{ padding-left: 0px; }

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */
<div class="column width-02">Width-02</div>
<div class="column width-03">Width-03</div>
<div class="column width-02">Width-02</div>
<div class="column width-05">Width-05</div>

繰り返しになりますが、これはうまく機能し、下の画像の結果にさらに近い結果を生成しますが、(実際の)問題は、パディングが列の幅に食い込み、幅の分布を台無しにしていることです。:first-child列のコンテンツ領域の幅は、兄弟よりも10ピクセル(またはマージンサイズが何であれ)大きくなっています。

これは無害に見えるかもしれませんが、気付かないかもしれません。ただし、要素間に正確な可能な限り正確な)幅の分布を設定する必要がある場合や、作業を完全に簡単にする場合がいくつかあります。

したがって、パディング、マージン、またはそれらの組み合わせを使用するかどうか。隣接するカラムから「マージナル」(*** haha​​ *)コンテンツ領域を奪わないガタースペースの均等な分散を備えた、流体カラム、固定マージンのソリューションはありますか?**


元の質問

検索と試行の結果が単純に不足しているため、これは不可能であると結論付けました。しかし、どこかで答えが得られるのであれば、それはここにあると確信しています。

純粋なCSSを使用して、固定幅のマージンを持つ流動的な幅の列レイアウトを実現する方法はありますか?

重要な注意:この図は単なる例であり、私が達成しようとしている特定のレイアウトではありません。与えられたソリューションは、隣接する列の任意の組み合わせを許可する必要があり、合計幅分布は合計12以下です。参照用に人気のある960グリッドを検討してください。)

super_awesome_layout.css
:12列のレイアウトでは、画像の列の幅の分布はそれぞれ2、3、2、および5です。

これまでのところ、パーセンテージを使用してほぼこれを達成するグリッドに頼ってきました。問題は、マージンを達成するために、各列に次の子(私はそれらと呼びます.panel)を追加する必要があることです。

width: 100%;
box-sizing: border-box;
padding: 10px;

これもほぼ問題ありません。このアプローチの問題は、最初と最後の列に外側の「マージン」(10px)があり、各列間の「マージン」が2倍になることです(2 x 10px

確かに、新しいCSS3calc()値型を含めることで、これははるかに簡単に解決できます。次の方向への何か:

.width-12 > .panel{ width: 100%; }
.width-09 > .panel{
    width: calc(75% - 10px);
    margin: ...;
}

私はいくつかのJavascriptの修正を持っています、私は「うまくいく」いくつかのものをハックアウトしました、しかし私は探求中です。うまくいけば、最も神聖なグレイルが存在します。

残念ながら、次の解決策と@avallが提供する解決策(単純化には確かに良い選択ですが)は、私が探しているものではありません。主な問題は、マージンが列間で均等に分散されていないことです。

.panelこれが機能していることを確認できる唯一の方法は、パディングを5px次のように減らすことです。

.column:first-child > .panel {
    padding-left: 0px;
}

.column:last-child > .panel {
    padding-right: 0px;
}

/* not necessary? in any case, haven't tested */
.column:only-child > .panel {
    padding-right: 0px;
    padding-left: 0px;
}

:last-childIE8が(さらに言えば:only-child)疑似セレクターを認識できないという理由だけで、このソリューションは受け入れられません。

4

10 に答える 10

64

やっとわかった。過去 10 年間、何百時間も無駄に過ごしてきました (ただし、私は 1 年前には機能しなかった CSS に依存しています)。私は何の問題もなくそれを解決しました。そしてIE8 +で。

この船に着陸するので、2001年宇宙の旅の音楽を用意してください。

この方法の優れた点と秘訣は、インライン ブロック要素を使用してから、単語間隔を使用して、負の右マージンを使用してバランスをとることです。負の右マージンはそれ自体で要素をまとめて、100% の幅を設定し、その間に物を収めることができますが、要素をオーバーラップさせたままにします。親に負のマージンを設定すると、合計幅との相互作用に対する効果に関して、子のマージンが取り消されます (ヒットしようとしている魔法の「100% 幅」マーク)。パディングは、要素のサイズを大きくするだけです。それ以外の場合 (およびマージン) をまったく使用する能力を失い、おそらくより多くのパディングを必要とするという犠牲を払って、この問題に対する陪審の不正な解決策でボックスサイジングと共に使用されることがよくあります。ラッパー要素。

word-spacing は、2 つの要素間の水平方向の距離を追加または削除する魔法の「第 3 の方法」を提供します。ただし、それらがインライン ブロックである場合、それらは単一の「単語」としてカウントされ、その間の空白は縮小されます。単一の制御可能な「単語間隔」プロパティ。このトリック以外に、この 100% の結果を得る別の方法を知りません。

私は謙虚に、固定側溝のフレックス柱の問題に対する究極の答えを提示します。私はここに私の解決策を「オメガマヌーバ」と名付けます。任意の混合幅の列 ​​(最大 100% の合計幅を正確に追加するか、丸めのためにわずかに小さくする) を処理する機能、任意のガター サイズ、任意の定義済みの幅の列の量、自動折り返しを使用して任意の量の行を処理する機能が付属しています。 inline-block 要素を使用するため、inline-block に付属する垂直方向の配置オプションが提供されます。また、追加のマークアップは必要なく、コンテナーで 1 つのクラス宣言のみが必要です (列幅の定義はカウントされません)。コードはそれ自体を物語っていると思います。10px ガターとパーセンテージのボーナス ヘルパー クラスを使用した 2 ~ 6 列のコード実装を次に示します。

編集:興味深い難問。わずかに異なる 2 つのバージョンを取得することができました。1 つは mozilla と ie8+ 用、もう 1 つは webkit 用です。単語間隔のトリックは Webkit では機能しないようです。他のバージョンが Webkit では機能するのに ie8+/mozilla では機能しない理由がわかりません。両方を組み合わせることで、すべてを網羅することができます。この戦術を統一する方法、または問題を回避するための非常に類似した方法があると確信しています。

EDIT2:ほとんどそれを手に入れました!Magicaltext-align: justifyは WebKit を単語間隔のものでほぼ実現します。間隔はほんの少しずれているように見えます.右側のピクセルの問題と、ガターの余分なピクセルのようです. しかし、それは使用可能であり、以前に使用したものよりも列を保持することについて信頼性が高いようです. ブラウザが水平スクロールバーを取得するまで圧縮されます。

Edit3: 完璧に少し近づきました。font-size を 0 に設定すると、スペーシングがオフになっている残りの問題のほとんどが正規化されます。フォントのサイズが 0 の場合に折りたたまれる IE9 を修正する必要があります。

EDIT4:他の流動的な幅の投稿からIEへの回答を得ました:-ms-text-justify: distribute-all-lines. IE8-10 でテスト済み。

/* The Omega Maneuver */
[class*=cols] { text-align: justify; padding-left: 10px; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class*=cols]>* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 20px; }
.cols3 { word-spacing: 30px; padding-right: 30px; }
.cols4 { word-spacing: 40px; padding-right: 40px; }
.cols5 { word-spacing: 50px; padding-right: 50px; }
.cols6 { word-spacing: 60px; padding-right: 60px; }

  .cols2 > * { margin-right: -10px; }
  .cols3 > * { margin-right: -20px; }
  .cols4 > * { margin-right: -30px; }
  .cols5 > * { margin-right: -40px; }
  .cols6 > * { margin-right: -50px; }

一部のヘルパー:

.⅛, .⅛s >* { width: 12.50%; }
.⅙, .⅙s >* { width: 16.66%; }
.⅕, .⅕s >* { width: 20.00%; }
.¼, .¼s >* { width: 25.00%; }
.⅓, .⅓s >* { width: 33.00%; }
.⅜, .⅜s >* { width: 37.50%; }
.⅖, .⅖s >* { width: 40.00%; }
.½, .½s >* { width: 50.00%; }
.⅗, .⅗s >* { width: 60.00%; }
.⅝, .⅝s >* { width: 62.50%; }
.⅔, .⅔s >* { width: 66.00%; }
.¾, .¾s >* { width: 75.00%; }
.⅘, .⅘s >* { width: 80.00%; }
.⅚, .⅚s >* { width: 83.33%; }
.⅞, .⅞s >* { width: 87.50%; }
.blarg-five-twelfs { width: 41.66%; }

ここで、栄光のフィールドの中で私の最高傑作を目の当たりにすることができます: http://jsfiddle.net/xg7nB/15/

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢&lt;/div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

例として 4 つの等しい幅 (25%) 幅の列と 10px のガターを使用する、絶対最小限の実装は次のようになります。

.fourEqualCols { word-spacing: 40px; padding: 0 40px 0 10px;
                 text-align: justify; font-size: 0;
                 -ms-text-justify: distribute-all-lines; }

.fourEqualCols>* { margin-right: -30px; width: 25%;
                   display: inline-block; word-spacing: normal;
                   text-align: left; font-size: 13px; }


<div class="fourEqualCols ">
  <div>GLORIOUSLY CLEAN MARKUP</div>
  <div>I hate extra markup and excessive class props</div>
  <div>Naked code</div>
  <div>get intimate</div>
</div>

このコードは、基本的に既存のグリッド フレームワークのほとんどを置き換えますよね? ガターを任意に設定してから、幅が 100% に達する列のセットを作成できる場合、それはほとんど/すべてのグリッド フレームワークよりも厳密に優れていますね。私たちの多くのように IE7 向けに開発を行っていない場合は、box-sizing と組み合わせると、border-box はパディングとボーダーをレンダリングし、問題になりません。

編集:そうです、コンテナの側面と同じ高さになりたかったのです。これで問題ありません。具体的にサイドガターを追加する必要があったので、いくつかの値を 10 だけ変更して、パディングと出来上がりを取り除くことができます。http://jsfiddle.net/bTty3/

[class^=cols] { text-align: justify; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class^=cols] >* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 10px; }
.cols3 { word-spacing: 30px; padding-right: 20px; }
.cols4 { word-spacing: 40px; padding-right: 30px; }
.cols5 { word-spacing: 50px; padding-right: 40px; }
.cols6 { word-spacing: 60px; padding-right: 50px; }
 .cols2 >* { margin-right: 0 }
 .cols2 >* { margin-right: -10px; }
 .cols3 >* { margin-right: -20px; }
 .cols4 >* { margin-right: -30px; }
 .cols5 >* { margin-right: -40px; }
 .cols6 >* { margin-right: -50px; }

同じhtml

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢&lt;/div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

私はCSSを打ち負かしました これがあなたの証拠です

于 2011-08-31T11:29:43.160 に答える
8

この純粋なCSS2ソリューションを試してください:デモフィドル

基本CSS (化粧品なしのフィドル) :

html, body {
    padding: 0;
    margin: 0;
}
#wrap {
    padding-right: 30px;
    overflow: hidden;
}
.col {
    float: left;
    margin-left: 40px;
    margin-right: -30px;
}
.col:first-child {
    margin-left: 0;
}
.small {
    width: 16.66%;
}
.medium {
    width: 25%;
}
.large {
    width: 41.66%;
}

HTML:

<div id="wrap">
    <div class="col small"></div>
    <div class="col medium"></div>
    <div class="col small"></div>
    <div class="col large"></div>
</div>

Win7でIE7、IE8、IE9、Opera 11.50、Safari 5.0.5、FF 6.0、Chrome13.0でテスト済み。


アップデート:

ここで、これを任意の数の列で機能させる場合は、列数を指定するクラスをコンテナーに追加する必要があります。

<div class="cols-12 count-04">
    <div class="col width-02"></div>
    <div class="col width-03"></div>
    <div class="col width-02"></div>
    <div class="col width-05"></div>
</div>

さまざまな列数の数を示すこの更新されたフィドルを参照してください。

考えられるバグ:

理論的には、このソリューションは、任意のブラウザウィンドウ幅で可能な最小列幅ごとに任意の数の列で機能するはずです。しかし、すべてのブラウザが次のことを処理できないことがわかっているようです。1. 1列幅の列が多数ある、または2.ブラウザウィンドウ幅が小さい。

最小幅が1440ピクセルのすべてのブラウザは、120ピクセルの12倍(10ピクセルの余白すべてが占めるスペース)に相当し、ソリューションを適切に処理することに注意してください。また、2つ以上の列幅の列を使用する場合、ブラウザーの最小幅の要件は実際には720ピクセル(6 * 120px)に低下します。この最後のケースはより現実的に聞こえますが、それでも、このブラウザーの動作を説明することはできません。

このフィドルで示されているように、最後の列クラスを追加して問題を修正しようとしましたが、ブラウザーの幅が小さい場合の問題は解決されません。幅のパーセンテージが壊れているために発生する小さな丸め誤差は解決されますが、その問題は無視できると思います。

これについて他のCSSエキスパートから聞きたいので、賞金を追加しました。

于 2011-08-26T05:26:13.360 に答える
7

使ってみませんか

.column > .panel {
    padding: 10px 0 10px 10px;
}

.column:first-child > .panel {
    padding-left: 0px;
}

ボックス間にのみ、最後の子を使用せずに10pxのスペースを作成します。

于 2011-08-25T13:46:50.890 に答える
2

元の質問を参照して、「純粋な CSS を使用して、幅が固定された流動的な幅の列レイアウトを実現する方法はありますか?」

この種の質問で CSS が非常に困難になることは注目に値します。先週、ボーダー、マージン、パディングを含む独自の「聖杯」を作成するための「ベース テンプレート」に取り組んでいました... CSS は、この種の質問には失敗しているようです。念頭に置いている質問は非常に簡単ですが、CSS、特にクロスブラウザーで達成することは (ほぼ?) 不可能になります。

おもしろいのは、これらの質問は表を使えば簡単に解決できるということです。ほとんどの引数は弱いか、または間違っているため、「セマンティクス」や「簡単な概要」などのあいまいな引数の代わりに div を使用するよう Web 社会によって強制されている理由がわかりません。テーブルがより多くの問題を引き起こしていると言う人々は、明らかに CSS 内にある実際の問題を理解していません。

とにかく、テーブル構造が必要な場合 (列はテーブルの一部であるため)、「display:table」を使用することをお勧めします。

純粋な CSS を使用して元の質問の下にある画像を実現するには、次を使用できます。

CSS

html,body{
    margin: 0px; 
    padding: 0px; 
    height: 100%; 
    width: 100%;
    overflow: auto;
}
.table{
    background: pink;
    display: table;
    width: 100%;
    height: 100%;
}
.tableRow{
    display: table-row;         
}
.tableCell{
    display: table-cell;
    vertical-align: top;
    height: 100%;  
}
/*
    Ensures the full size of the table-cell has the behaviour of a block-element. 
    This is needed, because 'table-cell' will behave differently in different browsers.
*/
.tableCell>div{
    height: 100%;
}
/*
    Padding has to be used instead of margin in 'border-box' modus.
*/
.tableCell>div>div{
    height: 100%;
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}
/*
    The final content.
*/
.tableCell>div>div>div{
    background: lightblue;
    padding: 5px;
    height: 100%;
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}


#col1{
    width: 16.66%;          
}
#col1>div>div{
    padding-right: 10px;
}
#col2{
    width: 25%;         
}
#col2>div>div{
    padding-right: 10px;
}
#col3{      
    width: 16.66%;
}
#col3>div>div{
    padding-right: 10px;
}
#col4{
    width: 41.66%;
}

HTML

<div class="table">
    <div class="tableRow">
        <div id='col1' class="tableCell">   
            <div><div><div>16.66%</div></div></div>
        </div>
        <div id='col2' class="tableCell">
            <div><div><div>25%</div></div></div>
        </div>
        <div id='col3' class="tableCell">
            <div><div><div>16.66%</div></div></div>
        </div>
        <div id='col4' class="tableCell">
            <div><div><div>41.66%</div></div></div>
        </div>  
    </div>
</div>

余白のために追加の div を使用するのはかなりやり過ぎだと思いますが、残念ながら、CSS には 'margin-box' モデルがなく、実際には 10 億の問題を解決します。

この量のネストされたコードは、「なぜ他の手法を使用しないのか?」と思わせるかもしれません。コードが少なくなる可能性があるためです。そのような非常に具体的な願いのために。ただし、他の手法では、フローティングまたは絶対配置が必要になることがよくあります。これらのテクニックは同じことを達成することはできません: たとえば、フロートは同じ長さの列を達成できますが、境界線やマージンが必要な場合、問題が発生します。絶対配置の場合は逆です。マージンの問題は解決できますが、高さは 1 つの列にのみ基づくことができます。

私の意見では、CSS は要件を満たしていません。ポジショニングのためにテーブルを交換することが提案されていますが、何年経っても同じ結果を得ることができません。「聖杯の聖杯」を達成するには、テーブル構造が最も簡単な方法であるだけでなく、唯一の方法もあります...少なくとも、何百もの可能性を試した後に私が知る限り。

残りの質問は、div をテーブルとして使用しているのに、なぜ div を使用するのかということです。これは私自身も完全には理解できていませんが、人にはそれぞれの理由があるようです。

于 2012-05-03T13:55:51.210 に答える
2

純粋な CSS/HTML (JavaScript を使用しない、等間隔の「列」を使用した流動的なレイアウト) については、このスレッドで 30dot の回答を確認してください...

DIV が等間隔に配置された流体幅

http://jsfiddle.net/thirtydot/EDp8R/

JSFiddle の変更は、「列」をさまざまな固定幅にすることができ、依然として均等で流動的な余白を持つことを示しています。

http://jsfiddle.net/EDp8R/43/

最後に、均等で流動的なマージンを維持しながらパーセンテージを使用する別の例を示します。

http://jsfiddle.net/EDp8R/45/

これは正確な解決策ではないかもしれませんが、かなり近いものになると思います.

于 2011-08-31T15:43:12.767 に答える
1

同じ効果を得る簡単な方法は、列自体にマージン/パディングを適用するのではなく、列内のコンテンツにガターを作成させることです。これは、固定、流動、弾性などのグリッドで実行できます。

例えば:

/* Gutters */
h1, h2, h3, h4, h5, h6,
p, ul, ol, blockquote,
hr, address, pre, object, fieldset
{
    margin-right: .75rem;
    margin-left: .75rem;
    padding-right: .75rem;
    padding-left: .75rem;
}

これにより、列のサイズ変更、ネスト、背景のレゴ ピースへの適用も簡単になります。

于 2012-02-01T21:53:58.940 に答える
1

これにはOOCSSのグリッドを使用します

https://github.com/stubbornella/oocss

オンラインで適切な例がないため、最近、自分のサイトでデモをオンラインにしました:(

http://www.leipeshit.com/awesome_stuff/oocss/core/grid/grids_all.html

于 2011-09-01T04:14:31.760 に答える
0

最初の例のようにパディングを使用してから、すべての要素に box-sizing: border-box を設定しないのはなぜですか?

于 2013-03-11T09:12:27.850 に答える
0

列ごとに別のネストされた div を使用できる場合は、それぞれに必要なマージンを定義できます。左右の外縁のマージンを取り除くには、外側のコンテナに負のマージンを定義できます。

例: pureCSSを使用すると、pure-g は外側のコンテナーで、pure-u-* はネストされた div を含む列ノード (表示: inline-block) です。間隔は、pureCSS グリッド システムのこのカスタム拡張の名前で、列の余白を許可します。

.pure-g.spacing {
    margin: 0 -10px;
}

.pure-g.spacing [class *= "pure-u"] > div {
    margin: 10px;
}

ほとんどのブラウザで動作するはずです。そうでない場合は教えてください - 私はすでに使用しています。

よろしく、マックス

于 2015-01-15T15:14:02.233 に答える