[ Tailwind + Styled-components ] 2. 사용하기

angie·2023년 1월 25일
1

HTML&CSS

목록 보기
11/11

CRA환경에서 Twin 설정하기

아래 포스팅 참고
Tailwind + Styled Component 1. 세팅하기 (CRA)

Styled-components 문법 먼저 살펴보기

Tailwind와 Styled-components가 결함된 문법을 살펴보기 전에, Styled-components의 문법을 살펴보자.

기본 문법

import styled from 'styled-components';

const 스타일드컴포넌트이름 = styled.태그명`
	css스타일명 : css스타일 값; 
` 

예시

// styled-components를 import한다.
import styled from 'styled-components';

// 스타일 컴포넌트를 사용하여 <h1>태그를 렌더링하는 Title 컴포넌트 생성
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// 스타일 컴포넌트를 사용하여 <section> 태그를 렌더링하는 Wrapper 컴포넌트 생성
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// 일반 컴포넌트 사용하는 것과 동일하게 스타일 컴포넌트 사용 (다만, 스타일링 되어있음)
render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
);

셀렉터 중첩

  • SCSS 문법과 동일한 문법을 지원한다.
  • &의 의미는 상위요소를 참조하는 것
import styled from 'styled-components'

const Button = styled.button`
  font: inherit;
  padding: 0.5rem 1.5rem;
  border: 1px solid #8b005d;
  color: white;
  background: #8b005d;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
  cursor: pointer;

  &:focus {
    outline: none;
  }

  &:hover,
  &:active {
    background: #ac0e77;
    border-color: #ac0e77;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
  }
`

Tailwind + Styled-components 문법

공식문서
Styled component guide

1번 ~ 3번은 내가 직접 twin.macro를 사용하며 적응한 유용한 문법들을 정리했다.

1. SASS 문법 사용하기 (중요)

생성된 컴포넌트의 하위 요소까지 스타일링 할 수 있는 방법이다. 제일 유용한 방법.

주의할 점!

import tw from 'twin.macro'

const Wrapper = tw.div`
	flex w-full ...
	& {
		//...
	}
`

tw를 사용하면 &이 작동하지 않는다.

import tw, { styled } from 'twin.macro'

const Wrapper = styled.div`
	${tw`flex w-full ...`}

	& {
		//...
	}
`

styled를 사용하면 &이 잘 작동한다!!!!

예시

import tw, { styled, css, theme } from 'twin.macro'

const Input = styled.div`
  ${css`
    -webkit-tap-highlight-color: transparent; /* add css styles */
    background-color: ${theme`colors.red.500`}; /* add values from your tailwind config */
    ${tw`text-blue-500 border-2`}; /* tailwind classes */

    &::selection {
      ${tw`text-purple-500`}; /* style custom css selectors with tailwind classes */
    }
  `}
`

const Component = () => <Input />

꼭 템플릿 리터럴(${})안에 tw를 쓰고 백틱안에 Tailwind 유틸리티 클래스를 작성해야한다.
단점은 tailwind 자동완성이 안된다!!! ㅠㅠㅠ
자동완성 기능을 사용하고 싶다면 JSX 구문에 className으로 Tailwind를 작성하여 자동완성 기능을 활용한 뒤, Styled component로 옮기는 방법이 있다.

2. SASS 문법 + props (중요)

예시

import tw, { styled } from 'twin.macro';

const Btn = styled.div`
  ${tw`w-full rounded-full flex justify-center items-center h-6`}
  ${props =>
    props.disabled ? tw`bg-grey1 text-grey2` : tw`bg-primary text-white`}

  & {
    span {
      ${tw`text-main-bold`}
    }
  }
`;

function FormSubmitBtn({ disabled, onClick, title }) {
  return (
    <Btn disabled={disabled} onClick={onClick}>
      <span>{title ? title : '다음'}</span>
    </Btn>
  );
}

템플릿 리터럴 (${}) 안에 props을 사용할 수 있다.

3. props 응용

twin.macro의 css를 임포트하여 사용하면 props를 활용하여 CSS 구문 그대로 작성가능하다.
굉장히 유용함

import tw, { styled, css } from 'twin.macro';

const Btn = styled.div`
	${props => css`background-image: url(${img});`}
`

Function Button({ img }) {
return (
	<Btn img={img}/>
	);
}

4번부터는 깃헙 공식문서 그대로 번역하여 정리함

4. Basic Styling

1) twin.macro import

twin.macro를 컴포넌트 파일 상단에 import한다.

import tw from 'twin.macro'

2) 컴포넌트 생성

템플릿 리터럴 구문안에 Tailwind CSS의 클래스를 작성하여 스타일을 입힌다.

const Wrapper = tw.section`flex w-full`
const Column = tw.div`w-1/2`

3) 스타일링된 컴포넌트의 사용

함수형 컴포넌트가 반환하는 JSX코드에 일반 컴포넌트를 사용하는 것과 마찬가지로 태그 안에 넣어 사용한다.

const Component = () => (
	// 3. 생성한 컴포넌트를 JSX 코드에 사용
  <Wrapper>
    <Column></Column>
    <Column></Column>
  </Wrapper>
)

전체 코드

// 1. twin.macro를 import 한다.
import tw from 'twin.macro'

// 2. 'tw.tagname`tailwind css`
const Wrapper = tw.section`flex w-full`
const Column = tw.div`w-1/2`

