Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【HTML Living Standard】part属性の使い方

part属性の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

partプロパティは、Web ComponentsのShadow DOM内部にある要素に、外部からCSSスタイルを適用するための名前を保持するプロパティです。このグローバル属性は、主にWeb Componentsにおけるカプセル化されたコンポーネントのデザインカスタマイズを可能にします。

Web Components技術の一つであるShadow DOMは、コンポーネントの内部構造とスタイルを外部から完全に隔離する仕組みを提供します。これにより、コンポーネントのスタイルが外部に影響を与えたり、外部から意図しないスタイルが適用されたりすることを防ぎ、再利用性や堅牢性を高めます。しかし、このカプセル化の性質上、コンポーネントの内部の特定の要素の見た目を外部から変更したい場合に課題が生じます。

partプロパティは、この課題を解決するために導入されました。Shadow DOM内部の要素にpartプロパティを設定し、任意の識別名(part名)をスペース区切りで付与することで、その要素を外部から参照できるようになります。その後、Web Componentsのホスト要素(Shadow DOMを持つコンポーネント自体)に対して::part()疑似要素を使用し、指定したpart名を用いて内部の要素を選択し、CSSでスタイリングすることが可能になります。

これにより、Web Componentsが提供する厳密なカプセル化を維持しつつ、ユーザーや開発者がコンポーネントの見た目を柔軟にカスタマイズできる設計を実現します。

公式リファレンス: HTML part global attribute

構文(syntax)

1<div part="header main-content"></div>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

HTML part 属性でカスタム要素をスタイリングする

1<!DOCTYPE html>
2<html lang="ja">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>HTML part 属性のサンプルコード</title>
7    <style>
8        /*
9         * my-custom-card::part(part-name) 構文を使用して、
10         * シャドウルート内の 'part' 属性を持つ要素を外部からスタイリングします。
11         */
12
13        /* カスタム要素全体に適用される基本スタイル */
14        my-custom-card {
15            display: block; /* カスタム要素はデフォルトでインラインなのでブロック要素にする */
16            border: 1px solid #ddd;
17            border-radius: 8px;
18            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
19            padding: 15px;
20            margin: 20px auto;
21            max-width: 400px;
22            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
23            background-color: #fff;
24        }
25
26        /* 'card-header' という part 名を持つ要素にスタイルを適用 */
27        my-custom-card::part(card-header) {
28            background-color: #f0f8ff; /* 薄い水色 */
29            color: #333;
30            padding: 10px 15px;
31            margin: -15px -15px 15px -15px; /* 親のパディングと合わせるため負のマージン */
32            border-bottom: 1px solid #eee;
33            border-radius: 8px 8px 0 0;
34            font-size: 1.2em;
35            font-weight: bold;
36        }
37
38        /* 'card-body' という part 名を持つ要素にスタイルを適用 */
39        my-custom-card::part(card-body) {
40            color: #555;
41            line-height: 1.6;
42            font-size: 0.95em;
43        }
44    </style>
45</head>
46<body>
47
48    <h1>`part` 属性のデモンストレーション</h1>
49    <p>`part` 属性はWebコンポーネントのシャドウルート内部にある要素を、外部のCSSからスタイリング可能にするためのグローバル属性です。</p>
50    <p>以下のカードはカスタム要素(<code>&lt;my-custom-card&gt;</code>)で、内部のヘッダーとボディが`part`属性によって外部CSSから装飾されています。</p>
51
52    <!--
53     * カスタム要素を定義するスクリプト。
54     * ここで `part` 属性を持つ要素がシャドウルート内に作成されます。
55     -->
56    <script>
57        class MyCustomCard extends HTMLElement {
58            constructor() {
59                super(); // HTMLElement のコンストラクタを呼び出す
60
61                // シャドウルートを作成し、モードを 'open' に設定(JavaScriptからアクセス可能)
62                const shadowRoot = this.attachShadow({ mode: 'open' });
63
64                // ヘッダー要素を作成し、'part' 属性を設定
65                const header = document.createElement('h3');
66                header.setAttribute('part', 'card-header'); // part 名を 'card-header' に設定
67                header.textContent = 'カスタムカードのタイトル';
68
69                // ボディ要素を作成し、'part' 属性を設定
70                const body = document.createElement('p');
71                body.setAttribute('part', 'card-body'); // part 名を 'card-body' に設定
72                body.textContent = 'これはカスタム要素の本文です。' +
73                                   'このテキストを含むパラグラフは、`part="card-body"` 属性が付与されているため、' +
74                                   '外部CSSの `my-custom-card::part(card-body)` セレクタでスタイリングされています。';
75
76                // シャドウルートに作成した要素を追加
77                shadowRoot.appendChild(header);
78                shadowRoot.appendChild(body);
79            }
80        }
81
82        // 'my-custom-card' というカスタム要素をDOMに登録
83        customElements.define('my-custom-card', MyCustomCard);
84    </script>
85
86    <!-- 定義したカスタム要素を使用する -->
87    <my-custom-card></my-custom-card>
88    <my-custom-card></my-custom-card>
89
90</body>
91</html>

