본문 바로가기

FrontEnd/React

[React] 테일윈드CSS 리액트 프로젝트 만들기


PostCSS가 탄생한 배경

 CSS개발은 역사적으로 브라우저 호환성과 벤더 접두사 같은 문제로 어려움을 많이 겪어왔으며, 이런 어려움을  극복하기 위해 루비 언어로 만든 Sass/SCSS라는 스타일 언어가 생겨나기도 했다. 


  Sass/SCSS는 for 반복문과 같은 프로그래밍 언어를 일부 지원했고, 벤더 접두사 문제를 해결해 주는 autoprefixer 플러그인도 제공해 지금도 큰 인기를 끌고 있다.  부트스트랩을 비롯해 널리 알려진 CSS 프레임워크는 대부분 Sass/SCSS로 만들어져 있다. 


 다른 언어들도 계속 발전하듯이 CSS분야에서도 '모듈화된 CSS'라는 가치를 내걸어 PostCSS라는 이름의 새로운 스타일  언어와 이를 동작하게 하는 프로그램이 탄생하였다.

 

 PostCSS는 다양한 플러그인을 자유롭게 장착할 수 있어 CSS 표준에 추가되길 요청하는 많은 기능을 표준화 이전에 실험해 볼 수 있게 하였다.   이 과정에서 Sass/SCSS의 기능인 autoprefixer도 PostCSS 플러그인 형태로 만들었다.

 

 PostCSS는 웹 팩이 1차로 만든 CSS를 가공해 최종 CSS를 생성해 내는 방법으로 동작한다. 
즉, PostCSS는 웹팩의 플러그인이면서 그 자체는 자신의 PostCSS 플러그인을 동작시키는 프로그램이다.

 

 이 책에서 사용되는 테일윈드CSS는 PostCSS 플러그인 방식으로 동작하는 진보된 CSS 프레임워크이다.

 

테일윈드CSS 사용하기

 테일윈드CSS는 유틸리티 최우선(utility first)를 지향하는 CSS 프레임워크이다.  Utility-First란 미리 세팅된 유틸리티
클래스를 활용해 HTML 코드 내에서 스타일링함을 의미한다.  현재 테일윈드CSS는 부트스트랩과 함께 가장 많이 쓰이는  CSS 프레임워크이며 PostCSS 버전 8의 플러그인 형태로 동작한다.

 

 테일윈드 CSS는 자체적으로도 좋은 프레임워크이지만 테일윈드CSS를 바탕으로 한 약 16종의 고수준 CSS 프레임워크  가 있다는 장점이 있다.

 

 PostCSS와 autoprefixer, 그리고 테일윈드 CSS 설치하기

  CSS관점으로 브라우저 호환성 문제는 -webkit, -moz, -ms 등으로 대표되는 벤더 접두사 문제이다.  CSS 표준은 linear-   gradient이지만, 구글 크롬이나 애플 사파리 브라우저는 -webkit-linear-gradient를, 마이크로소프트 브라우저(엣지)에서는   -ms-linear-gradient와 같은 일므으로 사용해야 하는 문제이다.

 

  autoprefixer는 대표적인 PostCSS 플러그인으로 벤터 접두사 문제를 해결한다.  autoprefixer는 사용자의 CSS에 벤더 접   두사를 붙이지 않더라도 후처리 과정에서 자동으로 접두사가 붙은 CSS를 생성해준다.  postcss, autoprefixer, tailwindcss   를 설치하더라도 동작하려면 각각의 구성파일이 있어야 한다.

> npm i -D postcss autoprefixer tailwindcss

up to date, audited 1348 packages in 3s

263 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (2 moderate, 6 high)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

 

 구성 파일 만들기

  테일윈드CSS는 PostCSS의 플러그인 형태로 동작하며 PostCSS가 테일윈드CSS를 플러그인으로 동작 시키려면   postcss.config.js파일에 테일윈드CSS를 등록해야 한다.  그리고 테일윈드CSS는 PostCSS와는 별도로 자신만의 구성파   일이 있어야 한다.   하단의 명령어를 통해 tailwind.config.js, postcss.config.js가 생성된다.

> npx tailwindcss init -p

Created Tailwind CSS config file: tailwind.config.js
Created PostCSS config file: postcss.config.js
// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}

 

 daisyui 패키지 설치하기

  테일윈드CSS는 부트스트랩과 같은 CSS 프레임워크를 쉽게 개발할 수 있게 해주는 저수준(lower-level) 프레임워크이다.

 그러므로 테일윈드 CSS를 사용해 CSS 컴포넌트를 제공하는 다양한 테일윈드 CSS 컴포넌트가 있으며 플러그인 형태로   동작한다. 이중 daiyui 플러그인을 설치해 사용해보자.

