リッチテキストにTailwindCSSを当てる時の最適解
microCMSのリッチテキストエディタを使用したブログ記事にTailwindCSSを当てる際、苦労した点を共有します。
最初は「TailwindCSS / Typographyプラグイン」を使用しましたが、この方法だと細かいところまで手が届かなかったので、その解決法を紹介します。
前提条件
- フレームワークにNext.js(App Router)を使用
- CSSフレームワークにTailwindCSSを使用
最適解
結論から言うとリッチテキストには@layerでカスタムクラスを定義することが最適解だと思いました。
以下で詳しく説明します。
1. リッチテキストをHMTL(JSX)に挿入する
以下のような、HTML(JSX)を想定します。
今回は、リッチテキストをdangerouslySetInnerHTML
で挿入し、そのdiv
タグにclassName="prose"
を設定しました。
import { createClient } from 'microcms-js-sdk';
// ブログの型定義
export type Blog = {
title: string;
description: string;
// リッチテキストはcontentに格納されている
content: string;
thumbnail?: MicroCMSImage;
tags?: Tag[];
writer?: Writer;
};
// Initialize Client SDK.
export const client = createClient({
serviceDomain: process.env.MICROCMS_SERVICE_DOMAIN,
apiKey: process.env.MICROCMS_API_KEY,
});
// ブログの詳細を取得
export const getDetail = async (contentId: string, queries?: MicroCMSQueries) => {
const detailData = await client
.getListDetail<Blog>({
endpoint: 'blog',
contentId,
queries,
})
.catch(notFound);
return detailData;
};
// リッチテキストエディタを使用する画面レイアウト
export default const Page: FC = () => {
const blog = await getDetail(contentId);
return (
<div
className="prose"
dangerouslySetInnerHTML={{ __html: blog.content }}
/>
)
}
@layer
でカスタムクラス(スタイル)を定義する
2. 上記でリッチテキスト部分にprose
というクラス名を適応させたので、生のCSSのように.prose
で定義していきます。
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.prose {
@apply text-base font-bold
}
.prose h1 {
@apply text-xl
}
/* ... */
}
@layer(base, components, utilities)とは?
公式ドキュメントがわかりやすいので、参考にしてください。
@applyとは?
簡単にいうと、生のCSSではなく、TailwindCSSの記法をそのまま使用するためのディレクティブです。
カスタムクラスを定義するメリット
メリットとして以下の3つが考えられます。
- リッチテキスト内の珍しいタグや独自のクラス名にもCSSを当てることができる
- TailwindCSSの記法を使用できる
- 別でCSSファイルを用意する必要がない
これが最適解だと思う理由です。
1. 珍しいタグや独自のクラス名にもCSSを当てられる
これは特に、microCMS + TailwindCSSで実装している人にとっては大きいメリットだと思います。
その理由がわかりやすいように、手軽にリッチテキストにCSSを当てられると有名な「Typographyプラグイン」を使用した場合と比較します。
想定するリッチテキスト(HTML)
実際にmicroCMSのリッチテキスト内で埋め込みを使用すると以下のようなコードが生成されます。
<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;">
<iframe src="https://www.youtube.com/embed/omKyoU5Ia04?rel=0" style="top: 0; left: 0; width: 100%; height: 100%; position: absolute; border: 0;" allowfullscreen scrolling="no" allow="accelerometer;
clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;">
</iframe>
</div>
Typographyプラグインを使用した場合
Typographyプラグインでは、iframe
タグ自体にCSSを当てられない設定になっています。
よって、上記のコードにCSSを当てることができません。
CSSを当てることができるタグ(Element modifiers)は以下の公式GitHubに記載されています。
カスタムクラスを定義した場合
以下のコードのように、自分でCSSを当てたいタグも定義できるので、上記のコードにCSSを当てることが可能です。
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.prose {
@apply text-base font-bold
}
// リッチテキスト(proseクラス)内のiframeタグにcssを適応
.prose iframe {
@apply my-6
}
/* ... */
}
2. TailwindCSSの記法を使用できる
先ほど紹介した@apply
ディレクトリを使用することによって、TailwindCSSの記法をそのまま利用できます。
これによって、TailwindCSSが用意してくれている既存のCSSを適応できるため、爆速で開発ができます。
3. 別でCSSファイルを用意する必要がない
これは、TailwindCSS自体の特徴でもありますが、カスタムクラスを定義することで、独自のクラス名にも対応しつつ、module.css
などの別のCSSファイルを用意する必要もありません。
最後に
僕は、この解決に合計で1ヶ月近くかかったと思います。
なので、この記事が同じような悩みを抱える人に届けば幸いです。(そもそもTailwindCSSをしっかり理解している人はこんなことにはならないと思いますが)
また、この経験を通してTailwindCSSの可能性を実際に感じることができました。
一見、生のCSSより拡張性がないように見えますが、カスタマイズをすることによって拡張性・利便性の両方で生のCSSを凌駕できると感じました。
参考サイト
Discussion