icon안동민 개발노트

스타일링을 적용한 프로필 카드 컴포넌트 만들기


 이 실습에서는 지금까지 학습한 스타일링 기법들을 종합적으로 활용하여 반응형 프로필 카드 컴포넌트를 만들어보겠습니다.

 CSS 모듈, Styled-components, 그리고 반응형 디자인 기법을 적용하여 다양한 화면 크기에 적응하는 컴포넌트를 구현할 것입니다.

1단계 : 프로젝트 설정

 먼저 새로운 React 프로젝트를 생성하고 필요한 dependencies를 설치합니다.

npx create-react-app profile-card
cd profile-card
npm install styled-components

2단계 : 기본 컴포넌트 구조 만들기

 src 폴더에 ProfileCard.js 파일을 생성하고 기본 구조를 작성합니다.

src/ProfileCard.js
import React from 'react';
 
function ProfileCard({ name, role, avatarUrl }) {
  return (
    <div className="card">
      <img src={avatarUrl} alt={`${name}'s avatar`} className="avatar" />
      <h2>{name}</h2>
      <p>{role}</p>
    </div>
  );
}
 
export default ProfileCard;

3단계 : CSS 모듈 적용하기

 ProfileCard.module.css 파일을 생성하고 기본 스타일을 작성합니다.

src/ProfileCard.module.css
.card {
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  max-width: 300px;
  margin: 0 auto;
}
 
.avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
}

 그리고 ProfileCard.js를 수정하여 CSS 모듈을 적용합니다.

src/ProfileCard.js
import React from 'react';
import styles from './ProfileCard.module.css';
 
function ProfileCard({ name, role, avatarUrl }) {
  return (
    <div className={styles.card}>
      <img src={avatarUrl} alt={`${name}'s avatar`} className={styles.avatar} />
      <h2>{name}</h2>
      <p>{role}</p>
    </div>
  );
}
 
export default ProfileCard;

 CSS 모듈을 사용하면 스타일의 범위를 컴포넌트로 제한할 수 있어 스타일 충돌을 방지할 수 있습니다.

4단계 : Styled-components 적용하기

 이제 Styled-components를 사용하여 더 동적인 스타일링을 적용해보겠습니다.

 ProfileCard.js를 다음과 같이 수정합니다.

src/ProfileCard.js
import React from 'react';
import styled from 'styled-components';
 
const Card = styled.div`
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  max-width: 300px;
  margin: 0 auto;
  background-color: ${props => props.theme === 'dark' ? '#333' : '#fff'};
  color: ${props => props.theme === 'dark' ? '#fff' : '#333'};
`;
 
const Avatar = styled.img`
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
`;
 
const Name = styled.h2`
  margin: 16px 0 8px;
  color: ${props => props.theme === 'dark' ? '#fff' : '#000'};
`;
 
const Role = styled.p`
  margin: 0;
  color: ${props => props.theme === 'dark' ? '#ccc' : '#666'};
`;
 
function ProfileCard({ name, role, avatarUrl, theme = 'light' }) {
  return (
    <Card theme={theme}>
      <Avatar src={avatarUrl} alt={`${name}'s avatar`} />
      <Name theme={theme}>{name}</Name>
      <Role theme={theme}>{role}</Role>
    </Card>
  );
}
 
export default ProfileCard;

 Styled-components를 사용하면 props를 기반으로 동적 스타일링을 쉽게 구현할 수 있습니다.

 여기서는 theme prop을 통해 라이트/다크 테마를 전환할 수 있게 했습니다.

5단계 : 반응형 디자인 적용하기

 이제 반응형 디자인을 적용하여 다양한 화면 크기에 대응할 수 있게 만들어보겠습니다.

src/ProfileCard.js
import React from 'react';
import styled from 'styled-components';
 
const Card = styled.div`
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  max-width: 300px;
  margin: 0 auto;
  background-color: ${props => props.theme === 'dark' ? '#333' : '#fff'};
  color: ${props => props.theme === 'dark' ? '#fff' : '#333'};
 
  @media (min-width: 768px) {
    max-width: 400px;
    display: flex;
    text-align: left;
  }
`;
 