part属性は、HTML要素に適用できるグローバル属性の一つです。これは主にWebコンポーネントにおいて、シャドウルートと呼ばれる内部構造を持つ要素を、外部のCSSから部分的にスタイリング可能にするための仕組みを提供します。part属性自体は引数や戻り値を持たず、値として任意の文字列(part名)を指定します。

提供されたサンプルコードでは、<my-custom-card>というカスタム要素が定義されています。このカスタム要素のスクリプト内で、シャドウルート内にヘッダー要素とボディ要素を作成し、それぞれにpart="card-header"part="card-body"という属性を設定しています。通常、シャドウルート内の要素は外部CSSから直接スタイルを適用できませんが、part属性を付与することで、::part()擬似要素を使って外部から特定の部品にスタイルを適用できるようになります。

具体的には、<style>タグ内でmy-custom-card::part(card-header)というCSSセレクタを使用し、カスタムカード内のcard-headerと名付けられた部分に背景色や文字色などのスタイルを設定しています。同様にmy-custom-card::part(card-body)で本文部分のスタイルを定義しています。このようにpart属性を利用することで、Webコンポーネントのカプセル化を保ちつつ、ユーザーや開発者がコンポーネントの見た目を柔軟にカスタマイズできる点が大きなメリットです。

part属性は、WebコンポーネントのShadow DOM内部にある要素を、外部CSSからスタイリング可能にするグローバル属性です。これはコンポーネントの内部構造を隠しながら、デザインのカスタマイズ性を提供します。注意点として、外部CSSでスタイルを適用するには::part(part-name)という専用のセレクタを使う必要があります。part属性がないシャドウルート内の要素は外部から直接スタイルできないため、どの要素をカスタマイズ可能にするか、開発者が意図的に設定することが重要です。Webコンポーネントの基礎知識と合わせて学習を進めてください。

HTML part属性で非同期コンテンツを制御する

