web-dev-qa-db-ja.com

CSSグリッドレイアウトでグリッドアイテム内の要素の高さが等しい

長さ4以上のdiv内に一連の記事があり、丸められた行タグはありません。おそらくdisplay: gridを使用して、行ごとに3つの記事(列)の表として表す必要があります。すべての記事には、ヘッダー、セクション、フッターがあります。

記事の各行内で、記事の下部に揃えて、各ヘッダーに同じ高さ、各セクションに同じ高さ、同じ高さのフッターをどのように実装しますか?可能ですか? display: tableを使用する必要がありますか?

PS画面の幅に応じて、行あたりの記事数を動的に変更する必要があります。ありがとう。

HTML:

body {
  width: 100%;
  max-width: 1024px;
  margin: auto;
}

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.container article {
  display: grid;
}

article header {
  background-color: #eeeeee;
}

article section {
  background-color: #cccccc;
}

article footer {
  background-color: #dddddd;
}
<div class="container">
  <article>
    <header>
      <h2>Header</h2>
      <h2>Header</h2>
    </header>
    <section>
      <p>Content</p>
    </section>
    <footer>
      <p>Footer</p>
    </footer>
  </article>
  <article>
    <header>
      <h2>Header</h2>
    </header>
    <section>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
    </section>
    <footer>
      <p>Footer</p>
      <p>Footer</p>
    </footer>
  </article>
  <article>
    <header>
      <h2>Header</h2>
    </header>
    <section>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
    </section>
    <footer>
      <p>Footer</p>
    </footer>
  </article>
  <article>
    <header>
      <h2>Header</h2>
    </header>
    <section>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
      <p>Content</p>
    </section>
    <footer>
      <p>Footer</p>
      <p>Footer</p>
    </footer>
  </article>
</div>

注意:JSは非推奨です。

https://codepen.io/yudnikov/pen/mBvbGW?editors=1100#

この解決策

grid-auto-rows: 1fr; 

重複として提案されていますが、そうではありません。それは記事に等しい高さを与えるだけですが、例えば各記事のヘッダーのサイズは変わりません。

私はもともとこの問題を抱えていました:

This is what I'am talking about

そしてgrid-auto-rows: 1frソリューションはこれをもたらします:

Wrong!

12
Igor Yudnikov

可能ですか?

tldr;はい。

Codepenデモ#1

Codepen Demo#2 (SASSを使用し、構成可能です)


実際には、CSSグリッドを使用して、マークアップを変更せずにこれを実現する方法があります。

すべての記事のすべてのコンポーネントが1つのCSSグリッド(記事コンテナー)の一部になるように、CSSで構造を「フラット化」できます。

これは、display: contentsで記事を設定することにより、現在のマークアップを変更することなく可能です。

display:contentscaniuse

から カニウス

display: contentsを指定すると、要素の子は、要素自体を無視して、要素の親の直接の子であるかのように表示されます。これは、CSSグリッドまたは同様のレイアウト手法を使用するときにラッパー要素を無視する必要がある場合に役立ちます。

したがって、display: contentsを使用して記事を設定すると、

.container article {
  display: contents;
}

これで、すべてのヘッダー、セクション、およびフッターが(直接の)グリッドアイテムになり(display:gridを持つコンテナーの)、grid-template-areasプロパティを使用して配置できます。

.container {
  display: grid;
  grid-column-gap: 1em; /* horizontal gap between articles */
  grid-template-columns: repeat(3, 1fr);

  grid-template-areas: "header1 header2 header3" 
                       "section1 section2 section3"
                       "footer1 footer2 footer3"
                       "header4 header5 header6" 
                       "section4 section5 section6"
                       "footer4 footer5 footer6"
}

各ヘッダー/セクション/フッターは1つのセルを占めるため、これにより、それらは強制的に同じ垂直高さを占有します。したがって、たとえばheader1、header2、header3は、内容に関係なく、すべて同じ高さになります。

次に、各セルにgrid-areaプロパティを設定します。

article:nth-child(1) header {
  grid-area: header1;
}
article:nth-child(2) header {
  grid-area: header2;
}
article:nth-child(3) header {
  grid-area: header3;
}
article:nth-child(4) header {
  grid-area: header4;
}
article:nth-child(1) section {
  grid-area: section1;
}
...
article:nth-child(4) section {
  grid-area: section4;
}
article:nth-child(1) footer {
  grid-area: footer1;
}
...
article:nth-child(4) footer {
  grid-area: footer4;
}

