CSSライブラリを goober から TailwindCSS に移行した

/

β機能である Next.js v13 app dir で CSS in JS が Server Components で非対応という事を見落として、次の様な goober 関連のエラーに遭遇した。

image

Warning: CSS-in-JS is currently not supported in Server Components.

Styling: CSS-in-JS | Next.js

ただし、styled-jsxstyled-componentsuse client と明記して適切な処理を加えれば Client Components (以下 CC)で動くとも書いてある。まあ取り敢えず TailwindCSS に移行することにした。同様の処理で goober やその他の CSS in JS ライブラリが動くかどうかは別レポジトリで試したい。

goober

※メモ書き

コード

goober 使用下ではこんな感じになっていた。Next.js v13 app dir では v12 までの _app.tsx_document.tsx が非対応なので、エラーを起こして当然ではある。

src/styles/goober.js
src/styles/goober.js
import { createGlobalStyles } from 'goober/global'
export const GlobalStyles = createGlobalStyles`
:root {
--color-miku: #00e1ee;
}`
src/pages/_app.tsx
src/styles/_app.tsx
import { setup } from 'goober'
setup(React.createElement, prefix)
export default function MyApp({ Component, pageProps}: AppProps) {
return (
<>
<Head />
<GlobalStyles />
<Component {...pageProps} />
</>
)
}
src/pages/_document.tsx
src/pages/_document.tsx
import { extractCss } from "goober"
export default class MyDocument extends Document<{ css: string }> {
static async getInitialProps({ renderPage }: DocumentContext) {
const page = await renderPage()
// Extrach the css for each page render
const css = extractCss()
return { ...page, css }
}
render() {
return (
<Html>
<Head>
<style
id={'_goober'}
// And defined it in here
dangerouslySetInnerHTML={{ __html: ' ' + this.props.css }}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
src/components/markdown/codeblock/copy-button.tsx
src/components/markdown/codeblock/copy-button.tsx
import { styled } from 'goober'
interface PasssedProps {
code: string
}
interface Props extends PasssedProps {
className?: string
}
const Component = ({ className, code }: Props) => (
<button className={className}>{code}</button>
)
const StyledComponent = styled(Component)`
background: var(--color-miku);
font-weight: bold;
padding: 0.2rem 0.5rem;
`
const ContainerComponent: React.FC<PasssedProps> = (props) => <StyledComponent {...props} />
export const Button = ContainerComponent

TailwindCSS

基本的に Install Tailwind CSS with Next.js - Tailwind CSS に倣って導入した。

undefined
npm i -D tailwindcss postcss autoprefixer
npm i @heroicons/react
npx tailwindcss init -p
npm i -D @tailwindcss/typography sass

CSS

/src/styles/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--color-miku: #00e1ee;
}
.markdown {
h2 > a::before {
/* Safari 用のフォールバック */
content: '## ';
/* 読み上げ等に対しては空文字として認識させる */
content: '## ' / '';
}
}
}
markdown list
リスト
image
タイポグラフィ

::before::after の疑似要素や置換要素 content などの使い方は、jxck 氏の blog.jxck.io を勝手に参考にさせてもらいました。

また、CSS の :has():is():not() といった疑似要素をはじめて使いましたが、結構便利でした。

/src/styles/globals.scss
figure:has(img), :not(figure) > img {
border: 1px solid gray;
}
:is(figure) > img {
border: none;
}
figcaption {
text-align: center;
}

Prettier for TailwindCSS

TailwindCSS 推奨のクラス名に並べ替えるための Pretteir プラグインを利用した。

terminal
npm 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.

Automatic Class Sorting with Prettier - Tailwind CSS

参照