【Astro】コンポーネントのスタイルを親から制御する方法
Vue のようにコンポーネントに class を付けようとしたら、適用されませんでしたのでその解決法を案内します。
青文字の Button コンポーネントを例に
次の Button
コンポーネントは、デフォルトで青色のテキストを持ちます。
親で指定された class を反映させるために class:list
を使用します。
html
---
const { class: className } = Astro.props;
---
<button class:list={['Button', className]}>
<slot />
</button>
<style>
.Button {
color: blue;
}
</style>
このボタンのテキストを赤文字にしたい
しかし、次のように index.astro
でこのボタンを赤色にしようとしても期待通りには動作しません。
html
---
import Layout from '../layouts/Layout.astro';
import Button from '../components/Button.astro';
---
<Layout title="トップページ">
<Button class="red">ボタン</Button>
</Layout>
<style>
.red {
color: red;
}
</style>
この方法では、ボタンは赤くなりませんでした。
解決策
解決策は英語版のドキュメントにありました。
Passing a class to a child component
スプレッド構文 (...rest
) を使用してすべての属性を受け取ることで、親の data-astro-cid
も子コンポーネントに渡され同一スコープとなることで親で定義したスタイルが適用されるようになります。
html
---
const { class: className, ...rest } = Astro.props;
---
<button class:list={['Button', className]} { ...rest }>
<slot />
</button>
<style>
.Button {
color: blue;
}
</style>
注意点
日本語版のドキュメントは古い情報のまま掲載されていました(2024/4/4現在)。
そこでは、「classを渡してclassNameで受け取る」と簡単に説明されていますが、英語版のドキュメントとは内容が異なりますので注意が必要です。
このパターンでは、子コンポーネントに直接スタイルを設定できます。Astroは、親のスコープ付きクラス名(例:astro-hhnqfkh6)をclassプロパティを通して自動的に渡し、その子を親のスコープに含めます。
簡単にまとめると...
- Astroでは、デフォルトでコンポーネント間で
class
属性は自動的に渡されません。 - 子コンポーネントにスタイルを適用するには、
class
属性とその他の必要な属性を明示的に渡す必要があります。 - スプレッド構文 (
...rest
) を使用することで、親コンポーネントのdata-astro-cid
と共にスタイルを子コンポーネントに適用できます。 - 日本語版ドキュメントは古い情報を含む可能性があるため、最新の情報は英語版ドキュメントを参照することが重要です。