[Tailwind CSS] TailwindCSS 기능 및 CSS in JS

jun gwon·2022년 11월 27일
0

TailwindCSS

목록 보기
2/3

TailwindCSS의 기능

공식문서 core-concepts
공식문서 Adding-Custom Styles

테일윈드에서 core-conepts로 소개하는것중 몇가지로, 반응형, 다크모드, Hover등의 state에 따른 style등을 사용하여 하나의 레이아웃을 만들어보겠습니다.

아래 예제에서 사용한 Card 및 Toggle 컴포넌트는 tailwinduikit 사이트를 참조하여 생성하였습니다.(추가적으로 일부 width 설정 및 애니메이션을 추가 하였습니다.)
tailwinduikit

기본적인 문법

시작에 앞서, 많이 사용되는 기본적인 TailwindCSS 문법에 대한 설명을 하자면.

  • 기본 표현관련
    1. width와 height는 w-number , h-number 등으로 표현합니다.
    2. display:flex는 TailwindCSS에서 flex 로 표현합니다.
    3. justify-content: center는 justify-center와 같이 표현합니다.
    4. h-screen과 표현에서는 screen이 의미하는 바는 100 뷰포인트 입니다.
    5. border-radius와 같은 옵션은 rounded를 통해 표현할수있습니다.
    6. space-x 기능을 사용하여, 자식 요소들간의 x축 값을 조절할수있습니다.(space-y도 가능합니다)
  • 추가 표현관련
    1. 기본으로 지원하지 않는 값을 사용하려는 경우 w-[100px]과 같이 사용할수있습니다. (컬러와 같은값도 지원합니다.)
    2. 기존 className:hover{background-black} 표현은 hover:bg-black과 같이 표현할수있습니다.
    3. 몇몇 css 셀렉터를 기본 지원합니다. first: 옵션의 경우 first-child 와 같은 효과가 있습니다.
      • 지원하지 않는 css 셀렉터를 사용하고 싶다면 [&>div]:ml-6 와 같이 대괄호안에 셀렉터를 지정하여 사용할수있습니다.
  • 반응형 관련
    • 반응형은 sm:값 md:값 lg:값 과 같이 표현할수있습니다.
      • md size(768px)이상 에서는 width가 768px이고, 그 이하에서는 width를 100%를 주려한다면 아래와 같이 작성할수있습니다.
        w-full md:w-[768px]
      • sm,md,lg 등의 반응형 사이즈를 비롯해서 여러 환경값등은 직접 커스텀 마이징 할 수 있습니다.(최상단 커스텀 문서)
  • dark모드 관련
    1. dark모드를 사용하기 위해선 tailwind.config.js 파일에 darkMode: "class", 를 추가하여야 합니다.
    2. 상위 엘리먼트가 className으로 dark를 가지고 있어야 하위엘리먼트의 dark모드가 실행됩니다.
    3. bg-white dark:bg-gray-700 과 같이 설정한다면, 기본 백그라운드값은 화이트,다크모드일때는 회색으로 변경이 됩니다.
    4. 상위 엘리먼트의 className을 지정하는 방법으로, 실제 HTML의 class 네임을 추가하는 방법과, 전체 Wrapper 엘리먼트를 만들고, className을 지정하는 방법 두가지가 있습니다.

Layout 만들기

만들어볼 Layout의 기능은 크게 3가지 입니다.
1. header / main / footer 총 3개로 영역으로 이루어져있습니다.
2. Darkmode토글 기능을 지원합니다.
3. Grid 형식으로 카드를 보여주고, 웹의 width에 따라 반응형으로 카드의 갯수를 다르게 보여줍니다.

다크모드는 HTML의 클래스를 바꾸는 형식이 아닌, 상위 Elment를 만들고 하위 컴포넌트를 구현하는 방식으로 하였습니다.

function App() {
  const [isDark, setIsDark] = useState(false);

  const toggleDarkmode = () => {
    setIsDark((prev) => !prev);
  };

  return (
    //Darkmode Wrapper
    <div className={`${isDark && "dark"}`}>
      {/* 레이아웃 wrapper */}
      <div className="flex flex-col min-h-screen h-full w-screen min-w-full dark:bg-slate-800 overflow-x-hidden">
        <header className="relative text-center h-12 border-b shadow-lg dark:text-white">
          <div>Header</div>
          <div className="flex absolute top-0 right-4">
            <Toggle toggleFn={toggleDarkmode} />
          </div>
        </header>
        {/* 레이아웃 wrapper */}
        <div className="flex-grow">
          <main className="grid grid-cols-1  md:grid-cols-3 2xl:grid-cols-4 p-4 gap-2 gap-y-4 ">
            <Card />
            <Card />
            ...
          </main>
        </div>
        <footer className="text-center h-12 border-t shadow-inner dark:text-white">
          Footer
        </footer>
      </div>
    </div>
  );
}

