Skip to content

다크모드에서 autofill 스타일이 깨지는 이유와 해결 방법 ​

📘 Official Docs

문제 상황 ​

다크모드를 적용한 로그인 페이지에서,
브라우저의 form autofill(자동완성)을 사용하면 input의 배경색이 밝아지는 문제가 발생했다.

  • 다크모드일 때만 발생
  • 직접 입력 시 정상
  • 브라우저 추천값을 클릭 시 스타일이 깨짐

원인 ​

브라우저가 autofill 스타일을 직접 제어한다 ​

Chrome과 Safari는 autofill이 적용된 input에 대해,
웹사이트 CSS보다 우선순위가 높은 User Agent Stylesheet를 강제로 적용한다.

대표적인 Chrome 내부 스타일은 다음과 같다.

css
input:-internal-autofill-selected {
  background-color: rgb(232, 240, 254) !important;
  background-image: none !important;
  color: -internal-light-dark(black, white) !important;
}
  • 밝은 하늘색 배경 강제 적용
  • 텍스트 색상 강제
  • 기존 background / image 무시

이 시점부터 input 스타일의 제어권은 React나 Tailwind가 아니라 브라우저에 있다.


왜 일반 CSS로 덮어쓸 수 없을까? ​

이 스타일은 보안·UX 목적상 !important가 붙은 상태로
브라우저 내부 pseudo-class (:-internal-autofill-selected)에서 관리된다.

MDN 문서에 따르면:

많은 브라우저는 :-webkit-autofill 스타일 선언에 !important를 사용하여, JavaScript 해킹이나 브라우저 비표준 동작을 사용하지 않는 한, 일반적인 웹페이지 CSS로는 이를 직접 덮어쓸 수 없도록 설계되어 있습니다.

즉,

  • Tailwind의 bg-*, text-* 유틸리티는 결국 일반 CSS를 생성할 뿐이다.
  • 브라우저 autofill 스타일 → User Agent + !important

해결 방법: box-shadow inset 우회 ​

브라우저는 autofill 상태에서도 background-color는 강제로 제어하지만, box-shadow는 건드리지 않는다.
이를 이용해 실제 배경색을 바꾸는 대신, 아주 큰 inset box-shadow를 배경처럼 보이게 그려서 우회한다. 이 방식은 브라우저의 보안 정책을 우회하지 않고, 브라우저가 관여하지 않는 CSS 속성만을 사용한 안전한 해결책이다.


적용 코드 ​

실제 프로젝트에서는 다음과 같이 최소한의 스타일만 오버라이드했다.

css
/* 브라우저 자동완성(autofill) 스타일 오버라이드 */

@layer base {
  input:-webkit-autofill,
  input:-webkit-autofill:hover,
  input:-webkit-autofill:focus,
  textarea:-webkit-autofill,
  select:-webkit-autofill {
    /* 배경처럼 보이는 거대한 inset shadow */
    -webkit-box-shadow: 0 0 0 1000px var(--background) inset !important;
    box-shadow: 0 0 0 1000px var(--background) inset !important;
    /* 텍스트, 커서 색상 */
    -webkit-text-fill-color: var(--foreground) !important;
    caret-color: var(--foreground) !important;
    /* 배경 클리핑 */
    background-clip: content-box !important;
  }
}
  • 0 0 0 1000px: blur와 spread 없이 1000px 크기의 shadow만 생성
  • inset: 안쪽으로 그림자를 그려 배경처럼 보이게 함
  • var(--background): Tailwind나 CSS 변수를 활용해 다크/라이트 모드 대응
  • -webkit-text-fill-color: 텍스트 색상도 함께 제어해야 가독성 확보
  • !important: 브라우저의 !important와 같은 레벨로 맞춰야 함
  • background-clip: content-box는 autofill 상태에서 caret(커서) 위치나 포커스 영역이 어긋나 보이는 브라우저 렌더링 이슈를 완화하기 위해 함께 적용

이 방식은 autofill 자체를 막지 않으면서, 다크모드 기준의 배경색과 텍스트 색상을 유지할 수 있다.


autocomplete="off" ​

autocomplete="off"를 시도할 수는 있지만, Chrome/Safari가 이를 무시하는 경우가 많다고 한다.
또한 autofill은 사용자가 기대하는 기본 UX이므로, 비활성화보다는 스타일을 제어하는 것이 현실적인 선택이다.


디버깅: User Agent Styles 확인 방법 ​

Chrome DevTools ​

  1. 개발자 도구 열기 (F12)
  2. Elements 탭에서 autofill된 input 요소 선택
  3. Styles 패널에서 user agent stylesheet 확인

User Agent 스타일은 이탤릭체로 표시되며 직접 수정할 수 없다.

Firefox에서 확인하는 방법 ​

  1. about:config 접속
  2. devtools.inspector.showAllAnonymousContent 검색
  3. true로 설정
  4. Inspector에서 요소의 User Agent 스타일 확인 가능


정리

  • autofill 스타일의 제어권은 브라우저에 있다
  • Tailwind나 React로 해결할 수 없는 영역이 존재한다.
  • 이런 경우, 제어권이 어디에 있는지를 먼저 파악하는 것이 중요하다.
  • box-shadow inset은 브라우저 정책을 우회하지 않는 안전한 해결책이다.
  • 다크모드 지원 시 반드시 고려해야 할 이슈다.

마지막 업데이트 날짜: