web-dev-qa-db-ja.com

レスポンシブな正方形のグリッドレイアウト

レスポンシブな正方形のグリッドレイアウトを作成したいです。

CSSグリッドレイアウトでこれを実行できるはずですが、各正方形の高さを幅に等しく設定するのに問題があります。

また、各正方形の間に溝を設定するのに問題があります。

フレックスボックスを使用したほうが良いでしょうか?

現在、私のHTMLはこのように見えますが、動的になるため、より多くの正方形を追加できます。そしてもちろん、応答性が必要であるため、メディアクエリを使用して1列にまとめるのが理想的です。

<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

CSSグリッドを使用して、これは私が得た限りです

.square-container{
    display: grid;
    grid-template-columns: 30% 30% 30%;
    .square {

    }
}

flexboxでもう少し進めることができ、Nice Gutterで正方形を揃えるためにspace-betweenを使用できましたが、各正方形の幅に合わせて高さを取得するのに苦労しました。

flexboxまたはgridのいずれかで行われているこの例は見つかりませんでしたが、どの例も同様に評価されます。

ありがとう

20
Stretch0

padding-bottomトリックは、それを達成するために最もよく使用されます。

FlexboxとCSSグリッドの両方と組み合わせることができます。マージン/パディングにパーセントを使用すると、フレックス/グリッドアイテムに一貫性のない結果が得られるため、追加のラッパーを追加できます。擬似。したがって、パーセントを持つ要素は、フレックス/グリッド項目ではありません。


Edit:注:仕様に対して 更新が行われています。 これで、一貫した結果が得られるはずです。フレックス/グリッドアイテムで使用されます。ただし、この問題は古いバージョンでも発生します。


注:content要素にコンテンツを追加する場合、正方形のアスペクト比を維持するために絶対位置にする必要があります。

フィドルデモ-Flexbox

.square-container {
  display: flex;
  flex-wrap: wrap;
}

.square {
  position: relative;
  flex-basis: calc(33.333% - 10px);
  margin: 5px;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

CSSグリッドバージョン

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  position: relative;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>
18
LGSon

ビューポートのパーセンテージ単位を使用してみてください。

jsFiddle

.square-container {
  display: grid;
  grid-template-columns: repeat(3, 30vw);
  grid-template-rows: 30vw;
  grid-gap: 2.5vw;
  padding: 2.5vw;
  background-color: gray;
}

.square {
  background-color: lightgreen;
}

body {
  margin: 0; /* remove default margins */
}
<div class="square-container">
  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content spread"></div>
  </div>
  <div class="square">
    <div class="content column"></div>
  </div>
</div>

仕様から:

5.1.2。ビューポートの割合の長さ:vwvhvminvmax単位

ビューポートの割合の長さは、最初の包含ブロックのサイズに相対的です。初期包含ブロックの高さまたは幅が変更されると、それに応じてスケーリングされます。

  • vw unit-初期包含ブロックの幅の1%に等しい。
  • vh unit-初期包含ブロックの高さの1%に等しい。
  • vmin unit-vwまたはvhの小さい方に等しい。
  • vmax unit-vwまたはvhの大きい方に等しい。
9
Michael_B

paddingが幅に基づいて計算され、padding-top: 100%に直接squareグリッド項目(グリッド項目は正方形になります)。


2019年更新

フレックスアイテムおよびグリッドアイテムの場合、これは以前は動作しませんでした。コメントでこの回答にリンクされている投稿を参照してください。

flex itemsgrid itemspaddingで同じ動作をするというブラウザー(新しいバージョン)のコンセンサスがあるので、このソリューションを使用できます。

以下のデモをご覧ください:

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  background: cadetblue;
  padding-top: 100%; /* padding trick directly on the grid item */
  box-sizing: border-box;
  position: relative;
}

.square .content { /* absolutely positioned */
  position: absolute;
  top: 0;
  right:0;
  left: 0;
  bottom: 0;
}
<div class="square-container">
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content column">some content here and there is a lot of text here</div>
  </div>
  <div class="square">
    <div class="content spread">text</div>
  </div>
  <div class="square">
    <div class="content column">some text here</div>
  </div>
</div>
2
kukkuz