다크모드에서 autofill 스타일이 깨지는 이유와 해결 방법
📘 Official Docs
🔍 Further Reading
문제 상황
다크모드를 적용한 로그인 페이지에서,
브라우저의 form autofill(자동완성)을 사용하면 input의 배경색이 밝아지는 문제가 발생했다.
- 다크모드일 때만 발생
- 직접 입력 시 정상
- 브라우저 추천값을 클릭 시 스타일이 깨짐
원인
브라우저가 autofill 스타일을 직접 제어한다
Chrome과 Safari는 autofill이 적용된 input에 대해,
웹사이트 CSS보다 우선순위가 높은 User Agent Stylesheet를 강제로 적용한다.
대표적인 Chrome 내부 스타일은 다음과 같다.
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 속성만을 사용한 안전한 해결책이다.
적용 코드
실제 프로젝트에서는 다음과 같이 최소한의 스타일만 오버라이드했다.
/* 브라우저 자동완성(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
- 개발자 도구 열기 (F12)
- Elements 탭에서 autofill된 input 요소 선택
- Styles 패널에서
user agent stylesheet확인
User Agent 스타일은 이탤릭체로 표시되며 직접 수정할 수 없다.
Firefox에서 확인하는 방법
about:config접속devtools.inspector.showAllAnonymousContent검색true로 설정- Inspector에서 요소의 User Agent 스타일 확인 가능
정리
- autofill 스타일의 제어권은 브라우저에 있다
- Tailwind나 React로 해결할 수 없는 영역이 존재한다.
- 이런 경우, 제어권이 어디에 있는지를 먼저 파악하는 것이 중요하다.
box-shadow inset은 브라우저 정책을 우회하지 않는 안전한 해결책이다.- 다크모드 지원 시 반드시 고려해야 할 이슈다.