> npm i -D daisyui

added 4 packages, and audited 1352 packages in 4s

264 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (2 moderate, 6 high)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

 

 @tailwindcss/line-clamp 플러그인 설치하기

  테일윈드CSS의 플러그인 이름에 '@tialwindcss/'라는 접두사가 붙은 패키지는 테일윈드CSS 제작사가 직접 만들어 제공   하는 플러그인이다.  이러한 플러그인들은 테일윈드CSS 기본에는 없는 기능을 추가로 사용할 수 있다.  line-clamp은       여러 줄의 텍슽를 지정한 줄 수 로 잘라서 표시해주는 플러그인이다.

> npm i -D @tailwindcss/line-clamp

added 1 package, and audited 1353 packages in 3s

264 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (2 moderate, 6 high)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
  // package.json에 명시된 테일윈드CSS관련 패키지들이다.
  "devDependencies": {
    "@tailwindcss/line-clamp": "^0.4.4",
    "autoprefixer": "^10.4.20",
    "daisyui": "^4.12.14",
    "postcss": "^8.4.49",
    "tailwindcss": "^3.4.15"
  }

 

 테일윈드 구성 파일 수정하기

  테일윈드 CSS기능들 중 사용하지 않는 기능은 npm run build 명령어 때 제거해 CSS 크기를 최소화 할 수 있으며   tailwind.config.js 파일에서 설정하면 된다.  또한 앞서 설치한 line-clamp, daisyui 플러그인도 등록해야 한다.

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./src/**/*.{js.jsx,ts,tsx}'],  // 어떤파일들이 tailwindcss에 유효한지 설정
  theme: {
    extend: {} // Tailwind CSS의 테마 설정을 확장
  },
  // Tailwind CSS의 플러그인 설정
  plugins: [require('@tailwindcss/line-clamp'), require('daisyui')] // 
}

 

 테일윈드CSS 기능 반영하기

  테일윈드 CSS를 사용하려면 .css에도 내용을 추가해줘야 한다.

// index.css
@tialwind base;
@tailwind components;
@tailwind utilities;
...생략...

 

 테일윈드CSS 테스트 코드 작성하기

import * as D from '../data'

export default function Tailwindcss() {
  return (
    <div className="bg-black/70">  // bg-black/70 : 바탕색을 불투명도 70%인 검정으로 설정
      <p className="w-full p-4 text-3xl text-white">Tailwindcss</p>
      // text-gray-50 : 텍스트 색상을 약간 회색빛이나는 흰색으로 표시
      <p className="italic text-gray-50 line-clamp-3">{D.randomParagraphs(10)}</p>
      // daisyui 플러그인을 통해 "btn btn-primary" 버튼 모양을 표시
      <button className="btn btn-primary" style={{textTransform: 'none'}}>
        Button
      </button>
    </div>
  )
}

line-clamp-3 : @tialwindcss/line-clamp 플러그인 css 클래스이며 텍스트가 길어도 3줄을 넘어가지 않게 한다 (... 으로 끝남)

 

색상을 설정하는 방법

 CSS는 이름에 'color'가 들어가는 몇가지 스타일 속성을 제공한다.  background-color 스타일 속성은 바탕색, color는 텍스트 색상, border-color는 HTML요소의 가장자리(경계) 색상을 의미하는 스타일 속성이다.

 

 CSS 색상 모델과 rgb, hsl 함수

  색상 표현 방법 중 가장 많이 사용되는 것은 빨간-초록-파랑으로 표현하는 RGB(red-green-blue)모델과 색상-채도-명도   형태의 실린더형 좌표로 표현하는 HSL(hue-saturation-light)모델이다.  CSS는 이 두 모델로 색상을 설정할 수 있도록     rgb와 hsl이라는 CSS 함수를 제공한다.  RGB모델은 16진수를 의미하는 '#빨강-초록-파랑' 방식으로도 표현 가능하다.

검정(black) 흰색(white) 빨강(red)
rgb(0, 0, 0)
#000000
hsl(0, 100%, 0%)
rgb(255, 255, 255)
#ffffff
hsl(0, 100%, 100%)
rgb(255, 0, 0)
#ff0000
hsl(0, 100%, 50%)

 

 CSS opacity(불투명) 스타일 속성과 rgba, hsal CSS 함수

  CSS는 색상의 불투명도를 표현하기 위해 opacity라는 이름의 속성을 제공한다.  불투명도는 알파값 0~1사이의 소수로   표현된다.  알파값이 0이면 완전이 투명함(transparency)을, 1이면 완전이 불투명함을 의미한다.

 CSS는 색상과 알파값을 동시에 표현할 수 있는 rgba, hsla라는 CSS함수도 제공한다.

