💻 Frontend
[영문] Tailwind 101
들어가며…
슬리드를 만들고 있는 비브리지에서는 매주 목요일 개발자들이 모여 Hacker sync와 Hack Hour를 진행한다. Hacker sync에서는 한 주간 모든 hacker들에게 유의미한 정보, 이슈, 업데이트 사항을 공유하며, Hack Hour에는 새로 알게된 기술을 모두에게 소개하거나 모두에게 공유할만한 업적(?)을 논하는 시간이다. 해당 문서는 Hack Hour에서 지난 주 필자가 동료들과 공유한 내용을 담은 문서이다.
NextJS 13.4에서 App Router가 안정화 된 후, NextJS를 사용하지 않을 이유가 없는 지금, server component에서 사용할 수 있는 CSS 프레임워크 중 하나인 Tailwind를 도입하는 것에 대한 논의가 시작되었다. 이에 CSS-in-JS에 익숙해져있는 hacker들에게 Tailwind를 간단히 소개하고, 사용 시 주의사항과 Tailwind를 둘러싼 의혹(?)들을 풀어보는 시간을 가졌다.
현재는 영문으로 작성되어있으나, 추후 한국어 버전도 업데이트 하는 것을 고려하고 있다.
What is Tailwind?How does it work?How does it differ from Bootstrap?Tailwind nightmareStill need to use Tailwind?NextJS 13 and TailwindWhy not keep using Styled-components?How does Styled-components work?Things to considerPrecedence of classnamesNext…?More…?Useful toolsReferences
What is Tailwind?
Tailwind CSS is a utility-first CSS framework. It provides pre-designed classes that you can use to style your HTML elements, rather than individual components or functions.
Utility-First approach
Utility-first is a CSS methodology where you build up your styles using many small, purpose-specific classes
- has no predefined components like buttons with
btn
class like Bootstrap.
- can customize as much as you want
How does it work?
- no need to make separate css file
- no need to think about the class naming
- no need to worry that css conflicting with other styles
How does it differ from Bootstrap?
- More utility classes
- Bigger size
- But Tailwind remove unused classes when build
- No prebuild component
Tailwind nightmare
- Steep learning curve
- Hard to update and maintain
- Bad readability
Still need to use Tailwind?
- No more abandoned classnames or styles & make zero legacy code
- You can anticipate the UI just by looking at the HTML = readability isn't as bad as you think (once you get used to it)
- No naming, no stress
- No pre-made ui
- Debugging is easier
- Small bundle size
- Tailwind automatically removes all unused CSS when building for production
Why not just use inline styles?
- Designing with constraints
unlike inline styles, we can use pre-defined design system that we can custom
- Responsive design
Tailwind provides responsive utilities
- Hover, focus, and other states
Tailwind’s state variants make it easy to style
- Above all, it’s best option for NextJS 13
NextJS 13 and Tailwind
Why not keep using Styled-components?
NextJS 13 - styling in CSS-in-JS
Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React, including concurrent rendering.We're working with the React team on upstream APIs to handle CSS and JavaScript assets with support for React Server Components and streaming architecture.
The following libraries are supported in Client Components in the
app
directory (alphabetical):The following are currently working on support:
Good to know: We're testing out different CSS-in-JS libraries and we'll be adding more examples for libraries that support React 18 features and/or the app directory.
If you want to style Server Components, we recommend using CSS Modules or other solutions that output CSS files, like PostCSS or Tailwind CSS.
How does Styled-components work?
const Title = styled.h1` font-size: 1.5em; text-align: center; color: palevioletred; `;
function h1(styles) { return function NewComponent(props) { const uniqueName = generateUniqueName(styles); const createdStyles = createStylesThroughStylis(styles); createWithInjectCSSClass(uniqueName, createdStyles); return <h1 className={uniqueName} {...props} />; }; }
<style> .dKamQW { font-size: 1.5em; text-align: center; color: palevioletred; } </style> <h1 class="dKamQW">Hello World</h1>
Things to consider
Precedence of classnames
// What color should the text below be? <button class="rounded-lg p-4 text-yellow-500 text-blue-500 text-red-500">Red Text</button>
It's expected behavior. This is how html and css works, you can't change the precedence in html with the order of class-names.What matters is the specificity of css selectors and the order of declarations in the source code if the specificity is the same. Because these declarations have the same specificity (single class-names) and the.p-4
declaration is defined later than.p-0
it will be the one applied to the element.Read more about specificity: MDN Article | Specifics on CSS Specificity (CSS-Tricks)If you are trying to dynamically toggle betweenp-0
andp-4
you should always swap them out, toggle both, you shouldn't rely on css source order.
// Will the button change the text weight? ... const [isBold, setBold] = useState(false); return( <> <button className={`bg-blue-300 rounded-[8px] p-4 text-gray-50`} onClick={() => setBold(!isBold)}> Will this button change the font weight? </button> <h2 className={`mb-3 text-2xl font-${isBold ? `black` : `semibold`}`}> Text here...!!! </h2> </> ) ...
It could also be that you are trying to use dynamic class names, which won’t work because Tailwind doesn’t actually evaluate your source code and can only detect static unbroken class strings. Make sure you always use complete class names in your code.
Next…?
- When we end up with NextJS 13, we should migrate some of the styles to Tailwind.
- It’s one of the popular CSS framework, so there is no reason not to learn anyways.. ;)
- Plus, there are so many extensions and libraries to boost your productivity as well!