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은 브라우저 정책을 우회하지 않는 안전한 해결책이다.
  • 다크모드 지원 시 반드시 고려해야 할 이슈다.

마지막 업데이트 날짜: