본문 바로가기
개발/코드컨벤션

개인 코드 컨벤션 정리 - CSS

by goodchuck 2024. 5. 23.

목차

     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 네이밍 컨벤션

    1. Block
      • 블록은 독립적으로 재사용 가능한 구성 요소이다.
      • 블록 이름은 명사 형태로 짓는다.
      • 예 : `.button`, `.card`, `.header`
    2. Element
      • 엘리먼트는 블록의 하위 구성 요소이다.
      • 블록의 일부로서만 존재한다.
      • 엘리먼트는 블록 내부의 하위 요소에 스타일을 적용할 때 사용한다.
      • 블록 이름과 엘리먼트 이름을 두 개의 밑줄(`__`)로 연결한다.
      • 예: `.button__icon`, `.card__title`, `.header__nav
    3. 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>

     

    추가 규칙

    1. 일관성 유지
      • 클래스 이름은 모두 소문자로 작성하고, 단어는 하이픈(`-`)으로 구분한다.
      • 예: `.main-header`, `.footer-nav`, `.sidebar-menu`
    2. 의미 있는 이름 사용
      • 클래스 이름은 해당 요소의 역할과 목적을 명확히 나타내야 한다.
      • 예: `.btn-submit` (좋음) vs `.btn-red` (나쁨, 스타일을 설명하는 대신 역할을 설명해야 한다)
    3. Avoid Over-Nesting
      • 너무 깊은 중첩을 피하고, 필요할 경우 새로운 블록으로 분리한다.
      • 예: `.header__nav__item__link` (나쁨) vs `.nav-item__link` (좋음)
    4. 재사용 가능한 클래스
      • 클래스는 재사용 가능하게 작성하여, 여러 곳에서 동일한 스타일을 적용할 수 있도록 한다.
      • 예: `.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;
    `;