chakra-uiで同じ属性に複数の値(fallback値)を持たせたい時
CSSで特定の値でしか利用できない指定を行う際、複数記述してfallback値とすることがある。
あまり最近は使わないが、例えばsvh
やdvh
のようにsafariでしか使えないものの場合はこんな具合になる
.some-container {
height: 100vh;
height: 100dvh;
}
Chakra UIなどの場合、オブジェクト形式で記載することになるので<Box height={"100vh"} height={"100dvh"} />
と記述しても片方で上書きされてしまう。
一方<Box height={["100dvh","100vh"]} />
のようにしてしまうとレスポンシブとして扱われてしまう。
そのためこの場合どうするか?というのに迷った。
### 解決策1: 型エラーを許容しつつ二重配列形式で記述。
TypeScriptのエラーが出てしまうのだが、下記のような記述で設定されるようだ
<Box
// @ts-ignore
height={[["100vh","100dvh"]]}
>
型を抑止するのに上記ではts-ignore
を利用している。
一応実現は可能だが、ざっとChakra UIのコードを見てもそれらしいコードやテストコードは見つけられなかったので、意図していない仕様バグのようなものの可能性もありそうだ
解決策2: cssプロパティを使う
cssプロパティを利用すれば生のCSSをねじ込むことが出来るので、一応これも可能。
この場合は型エラーも出ないが、CSS部分はなんのハンドリングも無いのでこの点は注意が必要
<Box css={`height: 100vh; height: 100dvh;`} >
&
で解決する
解決策3: sxプロパティとsxを利用する場合は、&
を駆使すると実現できる。
&
はその指定された自身のクラス名に置き換えられるため、無理やり自分を参照するスタイルを複数当てることになる。
<Box
sx={{
height: "100vh",
"&":{
height: "100svh"
}
}}
/>
sxであればChakraのthemeなども利用可能となるので、cssプロパティよりは利点もある。
また、3つ、4つと増やしたい場合、かなり無理はあるが、下記のようにスペースや詳細度に影響を与えない*
を追加することでも解決出来る。
<Box
sx={{
bg: "red.200",
"&":{
bg: "blue.200"
},
" &":{ // スペースを入れればJSを騙す
bg: "yellow.200"
},
"* &":{ // スペースの代わりに*でも代用出来る
bg: "green.200"
},
}}
/>
下に行くほど優先されるのが基本だが、div &
などの場合はCSSの詳細度が変わってしまうので、注意が必要だ。
Discussion