web-dev-qa-db-ja.com

可変高さのCSSフローティングDiv

100px幅のdivが無限にあり、250px幅の親に収まることができます。画像に示すように、高さに関係なく、divを行に表示する必要があります。私はこれを解決しようとしましたが、divの高さはそれを台無しにしているようです。

enter image description here

本当に助かります。ありがとう:)

        <style>
            #holder{
            width:250px;
            border:1px dotted blue;
            display:inline-block;
        }
        .box{
            width:100px;
            height:150px;
            background-color:#CCC;
            float:left;
            text-align:center;
            font-size:45px;
            display:inline-block;
        }
        .one{
            background-color:#0F0;
            height:200px;
        }

        .two{
            background-color:#0FF;
        }

        .three{
            background-color:#00F;
        }

        .four{
            background-color:#FF0;
        }
    </style>

    <div id="holder">
        <div class="box one">1</div>
        <div class="box two">2</div>
        <div class="box three">3</div>
        <div class="box four">4</div>
    </div>

これが jsfiddle です

これが私がjavascriptを使用して達成したことです https://jsfiddle.net/8o0nwft9/

81
stevenmc

私の知る限り、純粋なCSSでこの問題を解決する方法はありません(すべての一般的なブラウザで動作します):

  • フロート 動作しない
  • display: inline-block機能しない
  • position: relative with position: absoluteには 手動ピクセル調整 が必要です。サーバー側の言語を使用していて、画像(または高さを予測できるもの)で作業している場合、サーバー側のコードを使用してピクセルの調整を「自動的に」処理できます。

代わりに、 jQuery Masonry を使用します。

67
thirtydot

あなたのニーズはあなたの色付きのサンプルコードのようなものであるという前提で:

_.box:nth-child(odd){
    clear:both;
}
_

3行になる場合はnth-child(3n+1)

37
FatherStorm

解決策を提供する良いものがあっても( sing Masonry )、フロートを使用してこれを達成できない理由がまだ明確ではないため、私はこの答えを提供しています。

