Life-Calendar / Styled-Components

김하은·2023년 3월 8일
4
post-thumbnail

Styled-Components 조금더 잘 쓰기

프로젝트를 시작하면서 전체적인 스타일 방식을
Styled-Components vs scss
둘중에 어떤 방식으로 사용할지 많이 고민 하였다.
다른 분들은 어떻게 쓰는지 궁금해서 검색해본 결과 이 문제로
토론을 꽤나 했었던것 같다.

=> 오래전 레딧에 이런 토론 주제가 올라온것 같은데 거의 절반 이상의 대답이
scss 를 더 선호 한다는 편이 였다.

아래 댓글을 내려가 보니, 두가지의 특징을 비교해주신 댓글이 있었다. (번역기 돌렸다.)

아직 초보자인 나는 이분이 써주신 각각의 특징을 느끼지는 못했지만,

결론적으로 내가 프로젝트를 하며 styled-componens 를 사용했던 이유는 아래와 같다.
1. react + styledcomponents 조합을 많이쓴다.
2. react 와 같은 SPA의 개발에서 html,js를 모두 기술 할수 있으며,
따라서 문서의 구조와 로직에 스타일링 코드가 같은 위치를 유지할수 있다.
3. 개발하고 있는 컴포넌트 자체에 집중할수 있다.
4. 컴포넌트 호출시 필요한 css만 호출할수 있다.

따라 , 이 글에서는 어떻게 하면 styled-components 를 더 잘 쓸수 있는지
styled-components 사용법에 대해 기록해 보았다.


📌 1. styled-component 확장

=> 새로운 element의 스타일링을 하는데 위에 만들었던 스타일 컴포넌트의 대부분의 내용을 가져와야 하는 경우가 있었다. 예를 들어 border-radius만 추가 된다거나, box-shadow만 추가 된다거나. 이 때에 그 전의 컴포넌트의 요소들을 참조하는 확장된 컴포넌트를 만들 수 있다.

수정 전 코드

const Allwrap = styled.div`
    display:flex;
    width:100vw;
`

const Memo = styled.div`
    width:300px;
    height:30px;
    position: relative;
    left: 700px;
    top: 50px;
`

const ShadowMemo = styled.div`
	width:300px;
    height:30px;
    position: relative;
    left: 700px;
    top: 50px;
    box-shadow: 2px 4px 8px;
`

funtion OnePage () {
  return(
    <>
    <Allwrap>
      <Memo>오늘 하루를 기억해보세요</Memo>
      <ShadowMemo>추억 보관함</ShadowMemo>
    </Allwrap>
    </>
  )
}

-> 다음과 같은 Memo라는 이름의 스타일 컴포넌트가 있다. 이 메모 컴포넌트에 box-shadow를 부가하고 싶을때 ShadowMemo라는 컴포넌트를 하나 더 만들어 복사 붙여넣기 후 box-shadow 요소만 추가해주면 되지만, 이렇게 쓴다면 코드길이가 늘어나 가독성이 좋지 않을것이다. 따라,
Memo와 같은 CSS를 공유한다면, 저 Memo를 확장하여 사용할 수 있을 것입니다.

수정 후 코드

const Allwrap = styled.div`
    display:flex;
    width:100vw;
`

const Memo = styled.div`
    width:300px;
    height:30px;
    position: relative;
    left: 700px;
    top: 50px;
`

const ShadowMemo = styled(Memo)`
    box-shadow: 2px 4px 8px;
`

funtion OnePage () {
  return(
    <>
    <Allwrap>
      <Memo>오늘 하루를 기억해보세요</Memo>
      <ShadowMemo>추억 보관함</ShadowMemo>
    </Allwrap>
    </>
  )
}

📌 2. 유용한 선택자 with styled-component

=> 작성된 styled-component들이 자식요소와 부모요소로 섞여 있다. css에서는 이 것을 스코프 안에 선택자 스코프로 처리를 한다. styled-component는 자식요소에 대한 select를 어떻게 할까? Container 컴포넌트 안에 있는 Box 컴포넌트에만 스타일을 추가하고 싶을 때 아래와 같은 선택자를 사용할수 있다.

수정 전 코드

const Allwrap = styled.div`
    display:flex;
    width:100vw;
`

const Memo = styled.div`
    width:300px;
    height:30px;
    position: relative;
    left: 700px;
    top: 50px;
`

const ShadowMemo = styled(Memo)`
    box-shadow: 2px 4px 8px;
`

funtion OnePage () {
  return(
    <>
    <Allwrap>
      <Memo>오늘 하루를 기억해보세요</Memo>
      <ShadowMemo>추억 보관함</ShadowMemo>
    </Allwrap>
    </>
  )
}

-> 여기서 Allwrap 컴포넌트 안에 있는 Memo컴포넌트만 background-color를 pink, color를 white로 바꿀것이다. 여기서 우리는 Allwrap의 하위요소인 Memo만을 선택해 스타일을 부가할 수 있다.

