Tailwind CSSは本当にダメなのか
初めに
この記事ではTailwind CSSの書き方について、思うがままに書かせていただきました。
個人的見解が多分に含まれる内容となっています。
Tailwindが好きな人間なので、普通のCSSやSassを過小評価してる部分はあると思いまが、ご了承いただけたら幸いです。
Tailwindがダメと言われる理由
ちょっと前にTailwindCSSがどうだとかいう論争が起きてましたね。
私は趣味に没頭していたので、その時はあらゆる投稿に対していいねを押すマシーンと化してました。
中でも「Tailwindは負債になる」とか「Tailwindは不要」とか、デメリットが多い印象を受けましたね。
――そもそもTailwindは何が悪いのでしょうか?本当に悪いんでしょうか?
以下に、私が見かけた「Tailwindがダメ」と言われる理由を列挙します。
- クラスが大量に書かれて見づらい
- 可読性が悪い
- 覚えること多くて大変
- HTMLにCSSを持ち込むべきではない(関心の分離)
- 可読性が悪い
- なんか気に食わない
- 可読性が悪い
- styled-components最高!!!
- 可読性が悪い
- 可読...
結局のところ、可読性の悪さを指摘されることが物凄く多いように感じます。
まぁ、確かにCSSの代わりにTailwind書いたらそりゃ可読性悪くなるのは必然だと思います。
Tailwindはある種、Component指向に寄り添った代物だと思っているので、CSSの代わりに書いたらそりゃ読みにくくなると思います。
Component指向を行ったうえで扱うものだと思います。
また、Tailwindと比較してあげられるのがstyled-componentsです。
CSS-in-JS界隈ではTailwindよりもstyled-componentのほうが良いじゃないか?と言われてる印象があります。
私個人としては「どっちでもいい」と思っているのですが、
それでも、どちらが良いかを選ばなければいけない立場なら、Tailwindに軍配が上がると思っています。
何故そう思うのか、サンプルを見ながら確認していきます。
これは見にくい
まず、べた書きで書いたReact + Tailwindを見ていきます。
React + Tailwindを使った見にくい例です。を見ていきます。
import React from "react";
const Index = () => {
return (
<div className="flex items-center justify-center h-screen bg-gray-100">
<div className="w-[400px] h-[300px] flex flex-col justify-center px-4 mx-auto bg-white rounded-lg shadow-md dark:bg-gray-800">
<h1 className="mb-4 text-xl font-semibold text-gray-700 dark:text-gray-200">
Tailwind好きです
</h1>
<p className="mb-4 text-gray-600 dark:text-gray-400">好きな理由は……</p>
<button className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-500">
こちらをクリック!
</button>
</div>
</div>
);
};
export default Index;
……見にくい。
正直、初見で「これって何してる?」って聞かれたら、一発で答えられる自信は無いです。
なるほど。
確かにこういったサンプルを見せられると「Tailwind終わってんな」って思っちゃいますよね。
本来はHTML/CSSでは意味付け(セマンティックに書く)をするため、パッと分かるよう書くのが良しとされています。
例えばBEMとかだと、CSSが数個で済むようになるかと思います。
ひと先ず、CSSで書く方法見ていきましょう。
module.cssで書きます。
module.cssで書く
連続して書きます。
/* styles.module.css */
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #f7fafc;
}
.card {
width: 400px;
height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
padding: 16px;
margin: auto;
background-color: white;
border-radius: 0.5rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.23);
}
@media (prefers-color-scheme: dark) {
.card {
background-color: #2d3748;
}
}
.title {
margin-bottom: 16px;
font-size: 1.25rem;
font-weight: 600;
color: #4a5568;
}
@media (prefers-color-scheme: dark) {
.title {
color: #edf2f7;
}
}
.text {
margin-bottom: 16px;
color: #718096;
}
@media (prefers-color-scheme: dark) {
.text {
color: #a0aec0;
}
}
.button {
padding: 8px 16px;
font-size: 0.875rem;
font-weight: 500;
color: white;
background-color: #3182ce;
border-radius: 0.5rem;
transition: background-color 0.2s;
}
.button:hover {
background-color: #4299e1;
}
/** App.jsx */
import React from "react";
import styles from './styles.module.css';
const Index = () => {
return (
<div className={styles.container}>
<div className={styles.card}>
<h1 className={styles.title}>
Tailwind好きです
</h1>
<p className={styles.text}>好きな理由は……</p>
<button className={styles.button}>
こちらをクリック!
</button>
</div>
</div>
);
};
export default Index;
JSX側は見やすくなりました。
だけど、CSS側が長くて、正直管理しにくいです。
まずは、Tailwind + コンポーネント分割で、次のようにしてみます。
コンポーネント分割
上記の例の見にくさの理由は適切なコンポーネントに分割していないからです。
現代ではコンポーネント指向が主流で、適切なコンポーネントに分割することが何よりも可読性を高めると思います。
const Card = ({ children }) => (
<div className="w-[400px] h-[300px] flex flex-col justify-center px-4 mx-auto bg-white rounded-lg shadow-md dark:bg-gray-800">
{children}
</div>
);
const Title = ({ children }) => (
<h1 className="mb-4 text-xl font-semibold text-gray-700 dark:text-gray-200">
{children}
</h1>
);
const Text = ({ children }) => (
<p
className="mb-4 text-gray-600 dark:text-gray-400"
>
{children}
</p>
);
const Button = ({ children }) => (
<button
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-500"
>
{children}
</button>
);
必要なコンポーネントを抜き出しました。
これで先ほどのトップレベルの部分を見ますと、
const Index = () => {
return (
<div className="flex items-center justify-center h-screen bg-gray-100">
<Card>
<Title>Welcome to Tailwind CSS!</Title>
<Text>Lorem ipsum dolor sit amet...</Text>
<Button>Click me</Button>
</Card>
</div>
);
};
滅茶苦茶見やすくなったと思います。
これで十分だと思います。
「ん?module.cssとコンポーネント分割で良くない?」
確かに可読性においては、そうかもしれません。
ただ、私個人としては可読性だけではなく「ファイル管理」というのも保守しやすさの一つだと考えています。
わざわざmodule.cssのファイルを増やしてまでCSSを書くメリットってあるんでしょうか?
私は正直ないかなーと思っています。
そういったこともあり、一つのファイルで済む「Tailwind」または「styled-componets」のどちらかを利用したいと考えています。
また、CSSを書くようなシステムは「セマンティック」を考える意味合いも増えます。
コンポーネントに分割して、さらにそこの細かな部分に意味を見出しては名前付けします。
それって滅茶苦茶大変な作業じゃないでしょうか。
やはりCSS-in-JSでTailwindまたはstyled-componentsが良さそうです。
これで十分ですね……
と、行きたいところなんですが、これではTailwindとstyled-componentsの差があまり良く分かりません。
なので、もう少し発展していきます。
横に長くなる問題をどうするか
Cardコンポーネントを見てみます。
const Card = ({ children }) => (
<div className="w-[400px] h-[300px] flex flex-col justify-center px-4 mx-auto bg-white rounded-lg shadow-md dark:bg-gray-800">
{children}
</div>
);
横に長すぎますね。
これを見て、styled-componentの、いい例を次のように上げられることが多いです。
import styled from 'styled-components';
const Card = styled.div`
width: 400px;
height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
padding: 16px;
margin: auto;
background: white;
border-radius: 0.5rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.23);
@media (prefers-color-scheme: dark) {
background: #1a202c;
}
`;
縦に並べられて見やすいですね!
でも、これって本当にstyled-componentsだけの良さなのでしょうか?
Tailwindでも同様な可読性を求められないか、試してみましょう。
次のように修正してみます。
const Card = ({ children }) => (
<div
className={`
w-[400px] h-[300px]
px-4 mx-auto
flex flex-col justify-center
bg-white dark:bg-gray-800
rounded-lg shadow-md
`}
>
{children}
</div>
);
JSではテンプレートリテラルという構文で、上記のように改行することが可能です。
パッと見、どっちが見やすいですか?
もう一度、styled-componentsを出しましょう。
import styled from 'styled-components';
const Card = styled.div`
width: 400px;
height: 300px;
padding: 16px;
margin: auto;
display: flex;
flex-direction: column;
justify-content: center;
background: white;
border-radius: 0.5rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.23);
@media (prefers-color-scheme: dark) {
background: #1a202c;
}
`;
Tailwindに慣れてるからかもしれないのですが、私はTailwindの方が見やすいです。
何故こんな現象が起きるのかというと、単純に「文字数の差」です。
例えば横幅400pxを指定する場合、
width: 400px → 11文字
w-[400px] → 9文字
background: white → 15文字
bg-white → 8文字
こも文字数の差が積み重なることで、styled-componentsよりもTailwindのほうが見やすくなってるように私は感じます。
まとめ
ここまでTailwind好きが、色々と述べてきました。
見てくれてありがとうございます。
まとめると、
- CSS(module css)
- ファイルが増えてめんどくさい
- セマンティックがめんどくさい
- styled-components
- 文字数多い
- Tailwind
- コンポーネント化と改行さえ気を付ければ見やすい
こんな感じです。
もちろん、Tailwindにも弱点はあります。
ですが、可読性という観点では、私の中では一番いいと思えます。
皆さんはどうでしょうか?
Discussion