CSSライブラリを goober から TailwindCSS に移行した
β機能である Next.js v13 app
dir で CSS in JS が Server Components で非対応という事を見落として、次の様な goober 関連のエラーに遭遇した。
![image](https://i.imgur.com/MVNxSFg.png)
Warning: CSS-in-JS is currently not supported in Server Components.
ただし、styled-jsx
と styled-components
は use client
と明記して適切な処理を加えれば Client Components (以下 CC)で動くとも書いてある。まあ取り敢えず TailwindCSS に移行することにした。同様の処理で goober やその他の CSS in JS ライブラリが動くかどうかは別レポジトリで試したい。
goober
※メモ書き
- src/styles/goober.js
- src/pages/_app.tsx
- src/pages/_document.tsx
- src/components/markdown/codeblock/copy-button.tsx
コード
goober 使用下ではこんな感じになっていた。Next.js v13 app
dir では v12 までの _app.tsx
や _document.tsx
が非対応なので、エラーを起こして当然ではある。
src/styles/goober.js
1import { createGlobalStyles } from 'goober/global'2
3export const GlobalStyles = createGlobalStyles`4 :root {5 --color-miku: #00e1ee;6 }`
src/pages/_app.tsx
1import { setup } from 'goober'2
3setup(React.createElement, prefix)4
5export default function MyApp({ Component, pageProps}: AppProps) {6 return (7 <>8 <Head />9 <GlobalStyles />10 <Component {...pageProps} />11 </>12 )13}
src/pages/_document.tsx
1import { extractCss } from "goober"2
3export default class MyDocument extends Document<{ css: string }> {4 static async getInitialProps({ renderPage }: DocumentContext) {5 const page = await renderPage()6 // Extrach the css for each page render7 const css = extractCss()8 return { ...page, css }9 }10
11 render() {12 return (13 <Html>14 <Head>15 <style16 id={'_goober'}17 // And defined it in here18 dangerouslySetInnerHTML={{ __html: ' ' + this.props.css }}19 />20 </Head>21 <body>22 <Main />23 <NextScript />24 </body>25 </Html>26 )27 }28}
src/components/markdown/codeblock/copy-button.tsx
1import { styled } from 'goober'2
3interface PasssedProps {4 code: string5}6
7interface Props extends PasssedProps {8 className?: string9}10
11const Component = ({ className, code }: Props) => (12 <button className={className}>{code}</button>13)14
15const StyledComponent = styled(Component)`16 background: var(--color-miku);17 font-weight: bold;18 padding: 0.2rem 0.5rem;19`20
21const ContainerComponent: React.FC<PasssedProps> = (props) => <StyledComponent {...props} />22
23export const Button = ContainerComponent
TailwindCSS
基本的に Install Tailwind CSS with Next.js - Tailwind CSS に倣って導入した。
1npm i -D tailwindcss postcss autoprefixer2npm i @heroicons/react3npx tailwindcss init -p4npm i -D @tailwindcss/typography sass
CSS
1@tailwind base;2@tailwind components;3@tailwind utilities;4
5@layer base {6 :root {7 --color-miku: #00e1ee;8 }9
10 .markdown {11 h2 > a::before {12 /* Safari 用のフォールバック */13 content: '## ';14 /* 読み上げ等に対しては空文字として認識させる */15 content: '## ' / '';16 }17 }18}
![リスト markdown list](https://i.imgur.com/Oo6IRT9.png)
![タイポグラフィ image](https://i.imgur.com/H7zbAsX.png)
::before
や ::after
の疑似要素や置換要素 content
などの使い方は、jxck 氏の blog.jxck.io を勝手に参考にさせてもらいました。
また、CSS の :has()
、 :is()
、 :not()
といった疑似要素をはじめて使いましたが、結構便利でした。
1figure:has(img), :not(figure) > img {2 border: 1px solid gray;3}4
5:is(figure) > img {6 border: none;7}8
9figcaption {10 text-align: center;11}
Prettier for TailwindCSS
TailwindCSS 推奨のクラス名に並べ替えるための Pretteir プラグインを利用した。
1npm i -D prettier prettier-plugin-tailwindcss
ESLint や Prettier の他のプラグインなどと違って、こちらは何の設定もなく動いた。
It works seamlessly with custom Tailwind configurations, and because it’s just a Prettier plugin, it works anywhere Prettier works — including every popular editor and IDE, and of course on the command line.
参照
- Getting Started | Next.js
- Styling: CSS-in-JS | Next.js
- oriverk/blog.oriverk.dev: blog with React + Next.js + TypeScript
- cristianbote/goober: 🥜 goober, a less than 1KB 🎉 css-in-js alternative with a familiar API
- Installation - Tailwind CSS
- Automatic Class Sorting with Prettier - Tailwind CSS
- blog.jxck.io