remarkを用いて画像をインライン絵文字として使えるようにしてみた

公開日: 2026年4月24日 21時55分 517文字 3分間

文中で画像を絵文字のようにインライン表示させるため、remarkとremark-directiveを活用した新機能を実装しました。特定の構文で記述された画像を、CSSで文字サイズに合わせてリサイズし、ブロック表示にならないよう調整しています。これにより、スクリプトとスタイルを追加するだけで、手軽に新しいコンポーネントを導入できる仕組みを構築しました。

インライン絵文字 🥳

こんな感じ🥳で文中で画像を絵文字っぽく使いたかったのですが、普通に画像を埋め込むとマークダウンの変換の都合上ブロック型の表示になってしまうので、新たにその機能を自分のサイトに実装することにしました。

フォークしたリポジトリなので、何のライブラリが入ってるかまずは確認…

プロジェクトの依存関係
プロジェクトの依存関係

remarkが入ってるので、これを使って作ってみます。

スクリプトを書いてみる

remark-directiveというプラグインが入っていたので、これも活用します。このプラグインは具体的には:name[data]{attr="none"]みたいな感じの形式を扱いやすくする物らしいです。

    visit(tree, 'textDirective', (node, index, parent) => {
      if (index === undefined || !parent) return;
      if (node.type !== 'textDirective') return;
      const directive = node as TextDirective;
      if (directive.name !== 'emoji') return;

      const src =
        node.children
          ?.filter((child): child is TextNode => child.type === 'text')
          .map((child) => child.value)
          .join('') ?? '';
      const alt = node.attributes?.alt;
      const render = node.attributes?.render;

      let content = `<img class="emoji-image" src="${src}" `;
      if (alt) content += `alt="${alt}" `;
      if (render) content += `style="image-rendering: ${render}" `;
      content += '>';

      parent.children[index] = {
        type: 'html',
        value: content,
      };
    });

こんな感じのコードになりました。内容はシンプルに:emoji[...]があった場合に中身をsrcとしてemoji-imageクラスの画像を埋め込むようにするというもの。

attributeでaltと、ドット絵をぼやけず拡大させるためにimage-renderingも指定できるようにしてみました。一切れのケーキ

.emoji-image {
  display: inline-block;
  height: 1.2em;
  margin-top: 0;
  margin-bottom: 0;
}

CSS側ではheightを使って画像サイズを文字に合わせてリサイズするように設定して、その他ブロック表示用のスタイルを打ち消しています。

おわりに

記事を書いていて何か新しいコンポーネントがほしいとなった時に、スクリプトとスタイルだけ書いてサクッと実装できるのは結構面白いなと思いました。

結果: 絵文字で遊べて楽しい 🥳🥳🥳