구현한 코드는 위와 같은 형식으로 작성하였습니다.

  1. Dark mode만을 담당하는 Wrppaer를 만들고,
    하위 엘리먼트로 header,main,footer를 담을 Wrapper를 만들었습니다.

  2. header 엘리먼트에는 relative를 사용하여 우측에 toggle 컴포넌트를 absolute를 사용하여 만들고 darkmode를 토글하는 함수를 전달하여 사용하였습니다.

  3. main에서 grid를 사용하였고, 기본값으로 1개를 보여주고, md(768xp)에서 3개를 보여주고, 2xl(1536px)에서는 4개를 보여주도록 하였습니다.
    main 영역이 나머지 전체 영역을 차지할수있도록, 상위 엘리먼트에 flex-grow를 설정하엿습니다.

  4. Card컴포넌트는 기본값을 w-full (100%)로, md사이즈에서는 448px을 사용하는 md:max-w-md 설정을 사용하였습니다.

(다크모드 사용 및 md사이즈 이상일때)

(다크모드를 사용하지 않고, md사이즈 미만일때)

tailwind-styled-components

기능자체는 크게 문제 없이 작성하지만, 이런식으로 작성하게 되면 className이 너무 길어져 한눈에 파악하기도 힘들고, 유지보수가 힘들어지게 될것입니다.

이런경우 단순히 className에 사용할 tailwind옵션들을 변수를 만들어 사용하는 방법도 있을 수 있습니다.

하지만, CSS-IN-JS 및 컴포넌트화를 지원하는 emotion 및 styled-components와 같은 컴포넌트를 tailwind에서도 사용할 수 있습니다.

이런경우 twin.macro를 사용하게 되는데, 설치 및 설정이 까다로울 수 있습니다.
때문에 이번에는 간단히 사용할 수있는 tailwind-styled-components Lib를 사용해보겠습니다.

tailwind-styled-components

yarn add -D tailwind-styled-components 를 하여 설치합니다.

사용할 컴포넌트 상단에
import tw from "tailwind-styled-components" 를 추가 합니다.

Wrppaer를 담당하는 엘리먼트를 tailwind-styled-components를 사용하여 컴포넌트화 할 경우 아래와 같습니다.

const Wrapper = tw.header`
flex 
flex-col 
min-h-screen 
h-full 
w-screen 
min-w-full 
dark:bg-slate-800 
overflow-x-hidden
`;

 사용방법..
 <Wrapper>
 ...
 </Wrapper>

CSS-IN-JS가 사용되는 Darkmode Wrapper는 아래와 같이 컴포넌트화 할 수 있습니다.

const DarkModeWrapper = tw.div`
	${(p) => (p.dark ? "dark" : "")}
`;
사용방법..
    <DarkModeWrapper dark={isDark}>
    ...
    </DarkModeWrapper>

완성 Repo

문제점

tailwind-styled-components는 확실히 기존의 styled-componets와 같이 간단하고 가볍게 사용할 수 있습니다.

하지만 TS를 사용할경우 문제가 생겨 사용하기가 매우 번거로워집니다.
1. TS를 사용할경우, tw.div와 같이 설정할 El의 타입을 적용할때, 타입을 직접 적어주어야 합니다.
2. 가장 중요한것으로, div를 비롯해 몇몇 El의 타입이 적용이 되지 않습니다. div 타입을 명시해두어도 에러가 발생합니다.
2.2 때문에 any 타입을 명시해두어야 하는데, 이럴경우 jsx의 이벤트 자동완성이 작동하지 않습니다.(onClick과 같은.., 실제 작동은 됩니다.)

이러하게 tailwind-styled-components는 JS에서는 크게 문제없이 돌아가지만, TS호환이 제대로 되지 않는 문제점들을 가지고 있습니다. any 이슈는 현재 git Issue를 통해 문제에 대해 인지하고, 곧 고쳐질것 같지만, 매 컴포넌트마다 타입을 지정하기는 매우 번거롭습니다.

때문에 이러한 문제점들을 보완한 twin.macro를 다음 글에서 설치 및 사용해보겠습니다.

0개의 댓글