最近のChromeにはCSSの新機能が次々と搭載されています。2017年にはCSS Grid Layoutなどインパクトの大きい新機能が話題になりましたが、他にも有用な新機能があることをご存じでしょうか? この記事では、2018年のChromeに搭載された新機能の中から、CSS Paint APIを紹介します。
CSS Paint APIはグラフィックを描く機能
CSS Paint APIは自由にグラフィックを描ける仕様です。HTML5 Canvasのようなものを要素の背景画像(background-image
やborder-image
)として設定できます。JavaScriptを使って自由にグラフィックを描けるため、従来のCSSで再現の難しかった表現が実現可能になります。
たとえば、次のようなビジュアルを考えてみましょう。四隅の形状が欠けたような表現となっています。従来のCSSではdiv
タグを複雑に組む必要がありました。

CSS Paint APIを使うと、1つのdiv
タグにCSSを割り当てるだけで実現できます。CSSだけでなくJavaScriptを作成する必要はありますが、HTMLの構造を汚さずに装飾を自由に設計できることが利点といえるでしょう。
▼CSS Paint APIを使って実現したHTMLコード
CSS.paintWorklet.addModule('worklet.js'); |
background-image: paint(rect); |
基本的な利用方法の解説
CSS Paint APIを使って、簡単な三角形を描いてみましょう。下図のようにdiv
タグの背景にCSS Paint APIで描いた三角形が背景画像として設定されている状態を目指します。
CSS Paint APIを利用するには、独立したJavaScriptのファイルを作成します。これをペイントワークレットといいます。必ず独立した.js
ファイルとして作成する必要があります。
ペイントワークレット側の作成
ペイントワークレットのJavaScriptファイルには任意のクラスを作成します。クラスのフィールドにはpaint()
メソッドを実装し、registerPaint()
メソッドでクラスとメソッド名の関連付けします。
paint(context, geometry) { |
{x: 0, y: geometry.height}, |
{x: geometry.width, y: geometry.height}, |
{x: geometry.width / 2, y: 0}, |
context.moveTo(points[0].x, points[0].y); |
context.lineTo(points[1].x, points[1].y); |
context.lineTo(points[2].x, points[2].y); |
context.fillStyle = 'red' ; |
registerPaint( 'triangle' , TrianglePainter); |
paint()
メソッドはHTML5 CanvasのCanvas2DRendererContext
オブジェクトと似たコンテキストを引数として受け取れます。このコンテキストに対して命令をすることで描画結果を作成します。引数のgeometry
やproperties
に含まれる情報をもとに描画結果を調整します。
-
geometry
: この引数には描画領域のサイズ情報が入っている -
properties
: CSS変数と連携できる引数
メインのHTML側の作成
メインのHTML側からはJavaScriptでCSS.paintWorklet.addModule()
メソッドを利用してワークレットを登録します。引数にはワークレットのJavaScriptファイルを指定します。
▼ JavaScript
CSS.paintWorklet.addModule( 'worklet.js' ); |
スタイルシート側では、background-image
プロパティーに対してpaint()
メソッドを指定します。paint()
メソッドにはワークレットのregisterPaint()
登録した描画クラスを指定します。
▼ スタイルシート(CSS)
background-image : paint(triangle); |
パラメーターで動的に描画を変更可能に
CSS Paint APIとCSS変数を連携することで、パラメーターで動的に描画を変更可能になります。
ワークレット側のクラスにstatic get inputProperties()
を実装し、読み取りたいプロパティ名の配列を戻り値とします。
ワークレット側のpaint()
メソッドの第三引数properties
はCSSのプロパティを読み出すために使う引数です。get()
メソッドを使うとstatic get inputProperties()
で割り当てたCSS変数を受け取れます。
▼ ペイントワークレット(JavaScript)
static get inputProperties() { |
paint(context, geometry, properties) { |
const color = properties.get( '--fill-color' ).toString(); |
{x: 0, y: geometry.height}, |
{x: geometry.width, y: geometry.height}, |
{x: geometry.width / 2, y: 0}, |
context.moveTo(points[0].x, points[0].y); |
context.lineTo(points[1].x, points[1].y); |
context.lineTo(points[2].x, points[2].y); |
context.fillStyle = color; |
registerPaint( 'triangle' , TrianglePainter); |
利用する側にはCSS変数を定義します。ハイフンを二個つなげて定義します。
▼ スタイルシート(CSS)
background-image : paint(triangle); |
CSS変数はデベロッパーツールで変化させてみると、動的に変化可能であることがわかります。
アニメーションの実装方法
JavaScriptで時間経過によって値が変動するようにしましょう。次のサンプルでは、時間経過で塗りの色が変化するようにしています。
具体的にはJavaScriptのrequestAnimationFrame()
メソッドを使って、時間経過でCSS変数の値を書き換えます。
▼ メイン側のJavaScript
CSS.paintWorklet.addModule( 'worklet.js' ); |
window.addEventListener( 'DOMContentLoaded' , () => { |
const el = document.querySelector( '.graphics' ); |
const hue = Math.round((Date.now() / 10) % 360); |
el.style.setProperty( '--fill-color' , `hsl(${hue}, 100%, 50%)`); |
requestAnimationFrame(tick); |
このように、CSS変数との連携によってカスタマイズ性に富んだオリジナルのCSSを設計できるようになります。
応用作例を紹介〜タイル調グラデーション
次のサンプルはCSS変数を使って、グラデーションを描いたものです。動画を再生して、CSS Paint APIの可能性をご覧ください。
格子状の分割数はCSS変数で管理しているため、簡単に数値の変化でグラフィックを自在に編集できます。プログラミングアートと相性がよく、自由にグラフィックを描けるので応用の幅が広いです。
次のページでは気になる動作環境や注意点について紹介します。