はじめに
「Reactもビルドツールも使わず、静的なHTMLにマテリアルデザインのボタンやテキストフィールドを一発で入れたい」——そんな場面に出会ったことはないでしょうか。npmもwebpackも用意されていない古めのプロジェクトや、CDNだけで完結させたい社内ツールでは、選択肢が意外と限られます。
Material Design LiteはGoogleが公開しているCSS/JSツールキットで、<link>と<script>をそれぞれ1本読み込むだけでマテリアルデザインのコンポーネント群が使えるようになります。React・Angular・Vueといったフレームワークへの依存が一切ないのが最大の特徴で、素のHTMLにクラス名を付けるだけで見た目とインタラクション(リップルエフェクトなど)が完成します。
ただし正直に書いておくと、Material Design Liteは現在「limited support」というステータスで、Google自身が後継の「Material Components for Web」への移行を案内しています。とはいえv1.3.0はCDNからそのまま使え、枯れているぶん壊れる心配も少ないライブラリです。「いまさら使う価値があるのか」を、実際に手を動かしながら確認していきましょう。
Material Design Liteとは
Material Design Lite(以下MDL)は、GoogleがMaterial Designのガイドラインに沿ったUIコンポーネントを、素のCSS・JavaScript・HTMLだけで実装したツールキットです。npmパッケージとしても、CDN経由の<link>/<script>タグとしても導入できます。
主な特徴
- フレームワーク非依存 - React・Vue・Angularどころか、そもそもビルドステップすら不要です。HTMLにクラス名を付けるだけで動きます
- CDN一発導入 -
material.min.cssとmaterial.min.jsを読み込むだけで、ボタン・カード・テキストフィールド・スナックバーなど一通りのコンポーネントが揃います - componentHandlerによる自動アップグレード - ページ読み込み時に
mdl-js-*クラスの付いた要素を自動でスキャンし、リップルエフェクトなどのインタラクションを付与します - 軽量 - 依存ライブラリを持たず、CSS・JSともに単一ファイルで完結します
インストール
npm・yarnでインストールする場合は次のとおりです。
npm install material-design-lite
yarn add material-design-lite
ビルドツールを使わない場合は、CDNから直接読み込むだけで利用できます。かつて案内されていたgetmdl.ioホスト版のアセットは現在配信が停止しているため、jsDelivrなどのnpmミラー経由か、自前でホストする方法が確実です。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/material-design-lite@1.3.0/material.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/material-design-lite@1.3.0/material.min.js"></script>
Material Design Liteのサンプルを動かす
まずはボタンとテキストフィールドを動かしてみましょう。MDLではmdl-buttonやmdl-textfieldといったクラス名を付けるだけで、Material Designのスタイルとリップルエフェクトが自動で適用されます。フォームに入力すると、テキストフィールドのラベルが浮き上がる「フローティングラベル」の挙動も確認できます。
要点は次のとおりです。mdl-js-buttonやmdl-js-ripple-effectのようにjsが付いたクラスが、componentHandlerによる自動アップグレードの対象になります。
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored">
送信
</button>
<div class="mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="name">
<label class="mdl-textfield__label" for="name">お名前</label>
</div>
実際に動かせるサンプルは下です。名前欄に文字を入力するとラベルが浮き上がり、ボタンをクリックするとリップルエフェクトが広がります。
このサンプルではmdl-button--raisedをmdl-button--fabに変えると円形のFAB(Floating Action Button)に、mdl-textfield--floating-labelを外すと通常のプレースホルダー表示に切り替わります。クラス名を組み替えるだけで見た目が変わるのが、MDLの基本的な使い方です。
基本的な使い方
MDLの基本は、HTML要素に決められたクラス名を付けることです。JavaScriptを自分で書かなくても、mdl-js-*が付いたコンポーネントはページ読み込み時にcomponentHandlerが自動で検出し、インタラクションを組み込んでくれます。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/material-design-lite@1.3.0/material.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/material-design-lite@1.3.0/material.min.js"></script>
</head>
<body>
<div class="mdl-card mdl-shadow--2dp">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">カードタイトル</h2>
</div>
<div class="mdl-card__supporting-text">
これはMaterial Design Liteのカードコンポーネントです。
</div>
</div>
</body>
</html>
mdl-shadow--2dpのようなクラスを付けるだけで、影の深さも指定できます。JavaScript側で明示的に初期化する処理は不要です。
実践的なユースケース
カードでコンテンツをまとめる
一覧画面やダッシュボードでは、複数の情報をカード単位でまとめたい場面が多くあります。MDLのmdl-cardは、タイトル・本文・アクションボタンをひとまとまりにできるコンポーネントで、mdl-shadow--*dpクラスで影の深さを段階的に変えられます。
mdl-shadow--4dpの数値をmdl-shadow--16dpに変えると影がより濃く広くなり、要素が浮いているように見える度合いを調整できます。タイトル部分のbackground-colorを変えるだけで、通知の種類ごとに配色を変えるといった使い方もできます。
動的に追加した要素をアップグレードする
MDLのcomponentHandlerはページ読み込み時に存在する要素しか自動でスキャンしません。JavaScriptでinnerHTMLやDOM APIを使って要素を後から追加した場合、そのままではリップルエフェクトなどが効かないため、componentHandler.upgradeElement()を明示的に呼び出す必要があります。これはMDLを実務で使うときに必ずつまずくポイントです。
const button = document.createElement('button')
button.className = 'mdl-button mdl-js-button mdl-js-ripple-effect'
button.textContent = '追加ボタン'
document.body.appendChild(button)
// これを呼ばないとリップルエフェクトが効かない
componentHandler.upgradeElement(button)
実際に「アップグレードなし」と「アップグレードあり」でボタンを追加し、挙動の違いを比較できるサンプルです。
「アップグレードなしで追加」したボタンをクリックしても波紋(リップルエフェクト)が出ないのに対し、「アップグレードして追加」したボタンではクリックのたびに波紋が広がります。Ajaxで取得したHTMLを差し込む場合や、テンプレートエンジンで動的に一覧を生成する場合は、このcomponentHandler.upgradeElement()の呼び出し忘れが典型的なハマりどころです。
スナックバーで通知を出す
保存完了や削除の取り消しなど、一時的な通知を出したい場面ではMDLのMaterialSnackbarが使えます。mdl-js-snackbarを付けた要素に対してshowSnackbar()を呼ぶと、画面下部にメッセージが数秒間表示されます。
const snackbar = document.querySelector('.mdl-js-snackbar')
snackbar.MaterialSnackbar.showSnackbar({
message: '保存しました',
timeout: 3000,
})
ボタンを押すたびにスナックバーが表示され、メッセージ内容を書き換えられるサンプルです。
入力欄のテキストを書き換えてから「通知を出す」を押すと、そのメッセージがスナックバーに反映されます。timeoutの値を短くすれば表示時間を、actionTextとactionHandlerを追加すれば「元に戻す」のようなアクション付き通知も作れます。
まとめ
Material Design Liteは、Googleが開発を「limited support」に切り替えたとはいえ、ビルド不要でマテリアルデザインのコンポーネントを導入できる手軽さは健在です。componentHandlerによる自動アップグレードの仕組みと、動的要素ではupgradeElement()を明示的に呼ぶ必要がある点さえ押さえておけば、静的なHTMLだけのプロジェクトや、フレームワークを持ち込みたくない社内ツールでは今でも十分に選択肢になります。
より活発に開発が続くコンポーネントライブラリが必要な場合は、Googleが後継として案内している「Material Components for Web」も検討してみてください。まずは今回のサンプルをベースに、カードやスナックバーなど他のコンポーネントも試してみましょう。
