[CSS/SCSS] className 없이 스타일 적용하는 트릭

2025. 4. 17. 21:41CSS

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

반응형

리액트를 쓰다 보면 간혹 스타일이 “왜 안 먹지?” 싶은 경험을 하게 됩니다. 최근 작업 중 실제로 겪은 사례를 정리해 보겠습니다.

 

 

이런 코드, 왜 CSS가 적용이 안 될까?

다음과 같은 구조의 React 컴포넌트가 있다고 가정해 보겠습니다

<div className={cx(styles.shortsArea)}>
  <Flag type={"shutter"} />
  <Thumbnail src={thumUrl} alt={""} />
  <div className={cx(styles.videoBox)}>
    <video ...></video>
  </div>
  <div className={cx(styles.desc)}>{description}</div>
</div>

 

여기서 Thumbnail에 스타일을 적용하고 싶은데, 아래처럼 작성한 CSS가 전혀 먹히지 않았습니다.

.thumbnail {
  bottom: 40px;
}

 

그런데 신기하게도 다음과 같이 수정하면 스타일이 정상적으로 적용됩니다.

.shortsArea {
  [class*="thumbnail"] {
    bottom: 40px;
  }
}

 

 

왜 이걸 쓰는 경우가 생기냐면…

Thumbnail 컴포넌트가 외부에서 className을 전달받지 않도록 만들어져 있을 때가 있습니다. 혹은 외부 라이브러리에서 제공하는 컴포넌트라 우리가 내부 코드를 수정할 수 없는 경우도 있죠. 또 어떤 경우엔 단순히 컴포넌트를 열어 className을 추가하는 게 번거롭거나, 프로젝트 구조상 컴포넌트 내부를 직접 건드리는 걸 피하고 싶을 때도 있습니다. 이런 상황에서는 어쩔 수 없이 트릭성 방법을 쓰게 되는데, 이 포스트에서 다룬 [class*="thumbnail"] 같은 CSS 선택자가 바로 그런 경우에 사용되는 방법입니다.

 

스타일이 안 먹는 진짜 이유

예를 들어 React 컴포넌트 Thumbnail이 외부에서 className을 전달받지 않도록 아래와 같이 정의되어 있다면, 문제가 발생할 수 있습니다. 이렇게 구성된 경우 실제 HTML로 렌더링 될 때 <img> 태그에는 클래스 속성이 포함되지 않게 되고, 그 결과 .thumbnail로 지정한 CSS도 적용되지 않습니다. 결국 스타일이 적용되지 않았던 이유는 클래스 자체가 HTML에 존재하지 않았기 때문입니다.

interface ThumbnailProps {
  src: string;
  alt: string;
}

const Thumbnail = ({ src, alt }: ThumbnailProps) => {
  return <img src={src} alt={alt} />;
};

 

그런데 CSS Modules나 styled-components를 사용하면 클래스명이 예를 들어 다음과 같이 자동 생성됩니다.

<img class="Thumbnail_thumbnail__a3Xk2" />

 

이때 [class*="thumbnail"] 선택자는 "thumbnail"이라는 문자열이 클래스명에 포함돼 있으므로, 우연히 스타일이 적용됩니다.
즉, 이건 엄밀히 말해 트릭입니다. 클래스명이 바뀌거나 컴파일 방식이 바뀌면 언제든지 깨질 수 있습니다.

 

React에서 스타일 제대로 먹이는 법

정석은 단순합니다: className을 명시적으로 넘기세요.

interface ThumbnailProps {
  src: string;
  alt: string;
  className?: string; // 👈 className 추가
}

const Thumbnail = ({ src, alt, className }: ThumbnailProps) => {
  return <img src={src} alt={alt} className={className} />;
};
 

이렇게 하면 .thumbnail 스타일이 정확하게 적용됩니다.

<Thumbnail src={thumUrl} alt="" className={styles.thumbnail} />

 

 

우연에 의존한 스타일 적용은 언젠가 깨질 폭탄입니다.
특히 CSS Modules, styled-components, tailwind 등 자동 클래스명 체계를 사용하는 경우에는 명시적인 className 전달이 필수입니다. 트릭을 알아두는 건 좋지만, 명시적이고 유지보수를 위해 항상 정석을 먼저 고려하세요.

 

 

 

 

[Terminal] nvm 설치 방법 및 오류 해결 하기

Node.js 버전을 관리하기 위해 많이 사용하는 nvm(Node Version Manager)을 설치하려 했으나, 터미널에서 nvm 명령어를 찾을 수 없다는 메시지가 출력되는 경우가 있습니다. 이번 포스팅에서는 nvm 설치 방

dev-chim.tistory.com

 

 

 

[VSCode] 초보자를 위한 VSCode 단축키 가이드: 빠르고 효율적인 개발을 위해

VSCode는 Microsoft에서 개발한 가벼우면서 강력한 오픈 소스 코드 편집기로, 다양한 플랫폼에서 널리 사용되고 있습니다. 이 글에서는 VSCode의 핵심 기능 중 하나인 단축키 설정하는 방법에 대해 다

dev-chim.tistory.com

 

 

Array APIs - indexOf(), lastIndexOf(), includes()

indexOf : 특정한 요소의 위치를 찾을 때 indexOf(searchElement: T, fromIndex?: number): number; /** * Returns the index of the first occurrence of a value in an array. * @param searchElement The value to locate in the array. * @param fromIndex Th

dev-chim.tistory.com

 

 

 

 

간단하게 Vite로 프로젝트 생성하는 방법

간단하게 Vite로 프로젝트 생성하는 방법에 대해서 알아보겠습니다. https://vitejs-kr.github.io/guide/ Vite Vite, 차세대 프런트엔드 개발 툴 vitejs-kr.github.io 선행 작업으로 node.js가 설치되어 있어야 합니다

dev-chim.tistory.com

 

 

[macOS] Mac에서 QuickTime Player로 화면 녹화하는 간단한 가이드 및 팁

Mac OS에서 기본적으로 제공되는 QuickTime Player를 사용하여 화면을 기록하는 방법에 대해 알아보겠습니다. QuickTime Player는 모든 Mac에 무료로 포함되어 있어 사용자들이 간편하게 화면을 녹화하고

dev-chim.tistory.com

 

반응형