コンポーネントを組み合わせてコンテンツを作っていく時、
子コンポーネントに margin-top
を指定して隙間を設けたい場合が多々あります。
今回はそのやり方です。
[[私はemotionの記事を見てもできませんでしたが、このやり方は Attaching Props
に当てはまると思っています。]]
理想の形
- 親の中で
marign-top
を指定したい。 -
Footer
は自身のcssだけ管理したい。(親のcssは気にしたくない)
// 親
const marginTop = css`
margin-top: 2rem;
`
<Footer css={marginTop} />
//子供 (親の都合は知らない)
export const Footer = () => {
return (
<footer>
内容
</footer>
)
}
この時、やり方としては2パターンあるかなと思います。
1つ目:親側でdivやspanで囲ってしまう
// 親
const marginTop = css`
margin-top: 2rem;
`
<div css={marginTop}>
<Footer />
</div>
正しくstyleが当たります。
ただ、これだとcssを当てるためだけに div
が生まれてしまいます。
これが続くとファイルの見通しも悪くなってしまいます。
// 本当はいらないdivばっかり...
<div css={marginTop}>
<SampleA />
<div>
<span css={marginTop}> // 注意
<SampleB />
<span>
<p css={marginTop}>
<SampleC />
<p>
*注意:span等のinline要素はmargin-topは当たらない。block要素で囲むか、display: block;しよう
2つ目:理想の形を実現する Attaching
// 親
const marginTop = css`
margin-top: 2rem;
`
<Footer css={marginTop} />
//子供 (親の都合は知らない)
type Props = {
className? : string
}
export const Footer = ({className}:Props) => {
return (
<footer className={className}>
内容
</footer>
)
}
子供の変更は className
を持たせただけ。
それを当てておくだけだけで親で指定したStyleが当たります!
まとめ
この方法を使えば、不要な div
などを設けず、シンプルに実装できます。
ぜひ使ってください!
ちなみに。。。
純粋なAtomコンポーネントには、 margin-top
や margin-bottom
など、他のコンポーネントに影響する指定をする方法はお勧めしません。
後から「このページで使う時にはmarginいらないんだよね。。。」となってしまう時が必ず来る(来そう)からです。