💻 Frontend

[영문] Tailwind 101

Sep 3, 2023
얼마전 회사에서 테일윈드에 대한 기본적인 내용을 사내 동료들에게 공유했다. 테일윈드가 작동하는 원리, 다른 CSS 프레임워크와 다른 점, 그리고 사용시 주의해야할 점을 빠르게 살펴본다.
💻 Frontend
Sep 3, 2023 09:57 AM
슬리드를 만들고 있는 비브리지에서는 매주 목요일 개발자들이 모여 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?

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?

With classnames

notion image

With Tailwind CSS

출처: 애플코딩
출처: 애플코딩
  • 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

Tailwind nightmare

notion image
notion image
  • Steep learning curve
  • Hard to update and maintain
  • Bad readability
notion image

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?
  1. Designing with constraints
    1. unlike inline styles, we can use pre-defined design system that we can custom
  1. Responsive design
    1. Tailwind provides responsive utilities
  1. Hover, focus, and other states
    1. 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 between p-0 and p-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.


  • 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!


Useful tools