tailwind + styled-components
평상시 CSS in JS 방식인 styled-components를 선호하였지만 이번 프로젝트에선 빠르게 스타일링을 할 수 있는 tailwind를 사용하기로 했다. 하지만 스타일링을 하면서 불편한 점이 있었는데 바로 동적 스타일링이었다. props에 따라 스타일을 적용해야하는 경우에는 한계가 있었고 className에 작성하면서 길어질 수록 코드 가독성 또한 떨어졌다.
그래서 tailwind와 평상시 사용하던 styled-components를 함께 사용하여 각자의 장점을 부각시킬 수 있는 방법을 찾았고 바로 twin macro
였다.
npm i -D tailwindcss
yarn add -D tailwindcss
// tailwind.config.js 폴더 최상단에 생성 후 작성
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
darkMode: 'media',
theme: {
extend: {
colors: {},
},
},
plugins: [],
};
npm i twin.macro styled-components
yarn add twin.macro styled-components
// package.json
"babelMacros": {
"twin": {
"preset": "styled-components"
}
}
npm i -D babel-plugin-styled-components babel-plugin-macros
yarn add -D babel-plugin-styled-components babel-plugin-macros
// .babelrc
{
"plugins": [
"babel-plugin-macros",
"babel-plugin-styled-components"
]
}
본인은 Vite를 사용중이었기에 따로 .babelrc
를 설정하지 않고 vite.config.ts
파일에 plugins을 넣어주었다.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react({
babel: {
plugins: ['babel-plugin-macros', 'babel-plugin-styled-components'],
},
}),
],
});
기존의 index.css 파일의 tailwind 초기 설정은 twin.macro의 BaseStyles로 대신 해줄 수 있다.
// 기존 tailwind 초기설정
@tailwind base;
@tailwind components;
@tailwind utilities;
// src/GlobalStyles.jsx
import React from 'react'
import { createGlobalStyle } from 'styled-components'
import tw, { theme, GlobalStyles as BaseStyles } from 'twin.macro'
const CustomStyles = createGlobalStyle`
body {
-webkit-tap-highlight-color: ${theme`colors.purple.500`};
${tw`antialiased`}
}
`;
const GlobalStyles = () => (
<>
<BaseStyles />
<CustomStyles />
</>
);
export default GlobalStyles;
원하는 곳에 GlobalStyles를 넣어주면된다.
// src/index.jsx
import React from 'react'
import GlobalStyles from './styles/GlobalStyles'
import App from './App'
import { createRoot } from 'react-dom/client'
const container = document.getElementById('root')
const root = createRoot(container)
root.render(
<React.StrictMode>
<GlobalStyles />
<App />
</React.StrictMode>,
)
// 혹은
// src/App.jsx
import GlobalStyles from '@/styles/GlobalStyles';
import Layout from '@/styles/Layout';
import Header from 'components/header/Header';
function App() {
return (
<>
<GlobalStyles />
<Layout $opacityCtrl={opacityCtrl}>
<Header />
</Layout>
</>
);
}
export default App;
tailwind Extension처럼 twin.macro로 Extension이 있는데 설치하면 더 편하게 사용할 수 있다.
https://marketplace.visualstudio.com/items?itemName=lightyen.tailwindcss-intellisense-twin
https://github.com/ben-rogerson/twin.examples/tree/master/cra-styled-components
사용 방식은 다양했다. 본인이 사용해 본 방식만 설명한다.
// 인라인 스타일
import tw from 'twin.macro'
const Test = () => {
return (
<div tw='flex flex-col gap-4 bg-white'>
<p tw='text-blue-400'>Test</p>
</div>
);
}
export default Test;
// styled-components 방식
import tw from 'twin.macro'
const Test = () => {
return (
<Wrapper>
<Text>Test</Text>
</Wrapper>
);
}
const Wrapper = tw.div`
flex
flex-col
gap-4
bg-white
`
const Text = tw.p`
text-blue-400
`
export default Test;
// styled-components와 함께 쓰기
// 중첩 문법을 사용할 때 편하게 사용했다.
import tw from 'twin.macro'
import styled from 'styled-components'
const Test = () => {
return (
<Wrapper>
<p>Test</p>
</Wrapper>
);
}
const Wrapper = styled.div`
${tw`flex flex-col gap-4 bg-white`}
p {
${tw`text-blue-400`}
}
`
export default Test;
// props 사용
import tw from 'twin.macro'
import styled from 'styled-components'
const Test = ({gray}) => {
return (
<Wrapper>
<p gray={gray}>Test</p>
</Wrapper>
);
}
const Wrapper = styled.div`
${tw`flex flex-col gap-4 bg-white`}
p {
${({ gray }) => gray ? tw`text-blue-500` : tw`text-red-500`}
}
`
export default Test;
Tailwind 경험이 좋았던 만큼 twin.macro도 빠르게 스타일링을 할 수 있는 점에서 굉장히 만족도가 높았고 익숙한 styled-components 문법을 그대로 사용할 수 있고 또 함께 사용할 수 있음에 만족도가 높았다. Tailwind가 더 익숙해진다면 훨씬 더 빠르고 편하게 사용할 수 있을 듯 하다.