Frontend Mentor | Social media dashboard with theme switcher coding challenge
This challenge will be a perfect chance to practice your Grid skills. The color theme switcher also adds a nice additional test.
www.frontendmentor.io
- 깃헙 레포지토리: https://github.com/Ah-ae/social-media-dashboard
- 배포 링크: https://social-media-dashboard-frontend-challenge.vercel.app/
다크 모드를 구현해 보고 싶어서 sns 대쉬보드 챌린지를 선택했다. tailwind css가 다크 모드를 지원하기도 해서 연습 삼아 tailwind를 사용해봤다. tailwind를 처음 써보면서 헤맸던 부분들을 간단하게 기록해둔다.
1. border linear-gradient
인스타그램 카드에서 border에 linear-gradient를 적용해야 했다. tailwind에서는 background color만 linear-gradient를 지원하고, border에는 지원이 되지 않는다. 다른 css 스택이었다면 한 줄로 끝날 css 코드를 위해 div 박스를 두 개 만들어서 뒷배경에 gradient를 깔고 위의 박스에서 마치 border top처럼 윗부분을 제외하고 나머지는 덮는 방식으로 구현해야 했다.
참고: https://www.dhairyashah.dev/posts/how-to-create-gradient-border-with-tailwind-css/
2. 동적 스타일링
tailwind를 쓰면서 가장 불편했던 점이 동적 스타일링 코드를 작성하는 게 까다롭다는 점이었다. 방법이 아예 없는 건 아니지만 지켜야 하는 조건들이 있다.
1) 조건부로 class 명을 적을 때는 코드의 일부가 아닌 전체 코드가 다 포함되게 작성해야 한다.
2) props로 클래스명을 내리면 안 된다. 빌드 타임에 정적으로 탐지할 수 있게 props를 매핑해야 한다.
2)번이 무슨 말인고 하니, 코드를 살펴보자.
// 카드 컴포넌트
function Card({
logoPath,
type,
account,
follower,
changeType,
count,
borderTopColor,
}) {
return (
<section className="h-56 cursor-pointer">
<div className={`w-full pt-1.5 rounded-md ${borderTopColor}`}> // (*)
<div
className="w-full h-56 p-6 flex flex-col justify-between items-center rounded-b-md
bg-theme-light-lightGrayishBlue
hover:bg-theme-light-cardHoverBg
dark:bg-theme-dark-darkDesaturatedBlue dark:hover:bg-theme-dark-cardHoverBg
text-theme-light-darkGrayishBlue dark:text-theme-dark-desaturatedBlue
transition duration-500"
>
<div className="flex items-center">
<Image src={logoPath} alt={`${type} icon`} width={20} height={20} />
<span className="ml-3 text-sm font-bold">{account}</span>
</div>
<div className="flex flex-col items-center">
<span className="text-theme-light-veryDarkBlue dark:text-primary-white text-6xl font-bold">
{follower}
</span>
<span className="tracking-wide">{`${
type === "instagram"
? "SUBSCRIBERS"
: "FOLLOWERS"
}`}</span>
</div>
<TrendIndicator changeType={changeType} number={count} unit="Today" />
</div>
</div>
</section>
);
}
export default Card;
return 문에서 (*) 주석 표시를 한 라인을 보면 borderTopColor를 props로 받아서 클래스명에 넣고 있다.
// 컴포넌트 사용부
<ul className="laptop:grid laptop:grid-cols-4 laptop:gap-x-4 flex flex-col">
{socialMediaStats.map((info, idx) => (
<li key={idx} className="mb-6">
<Card
logoPath={`/icon-${info.socialMediaType}.svg`}
type={info.socialMediaType}
account={info.account}
follower={info.follower}
changeType={info.changeType}
count={info.count}
borderTopColor={info.borderTopColor}
/>
</li>
))}
</ul>
유저 정보를 로컬 데이터로 만들고, 여기에 borderColor 값도 함께 넣어서 카드 컴포넌트에 props로 보냈더니 개발자 도구에서는 분명 클래스명이 맞게 들어옴에도 불구하고 배경색이 렌더링되지 않았다.
공식문서에 나온 것처럼 정적 클래스명을 props와 매핑해주는 방식으로 컴포넌트를 수정했다.
function Card({
logoPath,
type,
account,
follower,
changeType,
count,
}) {
const colorVariants = {
facebook: "bg-sns-facebook",
twitter: "bg-sns-twitter",
instagram:
"bg-gradient-to-r from-sns-instagram-left to-sns-instagram-right",
youtube: "bg-sns-youtube",
};
return (
<section className="h-56 cursor-pointer">
<div className={`w-full pt-1.5 rounded-md ${colorVariants[type]}`}> // (*)
<div
className="w-full h-56 p-6 flex flex-col justify-between items-center rounded-b-md
bg-theme-light-lightGrayishBlue
hover:bg-theme-light-cardHoverBg
dark:bg-theme-dark-darkDesaturatedBlue dark:hover:bg-theme-dark-cardHoverBg
text-theme-light-darkGrayishBlue dark:text-theme-dark-desaturatedBlue
transition duration-500"
>
<div className="flex items-center">
<Image src={logoPath} alt={`${type} icon`} width={20} height={20} />
<span className="ml-3 text-sm font-bold">{account}</span>
</div>
<div className="flex flex-col items-center">
<span className="text-theme-light-veryDarkBlue dark:text-primary-white text-6xl font-bold">
{follower}
</span>
<span className="tracking-wide">{`${
type === "instagram"
? "SUBSCRIBERS"
: "FOLLOWERS"
}`}</span>
</div>
<TrendIndicator changeType={changeType} number={count} unit="Today" />
</div>
</div>
</section>
);
}
export default Card;
참고: https://tailwindcss.com/docs/content-configuration#dynamic-class-names
Content Configuration - Tailwind CSS
Configuring the content sources for your project.
tailwindcss.com
tailwind를 써보니 확실히 장단점이 뚜렷하다. css 스택의 세계는 장단점의 trade-off가 너무나 극명하다. 개인적으로 느낀 tailwind의 장단점은 다음과 같다.
장점
- css 파일을 따로 만들지 않아도 되고, 통상적인 클래스명에 대한 고민을 일체 하지 않아도 된다.
- 클래스명이 길어지면 조금 지저분해지긴 하지만 마크업이 비교적 한 눈에 보여서 어떻게 구성된 컴포넌트/페이지인지 눈에 쉽게 들어온다.
- 프레임워크에서 정한 규칙을 익히는데 시간이 조금 들 수 있겠지만, 기존 css 코드가 익숙하다면 크게 어렵지 않다. 손에 붙고 나면 스타일 코드 작성하는 시간이 다른 스택에 비해서 훨씬 단축될 것 같다.
- 반응형, 다크 모드 등의 구현이 쉽다.
단점
- 프레임워크다 보니 내가 원하는 모든 스타일링을 자유자재로 하기 힘들다. (border linear-gradient의 예시처럼 다른 구현 방법을 생각하거나 제3의 라이브러리를 사용해야 한다.)
- css 코드의 cascading을 파악하기가 어렵다.
- 개인 프로젝트가 아닌 협업시 위의 문제 때문에 css 충돌이 날 여지가 많아보인다.
'배워서 남 주자' 카테고리의 다른 글
import 구문을 자동 정렬할 수 있는 lint (0) | 2023.06.11 |
---|---|
프로그래머스 Lv.1 | 키패드 누르기 (JavaScript) (0) | 2023.06.08 |
redux-persist를 사용하여 새로고침 시에도 전역 상태 유지하기 (0) | 2023.05.31 |
Math.floor()와 parseInt()의 차이 (2) | 2023.05.23 |
프로그래머스 Lv.1 | 기사단원의 무기 (JavaScript) (0) | 2023.05.21 |