最後に、記事の各行の間に垂直ギャップを設定します(記事の2行目から開始):

article:nth-child(n + 4) header {
  margin-top: 1em;
}

デモ:

body {
  width: 100%;
  max-width: 1024px;
  margin: auto;
}

.container {
  display: grid;
  grid-column-gap: 1em;
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas: "header1 header2 header3" 
                      "section1 section2 section3"
                        "footer1 footer2 footer3"
                        "header4 header5 header6" 
                      "section4 section5 section6"
                        "footer4 footer5 footer6"
}

.container article {
  display: contents;
}

article header {
  background-color: #eeeeee;
}

article section {
  background-color: #cccccc;
}

article footer {
  background-color: #dddddd;
}

article:nth-child(n + 4) header {
  margin-top: 1em;
}

article:nth-child(1) header {
  grid-area: header1;
}
article:nth-child(2) header {
  grid-area: header2;
}
article:nth-child(3) header {
  grid-area: header3;
}
article:nth-child(4) header {
  grid-area: header4;
}
article:nth-child(1) section {
  grid-area: section1;
}
article:nth-child(2) section {
  grid-area: section2;
}
article:nth-child(3) section {
  grid-area: section3;
}
article:nth-child(4) section {
  grid-area: section4;
}
article:nth-child(1) footer {
  grid-area: footer1;
}
article:nth-child(2) footer {
  grid-area: footer2;
}
article:nth-child(3) footer {
  grid-area: footer3;
}
article:nth-child(4) footer {
  grid-area: footer4;
}
<div class="container">
    <article>
        <header>
            <h2>Header</h2>
            <h2>Header</h2>
        </header>
        <section>
            <p>Content</p>
        </section>
        <footer>
            <p>Footer</p>
        </footer>
    </article>
    <article>
        <header>
            <h2>Header</h2>
        </header>
        <section>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
        </section>
        <footer>
            <p>Footer</p>
            <p>Footer</p>
        </footer>
    </article>
    <article>
        <header>
            <h2>Header</h2>
        </header>
        <section>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
        </section>
        <footer>
            <p>Footer</p>
        </footer>
    </article>
    <article>
        <header>
            <h2>Header</h2>
        </header>
        <section>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
            <p>Content</p>
        </section>
        <footer>
            <p>Footer</p>
            <p>Footer</p>
        </footer>
    </article>
</div>

Codepen Demo)

もちろん、grid-template-areas + grid-areaプロパティを使用する代わりに、grid-row + grid-columnプロパティを使用して同じ結果を得ることができます-Codepenデモ


注:私は上記が冗長で正確に最適なソリューションではないことを理解しています-しかし、ここでの私のポイントはです可能です。また、 SASSループを使用して、そのコードをよりクリーンで構成可能にすることもできます

grid-template-areasを使用してパターンを繰り返す方法がある場合、それはいいかもしれません-次のようなもの:

疑似コード(非合法):

grid-template-areas: repeat("header1 header2 header3" 
                           "section1 section2 section3"
                           "footer1 footer2 footer3")

...次に、次のようにnth-childを使用してグリッド領域を設定することにより、n記事のソリューションで機能するより動的なソリューションを取得できます。

article:nth-child(3n + 1) header {
  grid-area: header1;
} 

等...しかし、現時点ではそれは可能ではないと思います(または subgrids がこれを行うことができるため、おそらく必要ないかもしれません)。


NB:

グリッドレイアウトモジュールレベル2に Subgrids が導入され、この問題を簡単に解決でき、display: contentsを使用する必要がなくなります


Display:tableを使用する必要がありますか?

必要なレイアウト-display:tableはあまり役に立ちません。まず、マークアップを完全に再構成して、articleコンポーネントをグループ化して記事に配置する必要があります。テーブルのスタイルを設定するには、ハックする必要があります。 「記事」のように見えるがそれでも-テーブルは折り返さないので、3つの記事ごとに別々のテーブルにラップする必要があります...たとえそれが可能であったとしても、本当に面倒でメンテナンスが難しいでしょう。

10
Danield