[프로젝트] Tailwind 공부

Jade·2022년 12월 22일
4

프로젝트

목록 보기
7/28

이번 프리 프로젝트에서 Tailwind를 사용해보기로 하고, 현재 컴포넌트 작업을 하면서 사용해보고 있는데 생각보다 효율적으로 사용하지 못하고 있는 것 같아서 공식문서를 참고해 Tailwind에 대해서 정리를 해보려고 한다.

(참고로 여기에 사용된 예시들은 대부분 Tailwind 공식 문서에서 가져왔고, 공식 문서에서는 직접 조작해볼 수 있는 예시들도 많으므로 꼭 공식 문서 예시들을 함께 참고하기를 바람!)

🕊 What is Tailwind?

Tailwind CSS works by scanning all of your HTML files, JavaScript components, and any other templates for class names, generating the corresponding styles and then writing them to a static CSS file.

Tailwind 공식 홈페이지에 소개문구는 위와 같다.
Tailwind는 클래스명으로 많은 CSS 속성과 값들을 정의하고 있고, 사용자는 해당 클래스명을 요소에 적용시켜주기만 하면 따로 CSS 파일을 조작할 필요 없이 CSS를 적용할 수 있게 된다.

현재까지 사용해본 바로는 클래스명만 입력하면 된다는 점이 편리하다는 생각이 들면서도,
적용해야하는 값들이 많아지면 클래스명이 한없이 길어져서... 이게 맞는 건가? 싶은 생각도 든다.
그래서 공식 문서를 좀 더 뜯어봐야겠다는 생각을 한 것도 있음.



✅ 설치

npm install -D tailwindcss
npx tailwindcss init

CLI로 설치를 완료하고 난 뒤에는 tailwind.config.js 파일을 생성한 뒤 아래와 같은 코드를 작성해두어야 한다.

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{html,js}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

그리고 메인으로 사용하는 CSS 파일에 아래 코드를 추가한다.
현재 하고 있는 프로젝트에서는 index.css 파일에 추가해주었다.

@tailwind base;
@tailwind components;
@tailwind utilities;


🟢 사용

🔍 원하는 속성 검색

tailwind 공식 페이지에서 검색을 통해서 속성을 찾을 수 있다.
처음에는 이런 클래스 이름들을 하나하나 찾아봐야하는 게 번거로울 수도 있지만, 곧 익숙해진다.

예를 들어서 background color를 검색하면 이렇게 이미 정의되어져 있는 클래스명들을 찾을 수 있다.

그리고 각 속성마다 함께 사용할 수 있는 속성들이 존재하므로 문서를 잘 읽어봐야 하는데,
background color는 opacity와 함께 사용할 수 있다.
아래와 같이 bg 속성 뒤에 슬래쉬를 붙이고, opacity 속성값을 붙여줄 수 있다.

<button class="bg-sky-500/100 ..."></button>
<button class="bg-sky-500/75 ..."></button>
<button class="bg-sky-500/50 ..."></button>

원하는 클래스명이 존재하면 그걸 사용하면 되지만, 만약 없는 경우 대괄호를 이용해 임시값을 지정해서 사용할 수도 있다.


🫢 Arbitrary properties

//대괄호를 이용해서 원하는 색상코드를 입력해주면 직접 background color를 조정해줄 수 있음. 
<div className="bg-[#fdf7e2]">

임시값은 내가 원하는 색상을 지정할 때, 원하는 너비나 높이, 그리고 마진이나 패딩값을 설정할 때도 사용할 수 있다.


🎨 Custom

커스텀 속성들을 일회성으로 사용할 수 있지만, 여러번 반복되고, 자주 사용되는 색 코드가 존재하면 config 파일에 커스텀을 저장해놓을 수도 있다.

//tailwind.config.js