const Avatar = styled.img`
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
 
  @media (min-width: 768px) {
    margin-right: 24px;
  }
`;
 
const Info = styled.div`
  @media (min-width: 768px) {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
`;
 
const Name = styled.h2`
  margin: 16px 0 8px;
  color: ${props => props.theme === 'dark' ? '#fff' : '#000'};
 
  @media (min-width: 768px) {
    margin-top: 0;
  }
`;
 
const Role = styled.p`
  margin: 0;
  color: ${props => props.theme === 'dark' ? '#ccc' : '#666'};
`;
 
function ProfileCard({ name, role, avatarUrl, theme = 'light' }) {
  return (
    <Card theme={theme}>
      <Avatar src={avatarUrl} alt={`${name}'s avatar`} />
      <Info>
        <Name theme={theme}>{name}</Name>
        <Role theme={theme}>{role}</Role>
      </Info>
    </Card>
  );
}
 
export default ProfileCard;

 이 버전에서는 미디어 쿼리를 사용하여 화면 크기가 768px 이상일 때 레이아웃을 변경합니다.

 모바일에서는 세로로 배치되고, 태블릿 이상에서는 가로로 배치됩니다.

6단계 : 최종 컴포넌트 사용하기

 App.js에서 ProfileCard 컴포넌트를 사용해봅시다.

src/App.js
import React from 'react';
import ProfileCard from './ProfileCard';
 
function App() {
  return (
    <div>
      <ProfileCard
        name="John Doe"
        role="Software Developer"
        avatarUrl="https://example.com/avatar.jpg"
        theme="light"
      />
      <ProfileCard
        name="Jane Smith"
        role="UX Designer"
        avatarUrl="https://example.com/avatar2.jpg"
        theme="dark"
      />
    </div>
  );
}
 
export default App;

스타일링 결정의 이유와 장단점

 1. CSS 모듈 사용

  • 장점 : 스타일 범위를 컴포넌트로 제한하여 충돌을 방지합니다.
  • 단점 : 동적 스타일링이 상대적으로 어렵습니다.

 2. Styled-components로 전환

  • 장점 : Props를 기반으로 한 동적 스타일링이 용이합니다. JavaScript와 CSS를 밀접하게 결합할 수 있습니다.
  • 단점 : 러닝 커브가 있으며, 빌드 시간이 약간 증가할 수 있습니다.

 3. 테마 지원 추가

  • 장점 : 다크 모드 등 다양한 테마를 쉽게 지원할 수 있습니다.
  • 단점 : 코드가 약간 복잡해질 수 있습니다.

 4. 반응형 디자인 적용

  • 장점 : 다양한 화면 크기에 대응할 수 있어 사용자 경험이 향상됩니다.
  • 단점 : 디자인과 테스트에 더 많은 시간이 소요될 수 있습니다.

 이 실습을 통해 우리는 CSS 모듈, Styled-components, 그리고 반응형 디자인 기법을 조합하여 유연하고 재사용 가능한 프로필 카드 컴포넌트를 만들었습니다.

 이 컴포넌트는 다양한 테마와 화면 크기에 적응할 수 있으며, props를 통해 쉽게 커스터마이즈할 수 있습니다.

 실제 프로젝트에서는 이러한 기법들을 상황에 맞게 선택적으로 적용할 수 있습니다.

 예를 들어, 작은 프로젝트에서는 CSS 모듈만으로도 충분할 수 있지만, 큰 프로젝트에서는 Styled-components의 동적 스타일링 기능이 유용할 수 있습니다.

 또한, 반응형 디자인은 현대 웹 개발에서 필수적인 요소입니다. 다양한 기기에서 일관된 사용자 경험을 제공하기 위해 미디어 쿼리와 유연한 레이아웃을 적극적으로 활용해야 합니다.

 마지막으로, 스타일링 결정을 내릴 때는 항상 성능, 유지보수성, 팀의 전문성 등을 종합적으로 고려해야 합니다.

 어떤 접근 방식이 "최고"라고 말할 수는 없으며, 각 프로젝트의 요구사항에 가장 적합한 방식을 선택하는 것이 중요합니다.