1<!DOCTYPE html>
2<html lang="ja">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>HTML part属性サンプル</title>
7    <style>
8        /* カスタム要素内の「content-text」というpartにスタイルを適用 */
9        /* ::part()擬似要素はシャドウルート外部から内部要素をスタイリングするために使用 */
10        my-async-part-element::part(content-text) {
11            font-size: 18px;
12            color: darkblue;
13            border: 1px solid #ccc;
14            padding: 10px;
15            background-color: #e0f7fa;
16            display: inline-block;
17            margin-bottom: 5px;
18        }
19
20        /* 別のpart「action-button」にスタイルを適用 */
21        my-async-part-element::part(action-button) {
22            background-color: #4CAF50;
23            color: white;
24            padding: 8px 15px;
25            border: none;
26            border-radius: 4px;
27            cursor: pointer;
28            font-size: 16px;
29        }
30
31        my-async-part-element::part(action-button):hover {
32            background-color: #45a049;
33        }
34    </style>
35</head>
36<body>
37    <h1><code>part</code>属性の基本サンプル</h1>
38    <p>
39        <code>part</code>属性は、Web Components (カスタム要素) のシャドウルート内部にある要素に名前を付け、
40        シャドウルートの外部からCSSでその要素にスタイルを適用したり、JavaScriptでアクセスしたりするためのフックを提供します。
41        特に、非同期でロード・生成されるコンテンツの一部を外部から制御したい場合に役立ちます。
42    </p>
43
44    <!-- ここにカスタム要素を配置します -->
45    <my-async-part-element></my-async-part-element>
46
47    <script>
48        // カスタム要素を定義します
49        class MyAsyncPartElement extends HTMLElement {
50            constructor() {
51                super();
52                // シャドウルートを作成し、モードを'open'に設定(外部からのアクセスを許可)
53                const shadowRoot = this.attachShadow({ mode: 'open' });
54
55                // 内部コンテンツを作成し、part属性を付与します
56                const wrapper = document.createElement('div');
57                wrapper.innerHTML = `
58                    <p part="content-text">初期のコンテンツです。</p>
59                    <button part="action-button">コンテンツを更新</button>
60                `;
61                shadowRoot.appendChild(wrapper);
62
63                // ボタンがクリックされた時のイベントリスナーを設定
64                // part属性を持つ要素は、shadowRoot.querySelector('[part="属性値"]')でアクセス
65                const button = shadowRoot.querySelector('[part="action-button"]');
66                button.addEventListener('click', () => {
67                    const contentText = shadowRoot.querySelector('[part="content-text"]');
68                    if (contentText) {
69                        contentText.textContent = 'ボタンが押されてコンテンツが更新されました!';
70                        contentText.style.color = 'red'; // JavaScriptで直接スタイルを変更
71                        contentText.style.backgroundColor = '#ffe0b2';
72                    }
73                });
74            }
75
76            // 要素がDOMに接続されたときに呼ばれるライフサイクルコールバック
77            connectedCallback() {
78                console.log('MyAsyncPartElementがDOMに接続されました。');
79
80                // 非同期処理をシミュレート
81                // 例えば、要素がDOMに接続された後に外部データに基づいてコンテンツを更新する場合
82                setTimeout(() => {
83                    console.log('2秒後に非同期でコンテンツを更新します。');
84                    const contentText = this.shadowRoot.querySelector('[part="content-text"]');
85                    if (contentText) {
86                        contentText.textContent = '非同期処理で更新されたコンテンツです!';
87                        contentText.style.fontStyle = 'italic';
88                        contentText.style.color = 'green';
89                    }
90                }, 2000); // 2秒後に実行
91            }
92        }
93
94        // 'my-async-part-element'という名前でカスタム要素を登録
95        customElements.define('my-async-part-element', MyAsyncPartElement);
96    </script>
97</body>
98</html>

HTMLのpart属性は、Web Components(カスタム要素)のシャドウルート内部にある特定の要素に対して、外部からアクセスするための「名前」を付ける役割を果たします。これにより、シャドウルートのカプセル化を維持しながら、外部のCSSで要素にスタイルを適用したり、JavaScriptでその要素を操作したりすることが可能になります。part属性自体は引数や戻り値を持たず、単純に名前を割り当てるために使用されます。

この属性は、特にカスタム要素内で非同期にロードまたは生成されるコンテンツに対して、外部から柔軟に制御したい場合に非常に有用です。例えば、サンプルコードではカスタム要素my-async-part-elementの内部にある段落にpart="content-text"、ボタンにpart="action-button"と名前を付けています。これにより、外部のCSSから::part(content-text)::part(action-button)といった擬似要素を使って、これらの内部要素に直接スタイルを適用しています。また、JavaScriptではshadowRoot.querySelector('[part="属性値"]')のように、この名前を使って要素を特定し、非同期でコンテンツを更新したり、スタイルを変更したりしています。このように、part属性を使用することで、カスタム要素の内部構造をすべて知らなくても、外部から見た目の調整や振る舞いの制御が容易になります。

part属性は、Web ComponentsのシャドウDOM内部にある特定の要素に、外部からCSSでスタイルを適用したり、JavaScriptでアクセスしたりするための仕組みです。初心者は、::part()擬似要素を使ってシャドウDOM内の要素をスタイリングすること、またJavaScriptからはshadowRoot.querySelector('[part="属性値"]')でアクセスすることに注意が必要です。シャドウルートのモードは必ずopenに設定してください。非同期でロード・生成されるコンテンツに対しても効果的に利用できますが、シャドウDOMのカプセル化とのバランスを考慮し、コンポーネントの独立性を損なわないよう利用箇所を限定することが安全なコード利用の鍵となります。

関連コンテンツ

関連IT用語