// 불투명도가 40%(0.4)인 검정을 바탕색으로 설정하는 CSS 코드 예
background-color: rgba(0, 0, 0, 0.4);

 

 테일윈드 CSS 색상 클래스

  테일윈드CSS는 색상과 관련된 스타일 속성에 대응하는 색상 클래스를 제공한다.  테일윈드에서 색상의 채도 부분은 50,   100, 200, 300, 400, 500, 600, 700, 800, 900 등 10개 번호로 세분된다.  예를들어 gray-50, gray-100, gray-900과 같은     이름을 가지며 숫자가 클수록 어두운 색상이다.  불투명도는 20~100사이의 5나 10씩 증가하는 숫자로 제한한다.  
  예를들어 bg-black/20은 가장 투명한 색상인 반면, bg-black/100은 가장 불투명한 색상이다.

bg-black/70     // 접두사(background)-색상명-/불투명도
text-white      // 접두사(text)-색상명
text-gray-50/0  // 접두사(text)-색상-채도/불투명도

 

export default function Color() {
  return (
    <div className="p-4 bg-sky-700">
      <p className="w-full p-4 text-3xl text-white">Color</p>
      <div className="mb-4">
        <p className="text-white">Email address</p>
        <input type="email" className="text-gray-900 border-sky-200 border-4" />
        <p className="text-rose-500">This field is required</p>
      </div>
    </div>
  )
}

Color 컴포넌트의 실행결과

 

 텍스트를 설정하는 방법

 CSS는 길이(length)를 표현할 때 픽셀 단위(px)를 사용한다.  하지만 픽셀 단위는 '몇 글자 정도의 길이'와 같은 텍스트의 표시 길이를 표현해야 할 때는 적합하지 않다.  예를들어 '60픽셀'보다는 '문자 20개 정도의 길이'로 표현하는게 자연스럽다.

 

 따라서 CSS는 픽셀 말고도 영문자 'M'의 발음 '엠'을 의미하는 em과 'root M'을 의미하는 rem이라는 단위를 제공한다.

root M은 <html>, <body> 등에 설정된 기본 글꼴 기준으로 'M'문자의 높이를 의미한다.  즉, 1rem은 'M'문자 1개 높이, 1.25rem은 'M'문자 1개와 1/4 높이를 더한 높이이다.

 

 글자 크기 설정하기

  CSS는 텍스트 글자 크기를 설정할 수 있는 font-size와 line-height라는 스타일 속성을 제공한다.  font-size는 글꼴의         크기, 즉 글짜의 높이를 의미한다.  line-height 속성은 글짜의 높이(즉, font-size)에 여분의 높이를 더한 값을 설정한다.

  웹 브라우저는 텍스트 표시를 담당하는 <h1>~<h6>, <p>요소에 각기 다른 font-size와 line-height값을 기본으로 설정했다.

 하지만 웹 브라우저마다 기본 설정 값이 조금씩 달라 디자인한 웹 페이지가 똑같아 보이지 않는 문제가 있다.  이 때문에   테일윈드 CSS는 <h1>~<h6>, <p>요소에 기본으로 설정된 글자 크기를 모두 초기화한다.

 

 

 이 클래스들의 이름은 text-접두사 뒤에 xs, sm과 같은
줄임말을 사용하는데 이 줄임말의 의미는 사이즈이다.

 

 대다수 CSS 프레임워크에서는 'small'을 의미하는 sm, 'medium'을 의미하는 md, 'large'를 의미하는 lg와 같은      단어를 흔히 사용한다.

 CSS관점에서 모바일은 sm, 테블릿은 md크기로 고정되어 사용할 수 있다.

 

 또한 'extra small'을 의미하는 xs나 'extra-large'를 의미하는 xl도 찾아볼 수 있다.

 

 이런 단어는 디스플레이 장치, 즉 열람 중인 웹 페이지의  크기를 의미한다.

 

 

 

 

 

 

 

 

  테일 윈드 CSS의 기본 글자 크기는 text-base(font-size:1rem, line-height:1.5rem) 클래스를 기준으로 한다.  

 

 글자 굵기 설정하기

  css는 글자의 굵기(weight)를 설정할 수 있는 font-weight 스타일 속성을 제공하며, 테일윈드 CSS는 이에 대응하는           클래스인 클래스를 다음과 같이 제공한다.

 

 font-normal 클래스는 font-weight 속성값을 400으로 설정해 보통 글자 굵기이다.  400보다 낮은 숫자일수록 글자가 옅게 보이며, 400보다 높을수록    글자가 진하게 보인다.

 보통 헤드라인 텍스트는 font-bold, font-black으로 설정하여 텍스트를 강조한다.

 

 

 

 

 기울임꼴 설정하기

  CSS는 font-style이라는 스타일 속성을 제공하여 글자가 기울임꼴(italic)로 보이도록 한다.  테일윈드는 이에 대응해 클래스를 제공한다.

