写真表示ページの更新

Gridにおけるoverflow処理

1.実現したいデザイン

Grid でレイアウトしていて、困ったことに直面した。それは次のような場面だった。

・上下に複数のボックス(BOX1、BOX2、BOX3とする)が並び、それらの全体を包含する親ボックス(container)がある。

・container と BOX2 はそれぞれ別々の事情で可変高、連動しない。BOX1 と BOX3 は高さ固定。

・BOX2 について、その中に収容するデータを下揃えで表示したい。データの量と BOX2 の高さは連動しない。

・BOX2 の中のデータ行数が少なくて余裕がある場合は、BOX1 との間にスペースが空く。

・BOX2 の中のデータ行数が増えて、満杯になると、下端の行からオーバーフロー非表示の処理を行う。その際、行の下半分が非表示といった乱れを避けるため、行単位でオーバーフロー処理を行いたい。

図にしてみると次のようになる。ここで、BOX2 は薄赤色に着色している。また、BOX2 の中に収容するテキストデータは緑色のボックスで表現している。また content-box で表現しているので border の幅 1px も考慮して見る必要がある。

■CSS主要部分■

#container {

height: 280px;

display: grid;

grid-template-rows: 50px 1fr 50px;

grid-template-columns: 1fr;

}

#box2 {

grid-row: 2/3;grid-column:1/2;

align-self: end;

}

#box4 {

}

図-1 データが少ない場合

図-1 はデータ量が 4 行と少ない場合で、BOX1 との間に隙間ができている状態。

2.直面した問題点

オーバーフロー処理が重要なテーマなので、データ量を増やしてみる。図-2 はデータ量を 10 行にした場合。Grid の定義による BOX2 の高さは、

・BOX2 の height = 280 - 50 - 50 = 180

BOX1 と BOX3 の height がそれぞれ 50px なので、border の上下で 2px 引いて、BOX2 の height は CSS の表現では 178px になる。しかし、データは、leine-height:20px で、10 行で計 200px と、BOX2 に収容しきれなくなる。つまり 20px 分溢れてしまう。この 20px がどのように表現されるかは図-2 で確認できる。

■CSS主要部分■

#container {

height: 280px;

display: grid;

grid-template-rows: 50px 1fr 50px;

grid-template-columns: 1fr;

}

#box2 {

grid-row: 2/3;grid-column:1/2;

align-self: end;

}

#box4 {

}

図-2 データが 10 行になった場合

図-2 では BOX2 の height が子要素の合計 height をそのまま継承し、container の height をオーバーして BOX3 を下方にずらしている。container の grid-template-rows 定義 1fr が無視された状態で、不可解としか言いようがない。これが Grid の仕様なのだろうか?

ちなみに、BOX2 の align-self:end を外したり、grid-template-rows の指定を相対指定にすると状況が変わるが主旨から外れるので、ここでは言及しない。(この稿の末尾に掲載する PDF で確認できる。)

次に BOX2 に overflow:hidden を加えたらどうなるか、図-3 をご覧いただきたい。

■CSS主要部分■

#container {

height: 270px;

display: grid;

grid-template-rows: 50px 1fr 50px;

grid-template-columns: 1fr;

}

#box2 {

grid-row: 2/3;grid-column:1/2;

align-self: end;

overflow: hidden;

}

#box4 {

}

図-3 BOX2 に overflow:hidden を加えた場合

container の height の中には納まったものの、BOX2 が拡大した分が BOX1 に被さっている。"container をはみ出せないなら上側の要素に重ねて配置する"ということか。これもどうにも理解できない結果だ。BOX2 が拡大した量は、200-(270-50-50)=30px となる。

3.解決策

色々と考えた結果、BOX2 の height の管理に問題があるのではと思い、BOX2 に対して動的に height 値を設定することとした。図-3 の場合だと 168px(content-box のため CSS 設定値は border の 2px 分差し引く)となる。結果は図-4 。

■CSS主要部分■

#container {

height: 270px;

display: grid;

grid-template-rows: 50px 1fr 50px;

grid-template-columns: 1fr;

}

#box2 {

grid-row: 2/3;grid-column:1/2;

align-self: end;

height: 168px;

overflow: hidden;

}

#box4 {

}

図-4 BOX2 に height を動的に設定

これで最初の目的が達成された。図-1と図-4の違いは、

・図-4では、BOX2 に height を動的に設定

・図-4 では、overflow:hidden を指定

このうち、overflow:hidden は図-1 に指定しておいても害はないので、あらかじめ固定的に CSS に書き加えておいて、BOX2 の height を動的に設定することでこの問題は解決できることが分かった。

最後に、オーバーフロー処理を行単位にする件については、動的に設定する height 値をデータの line-height 値の倍数に整正することで対応した。

■CSS主要部分■

#container {

height: 270px;

display: grid;

grid-template-rows: 50px 1fr 50px;

grid-template-columns: 1fr;

}

#box2 {

grid-row: 2/3;grid-column:1/2;

align-self: end;

height: 160px;

overflow: hidden;

}

#box4 {

}

図-4 BOX2 の height 設定を行高単位に整正

4.動的な設定の処理方法

BOX2 の height の設定をどのような条件の時に行うかについては、次の前提条件がある。

・レスポンシブ環境の中で container の height は独自の事情で変化する。

・BOX2 の中のデータ量も扱う個別のページの事情によって変化する。

・レスポンシブはターゲットを定めた @media による CSS 切り替え方式ではなく、どの様なデバイスであってもシームレスに対応したい。

上記の条件を満たす方法として、次の手順を考えた。

・container の height から逆算して BOX2 の取り得る最大の height 値を算出する。

・BOX2 の height 値を取得する。

両者を比較して、BOX2 の height 値の方が大きい、すなわちオーバーフローする条件の場合に、container の height 値から算出した値を BOx2 の height 値として設定する。

最後に、上の説明では省略した HTML/CSS の詳細や、Grid の定義を相対値で指定した場合などについて試行した結果を PDF にまとめたので、参考までに掲載することとしたい。

Grid の 1fr と overflow(PDF 別画面で開きます)

※掲載記事及び写真に係る著作権は著者に帰属します。著作権を侵害するような利用を禁止します。掲載記事及び写真の全部または一部を複製、蓄積、出版、送信、頒布および改変する等、著者の権利を侵害する利用をすることはできません。