const Component = () => (
	// 3. 생성한 컴포넌트를 JSX 코드에 사용
  <Wrapper>
    <Column></Column>
    <Column></Column>
  </Wrapper>
)

2. Conditional styling

styled를 사용하여 적용하고자 하는 스타일들을 배열에 담는다.

1) styled import

tw와 styled를 컴포넌트 파일 상단에 import한다.

import tw, { styled } from 'twin.macro'

2) 조건을 결정할 prop을 전달한다.

const Component = ({ hasBg }) => (
  <Container {...{ hasBg }}>
    <Column></Column>
    <Column></Column>
  </Container>
)

위 코드에서 hasBg라는 prop을 받아 Container라는 컴포넌트에 전달하고 있다.

3) 전달된 조건에 따라 Tailwind CSS 작성

const Container = styled.div(({ hasBg }) => [
  tw`flex w-full`, // 기본적으로 적용될 스타일을 먼저 작성한다.
  hasBg && tw`bg-black`, // 조건에 따라 추가될 스타일을 뒤에 작성한다.
])

위 코드에서 단축평가를 통해 hasBg가 True일 경우 twbg-black`` 클래스가 적용되고 있다.

전체 코드

import tw, { styled } from 'twin.macro'

const Container = styled.div(({ hasBg }) => [
  tw`flex w-full`, // Add base styles first
  hasBg && tw`bg-black`, // Then add conditional styles
])
const Column = tw.div`w-1/2`

const Component = ({ hasBg }) => (
  <Container {...{ hasBg }}>
    <Column></Column>
    <Column></Column>
  </Container>
)

3. Variants with many values

여러 변수에 스타일을 저장해놓고 사용하는 방식

1) 변수에 여러 스타일을 정의

const containerVariants = {
  light: tw`bg-white text-black`,
  dark: tw`bg-black text-white`,
  crazy: tw`bg-yellow-500 text-red-500`,
}

객체에 변수에 따른 스타일을 정의하고 있다.

2) prop을 통해 전달받은 변수로 스타일 선택

// 함수를 반환하고 있음
const Container = styled.section(() => [
  tw`flex w-full`,
  ({ variant = 'dark' }) => containerVariants[variant],
])

styled의 메서드는 함수를 반환하고 있다. 함수는 여러 스타일을 담은 배열을 반환하고 있으며, prop으로 전달받은 변수 값을 통해 객체에 담긴 스타일을 선택하고 있다.

3) 컴포넌트의 사용과 prop전달

const Component = () => (
  <Container variant="light">
    <Column></Column>
    <Column></Column>
  </Container>
)

Container라는 컴포넌트에 variant라는 prop을 보내고 있으며 그 값은 “light”이다. 이 값에 따라 containerVariants에 정의된 스타일을 선택한다.

전체 코드

import tw, { styled } from 'twin.macro'

const containerVariants = {
  // Named class sets
  light: tw`bg-white text-black`,
  dark: tw`bg-black text-white`,
  crazy: tw`bg-yellow-500 text-red-500`,
}

const Container = styled.section(() => [
  // Return a function here
  tw`flex w-full`,
  ({ variant = 'dark' }) => containerVariants[variant], // Grab the variant style via a prop
])
const Column = tw.div`w-1/2`

const Component = () => (
  <Container variant="light">
    <Column></Column>
    <Column></Column>
  </Container>
)

4. Extending components

이전에 만든 컴포넌트를 확장하여 스타일을 복사 혹은 삭제할 수 있다.

1)컴포넌트 작성

const Container = tw.div`bg-black text-white`

2) 이전에 작성한 컴포넌트를 확장

// Container 컴포넌트를 확장하여 기존 스타일에 'bg-blue-500'가 오버라이드 됨
const BlueContainer = tw(Container)`bg-blue-500`
// 조건을 추가하여 확장도 가능하다.
const RedContainer = styled(Container)(({ hasBorder }) => [
  tw`bg-red-500 text-black`,
  hasBorder && tw`border`,
])

주의 : 1번까지만 확장해서 사용하기

const BlueContainerBold = tw(BlueContainer)`font-bold`

2번 이상 확장하여 사용하는 것은 권장하지 않는다.

전체 코드

import tw, { styled } from 'twin.macro'

const Container = tw.div`bg-black text-white`

// Container 컴포넌트를 확장하여 기존 스타일에 'bg-blue-500'가 오버라이드 됨
const BlueContainer = tw(Container)`bg-blue-500`
// 조건을 추가하여 확장도 가능하다.
const RedContainer = styled(Container)(({ hasBorder }) => [
  tw`bg-red-500 text-black`,
  hasBorder && tw`border`,
])

const Component = () => (
  <>
    <Container />
    <BlueContainer />
    <RedContainer hasBorder />
  </>
)

5. Changing elements

기존에 생성한 컴포넌트를 다른 요소(h1, h2, div, a, section 등의 태그)로 재사용할 수 있다.

1) 컴포넌트 생성

import tw from 'twin.macro'

const Heading = tw.h1`font-bold`

2) 컴포넌트 사용시 as 속성 추가

const Component = () => (
  <>
    <Heading>I am a H1</Heading>
    <Heading as="h2">I am a H2 with the same style</Heading>
  </>
)

h1으로 생성한 Heading 컴포넌트가 h2태그로 재사용되고 있다.

profile
better than more

1개의 댓글

comment-user-thumbnail
2023년 1월 31일

다음 글도 부탁드릴게요 개발자님!

답글 달기