FlexとGridのContainerが広がって伸びる
下記コードでは、左側(①)が伸びてしまっている
gap-2を指定しているが、それ以上の間隔ができてしまっている
https://gyazo.com/7f0880657b002c1bc016b8a1d5fd0dcc
code:tsx
export default function App() {
return (
<div className="grid grid-cols-2 gap-2 h-64 bg-green-200">
{/* ① */}
<div className="grid">
<Child />
</div>
{/* ② */}
<div className="grid">
<div> // divを挟むことで伸びるのを防止
<Child />
</div>
</div>
</div>
);
}
const Child: React.FC = () => (
<div className="grid gap-2 bg-blue-200">
<div className="bg-red-100 h-16">aaa</div>
<div className="bg-red-100 h-16">bbb</div>
<div className="bg-red-100 h-16">ccc</div>
</div>
);
ボトムアップにコードを見ていくと
Childというgridを使って定義されたComponentがある
これをGridを使った親の中で使ったときに、①のように直接置くと伸びてしまう
gap-2を指定しているが、それ以上の間隔ができてしまっている
②のようにdivを挟むと伸びるのを止められる
こういう挙動になるのは当然のこと
Childの高さを誰が指定するかという話
①の場合は、親であるGrid Containerからレイアウトの指示を受けるため、親のGrid Containerに合わせて伸びている
②の場合は、誰もheightを指定していないので、autoの挙動になる
②のようなハックが必要になる状況を考えると
上のコード例では表現できてないが、親目線ではレイアウトを指定するためにgridを指定している
本来の目的としては、レイアウトを指定しつつ、伸びないようにしたい、というもの
Child内のアイテムにheightを指定している場合、伸びるとgapが無視されてしまう
Childにはgap-2を指定しているのに、それ以上の間隔ができてしまっている
他の解決策
items-start
code:tsx
<div className="grid items-start">
<Child />
</div>
これも微妙ではある
高さはautoになるが、<div className="grid">の下に子が2つ以上あるときに理想的でない場合がある
いや、挙動が謎だな
そもそもh-64を指定しているのがおかしい気がしてきた
これ、h-fullとかh-96とか指定すると再現しない
例示のコードがおかしいか
gridにheight指定することないし
これが原因では?mrsekut.icon
divを増やすのは変な気がするが、いまいち他の解決策がわからんな
code:miya.tsx
import * as React from 'react';
import './style.css';
// これへの返信 by miyamonz
export default function App() {
return (
<div className="grid grid-flow-col gap-2 h-64 bg-green-200">
{/* なんでこれがいかんのかというと、ここは↑のgrid itemなので↓はheightが100%になり、 */}
<div className="grid">
{/* ↑こいつがgridだから、↓もheightをいっぱいに広げられてしまうから */}
<Child />
</div>
{/* こうすれば意図通りになる。 */}
<div className="">
<Child />
</div>
↑意図通りにはなるのだけど、これのためにdivを一つ追加するの意味的におかしくない?と思ったのが最初のページを作ったきっかけmrsekut.icon
なるほどmiyamonz.icon
しかし、gridの子要素が縦幅いっぱいになる事実がある以上、避けられないもするmiyamonz.icon
意味的におかしいのかなmiyamonz.icon
grid layoutの子要素のwidth, heightがどのように振る舞うんだっけ
あれ、たしかにmrsekut.icon
flexはflex-basisがあるから、と思ったけどgridがどうなのか知らないな
code:miya.tsx
{/* これもだめ。gridのitemなので、Childはheightを広げて置かれる */}
<Child />
{/* そもそも、コンポーネント自体がいっぱいに広がっても良いようにする */}
<ChildHfull />
</div>
);
}
const Child: React.FC = () => (
<div className="grid gap-2 bg-blue-200">
<div className="bg-red-100 h-16">aaa</div>
<div className="bg-red-100 h-16">bbb</div>
<div className="bg-red-100 h-16">ccc</div>
</div>
);
↓これもなんか地味に意味が変わってそうな感じがして腑に落ちないmrsekut.icon
code:miya.tsx
const ChildHfull: React.FC = () => (
// コンポーネントを親側でいっぱい広げられても良いようにするとよい
<div
// 今回の要件だとw-full,h-fullは無くても同じだが、明示する点で良さげ
className="w-full h-full"
{/* ここでgap-2を維持したいというレイアウト上の要件を実装するために、↑↓でdivを分ける */}
<div className="grid gap-2 bg-blue-200">
<div className="bg-red-100 h-16">aaa</div>
<div className="bg-red-100 h-16">bbb</div>
<div className="bg-red-100 h-16">ccc</div>
</div>
</div>
);
mizchi氏のやつもわかるんだけど、あんまりweb標準標準的なwebの書き方と離れた書き方をしたくないmrsekut.icon
web標準ってなんだろうmiyamonz.icon
仕様という意味ならあるが、
作りたいアプリケーションを実現するためにdivが多めになるのはしゃあないからいいじゃん、とmiyamonz.iconは思ってる
現状のhtml,cssの表現力の限界
むしろgrid layoutとかどんどん改善は進んでいるわけではあるが
そもそもgridにheightを指定してるのが変なのでこう書くべきでは、と後で思ったmrsekut.icon
そんなことないな
最初の例示のコードがおかしいんだけど、あるプロジェクト内部でもミスってそう書いてた
code:ts
export default function App() {
return (
<div className="h-64">
<div className="grid grid-cols-2 gap-2 bg-green-200">
...
</div>
</div>
);
}
ただ、↑これがおかしい、だとして
元のコードで、h-fullとかh-96とか指定すると再現しないのは何故かわかっていないmrsekut.icon
あんまり関係ないけど、grid-flow-colの使い方なるほど(?)mrsekut.icon
使い道があまりわかってなかった
特に数を指定しないときとかに使えるのか(?)
業務のコードに書くならgrid-cols-[1fr,1fr,1fr,1fr]と書きそう(場合による)
rowとcolの向きを定めたってことですねmiyamonz.icon