클래스 이름 의미
italic font-style : italic;
non-italic font-style: normal;

 

 줄바꿈 문자 설정하기

  줄바꿈 문자 \n 은 HTML에서는 화이트 스페이스(white space)로 간주되어 무시된다.  하지만 CSS에서는 white-space   스타일 속성값으로 웹 프라우저가 \n과 같은 화이트 스페이스를 어떻게 해석할지를 설정할 수 있다.  다음 표는 테일윈드CSS의 white-space 관련 클래스를 나타낸다.  이 중 \n을 줄바꿈 처리하려면 whitespace-pre-line을 사용하면 된다. 

클래스 이름 의미
whitespace-normal white-space: normal;
whitespace-nowrap white-space: nowrap;
whitespace-pre white-space: pre;
whitespace-pre-line white-space: pre-line;
whitespace-pre-wrap white-space: pre-wrap;

 

 텍스트 정렬하기

  CSS는 텍스트를 정렬하는 text-align 스타일을 제공하며, 테일윈드 CSS의 대응 클래스는 다음과 같다.

클래스 이름 의미
text-left text-align : left;
text-center text-align : center;
text-right text-align : right;
text-justify text-align : justify;

 

 텍스트 표시 줄 수 조절하기

  @tailwindcss/line-clamp에 포함된 테일윈드CSS는 'line-clamp-숫자' 형태의 클래스를 제공하고 있다.  여기서 마지막 숫자는 출력할 텍스트 줄 수이다.  line-clamp-3은 최대 3줄로 출력하고, 생략(ellipsis) 문자열(...) 이 붙는다.

 

 텍스트 관련 컴포넌트 구현하기

  테일윈드CSS의 텍스트 클래스를 그대로 사용하면 코드가 복잡해진다.  그러므로 각각의 의미에 맞게 컴포넌트를 구성하면 코드가 간결해지고 명확해질 수 있다.  Title, Subtitle, Summary, Paragraph 컴포넌트를 생성하자.

 

// textUtil.ts
// prettier-ignore
export const makeClassName = (setting: string, _className?: string, numberOfLines?: number) =>
  [setting, numberOfLines ? `line-clamp-${numberOfLines}` : '', _className].join(' ')

 

 위의 유틸리티 함수를 사용해 텍스트 관련 컴포넌트를 4개 생성하자.

import type {FC, DetailedHTMLProps, HTMLAttributes} from 'react'
import {makeClassName} from './textUtil'

type TextProps = DetailedHTMLProps<
  HTMLAttributes<HTMLParagraphElement>,
  HTMLParagraphElement
>

export type TitleProps = TextProps & {
  numberOfLines?: number
}

export const Title: FC<TitleProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-bold text-5xl text-center whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type SubTitleProps = TitleProps & {}
export const SubTitle: FC<SubTitleProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-semibold text-3xl text-center whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type SummaryProps = SubTitleProps & {}
export const Summary: FC<SummaryProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'text-sm whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type ParagraphProps = SummaryProps & {}
export const Paragraph: FC<ParagraphProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-normal text-base whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

 

그 후 index.ts 파일에 구현한 내용을 export 해줘야 한다.

export * from './Icon'
export * from './Texts'

 

마지막으로 TextsTest.tsx 컴포넌트를 작성하면 테일윈드CSS의 실행결과를 확인할 수 있다.

import * as D from '../data'
import {Title, SubTitle, Summary, Paragraph} from '../components'

const paragraphs = D.makeArray(2).map(D.randomParagraphs).join('\n\n')
const summery = D.makeArray(3).map(D.randomSentence).join('\n')

export default function TextTest() {
  return (
    <div>
      <Title>TextsTest</Title>
      <div>
        <Title className="text-blue-600">{D.randomTitleText()}</Title>
        <SubTitle className="text-blue-400">{D.randomSentence()}</SubTitle>
        <p className="text-xl italic text-center text-gray-900 text-bold">
          {D.randomName()}
        </p>
        <Paragraph numberOfLines={3}>{paragraphs}</Paragraph>
        <Summary className="text-center text-gray-500">{summery}</Summary>
        <p className="text-center text-pink-400">
          {D.randomDayMonthYear()} ({D.randomRelativeDate()})
        </p>
      </div>
    </div>
  )
}

 

실행 결과