(これは重要です-#1)。

フロートした要素は、元の位置にできる限り左または右に移動します

したがって、次のように配置します。

2 divあります

<div class="div5">div5</div>
<div class="div6">div6</div>

.div-blue{
    width:100px;
    height:100px;
    background: blue;
}

.div-red{
    width:50px;
    height:50px;
    background: red;
}

floatがなければ、それらは互いに下になります

enter image description here

float: rightdiv5にすると、div6は、div5があった行に配置されます。

/*the lines are just for illustrate*/

enter image description here

そのため、float: leftdiv6できる限り左に移動すると、「in this line」(上記の#1を参照)なので、div5が行を変更すると、 div6がそれに続きます。

ここで、方程式に他のdivを追加しましょう

<div class="div4">div4</div>
<div class="div5">div5</div>
<div class="div6">div6</div>

.div-gree{
    width:150px;
    height:150px;
    background: green;

    float:right;
}

これがあります

enter image description here

clear: rightdiv5に設定すると、強制的にdiv4の下の行になります

enter image description here

div6は、この新しい行で右または左に浮動します。

重複のために私をここに連れてきた質問を例として使用してみましょう divスタックを左から右に強制

ここでそれをテストするためのスニペット:

div{
    width:24%;
    margin-right: 1%;
    float: left;
    margin-top:5px;
    color: #fff;
    font-size: 24px;
    text-align: center;
}

.one{
    background-color:red;
    height: 50px;
}

.two{
    background-color:green;
    height:40px;
}

.three{
    background-color:orange;
    height:55px;
}

.four{
    background-color:Magenta;
    height:25px;
}

.five{
    background-color:black;
    height:55px;
}
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
<div class="five">5</div>

<div class="one">1*</div>
<div class="three">2*</div>
<div class="four">3*</div>
<div class="two">4*</div>
<div class="five">5*</div>

enter image description here

上の画像では、div.5div.3のすぐ隣にあることを確認できます。これは、その行(div.4の行ボックスで定義されている)で、div.1*div.2*などが、div.5の左にフロートしているが、彼らはその行に収まらないので、彼らは以下の行に行きます(div.5の行ボックスによって定義されます)

ここで、div.2*の高さをdiv.4*よりも低くなるように小さくすると、div.5*に渡す方法がわかります。

enter image description here

これがフロートを使用して達成できない理由を明らかにするのに役立つことを願っています。タイトルが「CSS Floating Divs At Variable Heights」であり、現時点では答えが非常に長いため、フロート(インラインブロックではない)の使用のみを明確にします。

35
Yandy_Viera

正しく指摘されているように、これはCSSだけでは不可能です...ありがたいことに、私は http://isotope.metafizzy.co/ で解決策を見つけました

問題を完全に解決するようです。

8
stevenmc

このコメントから少し助けを借りて( CSS Block float left )答えを見つけました。

作成するすべての「行」に、クラス名leftを追加します。
他のすべての「行」に、クラス名rightを追加します。

次に、これらのクラス名ごとに左にフロートし、右にフロートします!

唯一の問題は、「右」の行でコンテンツの順序が逆になることですが、PHPを使用して解決できます。

助けてくれてありがとう!

#holder{
  width:200px;
  border:1px dotted blue;
  display:inline-block;
}
.box{
  width:100px;
  height:150px;
  background-color:#CCC;
  float:left;
  text-align:center;
  font-size:45px;
}
.one{
  background-color:#0F0;
  height:200px;
}

.two{
  background-color:#0FF;
}

.three{
  background-color:#00F;
  float:right;
}

.four{
  background-color:#FF0;
  float:right;
}
.left{float:left;}
.right{float:right;}
<div id="holder">
  <div class="box one left">1</div>
  <div class="box two left">2</div>
  <div class="box four right">4</div>
  <div class="box three right">3</div>
</div>
</body>
3
stevenmc

Thirtydotのおかげで、以前の答えでは問題が適切に解決されなかったことに気付きました。 CSSのみのソリューションとしてJQueryを利用する2番目の試みは次のとおりです。

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
        <script type="text/javascript" language="javascript">
            $(document).ready(function() {
                var numberOfColumns = 3;
                var numberOfColumnsPlusOne = numberOfColumns+1;
                var marginBottom = 10;  //Top and bottom margins added
                var kids = $('#holder:first-child').children();
                var add;
                $.each(kids, function(key, value) {
                    add = numberOfColumnsPlusOne+key;
                    if (add <= kids.length){
                        $('#holder:first-child :nth-child('+(numberOfColumnsPlusOne+key)+')').offset({ top: $('#holder:first-child :nth-child('+(key+1)+')').offset().top+$('#holder:first-child :nth-child('+(key+1)+')').height()+marginBottom });
                    }
                });
            });             
        </script>
        <style>
            #holder{
                width:270px;
                border:1px dotted blue;
                display:inline-block; /* Enables the holder to hold floated elements (look at dotted blue line with and without */
            }
            .box{
                width:80px;
                height:150px;
                background-color:#CCC;
                margin:5px;
                text-align:center;
                font-size:45px;
            }
            .one{
                height:86px;
            }
            .two{
                height:130px;
            }
            .three{
                height:60px;
            }
            .four{
                clear:both;
                height:107px;
            }
            .five{
                height:89px;
            }
            .six{
                height:89px;
            }
            .left{float:left;}
            .right{float:right;}
        </style>
    </head>
    <body>      
        <div id="holder">
            <div class="box one left">1</div>
            <div class="box two left">2</div>
            <div class="box three left">3</div>
            <div class="box four left">4</div>
            <div class="box five left">5</div>
            <div class="box six left">6</div>
        </div>
    </body>
</body>

私のソリューションで残っている唯一の問題は、ボックスが1つではなく2ボックス幅の場合に何が起こるかです。私はまだこのソリューションに取り組んでいます。完了したら投稿します。

1
stevenmc

誰かがまだ代替を探しているなら、ここにあります。 (-moz-/-webkit-)column-widthプロパティを使用してみてください。可変div高さの問題を処理します。ただし、列幅は列の最後に新しいdivを追加します。

それ以外の場合、jQuery Masonryが最適に機能します。

1
rodiwa

これは誰にとっても正確な解決策ではないかもしれませんが、私は(文字通り)ボックスの外側を考えることが多くの場合に機能することを見つけました:左から右にボックスを表示する代わりに、多くの場合、最初に左の列を埋めることができます真ん中に行き、それをボックスで埋め、最後に右の列をボックスで埋めます。画像は次のようになります。

order of filling

Phpなどのスクリプト言語を使用している場合は、新しいボックスを追加し、すべての列がいっぱいになったら出力することで、左から右に列を埋めることもできます。例(テストされていないphpコード):

$col1 = '<div class="col1"> <div>box1</div>';
$col2 = '<div class="col2"> <div>box2</div>';
$col3 = '<div class="col3"> <div>box3</div>';
$col1 .= '<div>box4</div> </div>'; //last </div> closes the col1 div
$col2 .= '<div>box5</div> </div>';
$col3 .= '<div>box6</div> </div>';
echo $col1.$col2.$col3;

$ col1、$ col2、および$ col3には、float:leftおよびwidth:33%を指定できます。div内のボックスを全幅に設定し、フロートなしにします。

明らかに、javascript/jqueryを使用してボックスを動的にロードする場合は、このスレッドの他の回答で説明されているように、この方法でボックスをスタイリングすることをお勧めします。

0
bolvo