module.exports = {
  theme: {
    screens: {
      sm: '480px',
      md: '768px',
      lg: '976px',
      xl: '1440px',
    },
    colors: {
      'blue': '#1fb6ff',
      'pink': '#ff49db',
      'orange': '#ff7849',
      'green': '#13ce66',
      'gray-dark': '#273444',
      'gray': '#8492a6',
      'gray-light': '#d3dce6',
    },
    fontFamily: {
      sans: ['Graphik', 'sans-serif'],
      serif: ['Merriweather', 'serif'],
    },
    extend: {
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      borderRadius: {
        '4xl': '2rem',
      }
    }
  }
}

위와 같이 작성하면 blue를 속성값으로 전달했을 때 #1fb6ff에 해당하는 색이 적용된다.
편리한 기능이지만, 여러 사람들이 함께 문서를 작성할 때는 동일한 이름으로 커스텀 클래스명을 작성하지 않도록 조심해야겠다는 생각이 들었다. 아니면 처음부터 자주 사용하는 색상들을 커스텀을 정해놓고 쓰면 어떨까 싶기도 함.


🖱 modifier

Tailwind로도 hover, focus와 같은 상태 속성들을 적용해줄 수 있다.

Every utility class in Tailwind can be applied conditionally by adding a modifier to the beginning of the class name that describes the condition you want to target.

내가 조정하고자 하는 상태들은 클래스명 앞에 modifier(뭐라고 해석해야 좋을지 몰라서 원어 그대로 사용)를 작성해서 적용시킬 수 있다고 한다.

//hover 상태일 때 배경색을 cyan-600으로 변경한다 
<button class="bg-cyan-500 hover:bg-cyan-600 ...">Subscribe</button>

Tailwind에는 다양한 modifier가 존재하는데 아래와 같이 분류하는듯 하다.

  • Pseudo-classes (ex: hover, :focus, :first-child, and :required)
  • Pseudo-elements (ex: ::before, ::after, ::placeholder, and ::selection)
  • Media queries, like responsive breakpoints, dark mode, and prefers-reduced-motion
  • Attribute selectors (ex: [dir="rtl"] and [open] )

아직 CSS를 사용할 때 다뤄보지도 않는 속성들도 있는듯.

이런 modifier들은 여러겹으로 겹쳐질 수도(stacked) 있는데 예를들어 '다크 모드로 바꿀 때, 중간정도의 breakpoint에 해당하고, hover 상태일 때' 특정 background-color 속성을 적용할 수 있을 것이다.

<button class="dark:md:hover:bg-fuchsia-600 ...">
  Save changes
</button>

Quick reference가 존재하므로 tailwind가 어떤 modifier를 가지고 있는지 볼 수 있다.

상태 modifier 외에도 CSS 선택자에 first-child, last-child를 붙여서 첫번째 자식요소와 마지막 자식 요소에 대해서만 어떤 속성을 설정해줄 수 있었듯이 Tailwind에서는 first, last와 같은 modifier를 사용하면 동일하게 적용이 가능하다. (이외에도 짝수번째, 홀수번째에 해당하는 자식 요소들에 대해서도 가능)

//첫번째와 마지막 자식 요소의 padding값을 제거하고 싶을 때 아래와 같이 쓸 수 있음. 
    <li class="flex py-4 first:pt-0 last:pb-0">
      <img class="h-10 w-10 rounded-full" src="{person.imageUrl}" alt="" />
      <div class="ml-3 overflow-hidden">
        <p class="text-sm font-medium text-slate-900">{person.name}</p>
        <p class="text-sm text-slate-500 truncate">{person.email}</p>
      </div>
    </li>


🤓 group, peer modifier

👩‍👩‍👧‍👦 group

group modifier는 어떤 요소의 스타일을 부모 요소의 상태에 기반해 변경시키고 싶을 때 사용할 수 있다.
부모 요소에 group이라는 클래스명을 추가하고, group-hover와 같이 자식 요소들에 사용해준다.

아래 예시는 부모 요소인 a 태그 내의 자식 요소들이 부모 요소가 hover인 경우에 해당하는 속성값이 적용되도록한 것이다.