수정 된 코드


const Memo = styled.div`
    width:300px;
    height:30px;
    position: relative;
    left: 700px;
    top: 50px;
`

const Allwrap = styled.div`
    display:flex;
    width:100vw;

 ✔ ${Memo} {
      background-color:pink;
      color: white;
    }
`

const ShadowMemo = styled(Memo)`
    box-shadow: 2px 4px 8px;
`

funtion OnePage () {
  return(
    <>
    <Allwrap>
      <Memo>오늘 하루를 기억해보세요</Memo>
      <ShadowMemo>추억 보관함</ShadowMemo>
    </Allwrap>
    </>
  )
}

결과


📌 3. Styled-component의 props전달

=> 같은 h2 태그를 가진 element를 사용해야 한다. 둘 다 부제목이지만 다른 폰트 사이즈를 사용해야 한다면 어떻게 사용할 수 있을까?
물론, 같은 h2태그를 가진 styled-component를 만들어서 사용할 수도 있겠지만,
font-size만 변경하면 될 경우 우리는 font-size가 바뀔때마다 새로운 컴포넌트를 만들어야하는 불필요한 행위를 해야한다.
이런 단순 반복 작업을 피하기위해 styled-component의 props를 이용해보자.

안좋은 예

const SubTitleFont = styled.h2`
	font-size: 22px;
    font-weight: 600;
`

const SubTitleFont2 = styled.h2`
	font-size: 24px;
    font-weight: 600;

`

function Layout() => {
	return (
    	<section>
        	<SubTitleFont>Life</SubTitleFont>
            <SubTitleFont2>Calendar</SubTitleFont2>
        </section>
    )
}

-> font-size 만 다를 경우 props를 통해 font-size를 가변값으로 만들어 줄 수 있다.

수정된 옳바른 예 ⭕

const SubTitleFont = styled.h2`
	font-size: ${(props) => props.fontSize};
    font-weight: 600;
`
function Layout() => {
	return (
    	<section>
        	<SubTitleFont fontSize="22px">Life</SubTitleFont>
            <SubTitleFont fontSize="24px">Calendar</SubTitleFont2>
        </section>
    )
}

결과


-> 2px 밖에 차이가 안나지만 calendar 부분의 폰트 사이즈가 조금더 커진걸 볼수 있다.


4. styled-component.attrs

styled-component를 사용하여 이미지 태그를 가지는 태그의 스타일링을 하던 도중
동일한 alt 속성을 가지는 이미지들을 작업 중이라면, image 태그의 스타일링 만을 한 후, 컴포넌트에 alt 속성을 부여하지 않을 수 있다. 👏🏻

const ProductImage = styled.img`
    width: 100px;
    height: 100px;
`

function ProductItem() {
	return (
    	<Layout>
            <ProductImage src='https://*****' alt='제품 이미지' />
            <ProductImage src='https://*****2' alt='제품 이미지' />
            <ProductImage src='https://*****3' alt='제품 이미지' />
        </Layout>
    )
}

-> ProdImage의 component를 사용하는 이미지는 공통적으로 alt에 '제품 이미지'라는 속성을 가지고 있습니다. 이때 styled-component의 attrs를 사용할수 있다.

const ProductImage = styled.img.attrs({ alt='제품 이미지' })`
    width: 100px;
    height: 100px;
`

function ProductItem() {
	return (
    	<Layout>
            <ProductImage src='https://*****' alt='제품 이미지' />
            <ProductImage src='https://*****2' alt='제품 이미지' />
            <ProductImage src='https://*****3' alt='제품 이미지' />
        </Layout>
    )
};

-> 다음과 같이 ProdImage를 사용하는 컴포넌트들의 기본 속성 alt를 styled-component에서 선언해주어, 자동으로 ProductImage를 사용하는 컴포넌트들에 대한 속성을 줄수 있다.


📝후기

프로젝트를 하면서 기본적인 styled-components 방식만 써왔는데
프로젝트 도중 여러가지의 방법이 있다는 것을 알게 되어 적용 시켰다.
여러가지 방법에 대해 처음 접했을때 신기해 하면서 썼던 경험이 있어 끝난 후에
이렇게 기록하게 되었다. 아마, styled-components 를 쓰는 방식은 이것 뿐만 아니라 여러 방식이 있을 것이다.
이후에 차차 써 나가보면서 추가해서 기록 해야겠다.

또한, 다음 기회에는 scss 의 방식을 사용하여 두 방식에 대해 차이점을 느껴 봐야겠다. 나도

profile
꾸준함을 이기는것은 없다

1개의 댓글

comment-user-thumbnail
2023년 3월 8일

글 잘보았습니다. 스타일을 재사용할때 유용할꺼같네요 :)

답글 달기