목차
styled-components
폴더구조
- 컴포넌트 기반 구조로 각 컴포넌트에 대해 별도의 스타일 파일을 생성한다.
src/
components/
Button/
Button.tsx
Button.styles.ts
Header/
Header.tsx
Header.styles.ts
네이밍 컨벤션
파일명
- CamelCase를 사용한다.
- `Button.styles.ts`
변수명
- PascalCase를 사용하여 styled-component를 정의한다.
const PrimaryButton = styled.button`
/* styles */
`;
스타일 정의
순서 : 스타일 속성은 다음 순서대로 작성
- Positioning: position, top, right, bottom, left, z-index
- Box model: display, width, height, margin, padding, border
- Typography: font-size, font-family, text-align, line-height
- Visual: background, color, opacity
- Miscellaneous: animation, transition
클래스 이름 : BEM(Block Element Modifier) 방법론을 사용한다.
.block {}
.block__element {}
.block--modifier {}
BEM 네이밍 컨벤션
- Block
- 블록은 독립적으로 재사용 가능한 구성 요소이다.
- 블록 이름은 명사 형태로 짓는다.
- 예 : `.button`, `.card`, `.header`
- Element
- 엘리먼트는 블록의 하위 구성 요소이다.
- 블록의 일부로서만 존재한다.
- 엘리먼트는 블록 내부의 하위 요소에 스타일을 적용할 때 사용한다.
- 블록 이름과 엘리먼트 이름을 두 개의 밑줄(`__`)로 연결한다.
- 예: `.button__icon`, `.card__title`, `.header__nav
- Modifier
- Modifier는 블록이나 엘리먼트의 변형을 나타낸다.
- 블록 또는 엘리먼트 이름과 모디파이어 이름을 두 개의 하이픈(`--`)으로 연결한다.
- 예: `button--primary`, `.card__title--large`, `.header--sticky`
<!-- Block 예시 -->
<div class="button">Button</div>
<!-- Element 예시 -->
<div class="card">
<h2 class="card__title">Card Title</h2>
<p class="card__content">Card Content</p>
</div>
<!-- Modifier 예시 -->
<div class="button button--primary">Primary Button</div>
<div class="card card--highlighted">
<h2 class="card__title card__title--large">Large Title</h2>
</div>
추가 규칙
- 일관성 유지
- 클래스 이름은 모두 소문자로 작성하고, 단어는 하이픈(`-`)으로 구분한다.
- 예: `.main-header`, `.footer-nav`, `.sidebar-menu`
- 의미 있는 이름 사용
- 클래스 이름은 해당 요소의 역할과 목적을 명확히 나타내야 한다.
- 예: `.btn-submit` (좋음) vs `.btn-red` (나쁨, 스타일을 설명하는 대신 역할을 설명해야 한다)
- Avoid Over-Nesting
- 너무 깊은 중첩을 피하고, 필요할 경우 새로운 블록으로 분리한다.
- 예: `.header__nav__item__link` (나쁨) vs `.nav-item__link` (좋음)
- 재사용 가능한 클래스
- 클래스는 재사용 가능하게 작성하여, 여러 곳에서 동일한 스타일을 적용할 수 있도록 한다.
- 예: `.margin-top-small`, `.text-center`
<!-- Block -->
<div class="navbar">
<!-- Element -->
<div class="navbar__logo"></div>
<ul class="navbar__menu">
<li class="navbar__menu-item"><a href="#" class="navbar__menu-link">Home</a></li>
<li class="navbar__menu-item"><a href="#" class="navbar__menu-link">About</a></li>
<li class="navbar__menu-item"><a href="#" class="navbar__menu-link">Contact</a></li>
</ul>
<!-- Modifier -->
<div class="navbar navbar--sticky"></div>
</div>
Styled-Components 네이밍 컨벤션
- styled-components를 사용할 때도 비슷한 규칙을 적용할 수 있다. 컴포넌트 이름을 PascalCase로 작성하고, 내부 클래스 이름은 BEM 규칙을 따른다.
import styled from 'styled-components';
// Block
const Navbar = styled.nav`
/* 스타일 */
`;
// Element
const NavbarLogo = styled.div`
/* 스타일 */
`;
const NavbarMenu = styled.ul`
/* 스타일 */
`;
const NavbarMenuItem = styled.li`
/* 스타일 */
`;
const NavbarMenuLink = styled.a`
/* 스타일 */
`;
// Modifier
const StickyNavbar = styled(Navbar)`
position: sticky;
top: 0;
`;
변수 이름 : `kebab-case`를 사용한다.
--main-color: #333;
--padding-small: 8px;
예시
const PrimaryButton = styled.button`
position: relative;
display: inline-block;
width: 100px;
height: 40px;
margin: 10px;
padding: 10px;
border: 1px solid #000;
font-size: 16px;
font-family: Arial, sans-serif;
text-align: center;
line-height: 1.5;
background: #007bff;
color: #fff;
opacity: 1;
transition: background 0.3s ease;
&:hover {
background: #0056b3;
}
`;
CSS-in-JS 특성 활용
- Props 기반 스타일링 : props를 받아서 조건부 스타일을 적용한다.
interface ButtonProps {
primary?: boolean;
}
const Button = styled.button<ButtonProps>`
background: ${(props) => (props.primary ? 'blue' : 'gray')};
color: ${(props) => (props.primary ? 'white' : 'black')};
`;
중첩된 셀렉터
- 자식 요소 : 컴포넌트 내의 자식 요소에 대한 스타일을 중첩하여 정의한다.
const Card = styled.div`
padding: 20px;
border: 1px solid #ccc;
h2 {
font-size: 20px;
margin-bottom: 10px;
}
p {
font-size: 16px;
color: #666;
}
`;
테마 사용
- 테마 객체 : theme를 사용하여 공통 스타일을 관리한다.
import { ThemeProvider } from 'styled-components';
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
},
fontSizes: {
small: '12px',
medium: '16px',
large: '20px',
},
};
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>;
const ThemedButton = styled.button`
background: ${(props) => props.theme.colors.primary};
font-size: ${(props) => props.theme.fontSizes.medium};
`;
유틸리티 클래스
- 유틸리티 클래스 : 자주 사용하는 스타일 조합을 유틸리티 클래스로 정의한다.
const FlexContainer = styled.div`
display: flex;
align-items: center;
justify-content: center;
`;
반응형 디자인
- 미디어 쿼리 : 반응형 디자인을 위해 미디어 쿼리를 사용한다.
const ResponsiveDiv = styled.div`
width: 100%;
@media (min-width: 768px) {
width: 50%;
}
@media (min-width: 1024px) {
width: 25%;
}
`;
주석
- 주석 : 코드에 설명이 필요한 경우 주석을 사용한다.
const Header = styled.header`
/* Header 영역의 배경색 설정 */
background: #f8f9fa;
padding: 20px;
text-align: center;
`;
'개발 > 코드컨벤션' 카테고리의 다른 글
[Git] Github commit message 템플릿 화하기 (0) | 2024.06.22 |
---|---|
[Next.js, React] useState, useEffect 코드 컨벤션 (0) | 2024.05.23 |
TSX에서의 코드 컨벤션 (0) | 2024.05.23 |
개인 코드 컨벤션 정리 (0) | 2024.05.22 |