<a href="#" class="group block max-w-xs mx-auto rounded-lg p-6 bg-white ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500">
  <div class="flex items-center space-x-3">
    <svg class="h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24">
    <h3 class="text-slate-900 group-hover:text-white text-sm font-semibold">New project</h3>
  </div>
  <p class="text-slate-500 group-hover:text-white text-sm">Create a new project from a variety of starting templates.</p>
</a>

이 group은 group/item, group/edit과 같이 뒤에 이름을 붙여서 지정할 수도 있는데, 여러 그룹들을 사용해야 할 때 유용할 것 같다. (이에대한 예시도 공식문서에서 볼 수 있음)

그룹 이름을 지정하는 것 외에도 초반부에 설명했듯이 대괄호로 arbitrary value를 사용해주면 임시의 그룹을 지정해줄 수 있는 것 같았다. 공식문서에서는 아래와 같은 예시들을 보여주고 있는데,

첫번째 예시는 is-published라는 사용자가 만든(your own selector) 셀렉터를 대괄호 사이에 넣어서 일회성 group modifier로 사용해줄 수 있다고 한다. (바로 위 group/item처럼 따로 이름을 붙이거나 하지 않아도 되어서 임시라고 하는듯?)

<div class="group is-published">
  <div class="hidden group-[.is-published]:block">
    Published
  </div>
</div>

두번째 예시는 & 기호를 사용해 group이 최종적으로 위치해야 하는 곳을 표시할 수도 있다고 하는 것 같다.

<div class="group">
  <div class="group-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>


🤼‍♂️ peer modifier

형제 요소에 기초해서 스타일링을 해야할 때는 'peer'이나 'peer-*' 형식의 modifier를 사용해서 스타일을 지정해줄 수 있다고 한다.

아래 예시에서 input과 p는 label을 부모요소로 가진 형제 요소라고 할 수 있는데,
input에 peer modifier를 주고, 이를 p 요소와 연결시켜주어서 input 요소에 정확하지 않은 이메일이 입력될 경우에 p요소(이메일을 똑바로 입력하라는 경고 문구)를 visible하게 만들어주고 있다.

<form>
  <label class="block">
    <span class="block text-sm font-medium text-slate-700">Email</span>
    <input type="email" class="peer ..."/>
    <p class="mt-2 invisible peer-invalid:visible text-pink-600 text-sm">
      Please provide a valid email address.
    </p>
  </label>
</form>

이런 방식으로 floating labels를 Js 없이도 만드는 게 가능하다고 한다.

🚫 peer modifier를 주기 전 먼저 peer를 사용해서 특정 스타일을 지정해주면 해당 스타일은 지정되지 않음

<label>
  <span class="peer-invalid:text-red-500 ...">Email</span>
  <input type="email" class="peer ..."/>
</label>

peer modifier 역시 group처럼 이름을 지정해줄 수 있고, 대괄호를 이용한 임시 peer 지정도 가능하다.

이 외에도 정말 많은 modifier들이 있으나, 한 번에 보고 다 외워서 사용하기에는 무리일 것 같고, 필요할 때마다 찾아보면서 익혀나가는 게 좋을 것 같다.



🧩 Responsive Design

반응형 웹을 만들 때 사용할 수 있는 breakpoin prefix들도 Tailwind에서는 제공하고 있다.
sm, md, lg, xl, 2xl 과 같은 클래스명이 있고, 각각 Minimum width가 자주 사용되는 화면 크기에 맞춰서 적용되어 있다.

참고


눈이 너무 뻐근해서... 일단은 여기까지 읽고, 다음에 공식문서 사용해보면서 더 알게되는 내용이 있다면 좀 더 추가해보도록 하겠다...!

profile
키보드로 그려내는 일

2개의 댓글

comment-user-thumbnail
2022년 12월 22일

프론트의 길은 멀고도 험하네요...😭

1개의 답글