Google PlaceAutocompleteElement 검은 테두리 제거하고 기존 폼 스타일 맞추는 방법
Problem
Rails 애플리케이션에서 기존 Google Places Autocomplete을 새로운 PlaceAutocompleteElement로 migration했다. 기능은 정상적으로 동작하지만, 새 컴포넌트가 Google 기본 스타일로 별도 입력 필드를 렌더링해 UI가 일관성 없이 보였다. 특히 검은색 테두리와 내부 스타일을 제거하고 기존 입력 필드와 맞추는 방법이 필요했다. 공식 문서에는 스타일링 예제가 거의 없어 해결이 어려웠다.
Background
PlaceAutocompleteElement는 Google Maps JavaScript API의 새로운 웹 컴포넌트다. 이 컴포넌트는 closed Shadow Root를 사용해 내부 요소와 스타일을 외부에서 직접 수정할 수 없도록 설계되었다. 이는 웹 컴포넌트의 캡슐화 원칙을 따르기 위한 것이지만, 기존 디자인 시스템과 통합할 때 큰 제약이 된다. 과거 legacy Autocomplete는 CSS로 쉽게 스타일링이 가능했으나, 새로운 요소는 Shadow DOM 때문에 일반적인 CSS 선택자가 먹히지 않는다. 따라서 창의적인 접근법이 필요해졌다.
Solution
1. Shadow Root를 열어 스타일 주입하기 (가장 효과적인 방법)
Google이 attachShadow를 호출할 때 mode를 강제로 “open"으로 변경하고, style 요소를 삽입하는 hack이다. 프로토타입을 오버라이드하는 방식으로 구현한다.
// Element.prototype.attachShadow를 백업합니다
const originalAttachShadow = Element.prototype.attachShadow;
// attachShadow 호출을 가로챕니다
Element.prototype.attachShadow = function (init) {
// gmp-place-autocomplete 요소인지 확인합니다
if (this.localName === "gmp-place-autocomplete") {
// mode를 open으로 강제 변경하여 Shadow DOM을 열어줍니다
const shadow = originalAttachShadow.call(this, {
...init,
mode: "open"
});
const style = document.createElement("style");
// Shadow DOM 내부에 적용할 스타일을 정의합니다
style.textContent = `
.widget-container { border: none !important; }
.input-container { padding: 0px !important; }
.focus-ring { display: none !important; }
input {
color: rgb(185 193 203);
background-color: transparent;
border: 1px solid rgb(209 213 219);
border-radius: 6px;
}
/* 드롭다운과 항목 스타일링 */
.dropdown {
background-color: #ffffff !important;
border: 1px solid rgb(209 213 219) !important;
border-radius: 6px;
}
`;
shadow.appendChild(style);
return shadow;
}
// 다른 요소는 원래 동작 유지
return originalAttachShadow.call(this, init);
};
이 코드를 PlaceAutocompleteElement를 사용하기 전에 실행하면 된다. 기존 input 필드의 테두리, 패딩, 색상과 거의 동일하게 맞출 수 있다.
2. 제한적인 CSS Properties 사용하기 (간단한 경우)
Google이 공식 지원하는 CSS 속성을 직접 적용하는 방법이다. Shadow DOM 내부까지는 영향을 주지 못하지만, 외부 컨테이너 스타일링에는 유용하다.
gmp-place-autocomplete {
background-color: #ffffff;
border: 1px solid rgb(209 213 219);
border-radius: 6px;
padding: 2px 8px;
color-scheme: light;
}
이 방법은 문서에 명시된 속성만 사용할 수 있어 자유도가 낮지만, 해킹 없이 안전하게 사용할 수 있다.
Deep Dive
Shadow DOM 오버라이드는 강력하지만 Google이 내부 구현을 변경하면 동작이 깨질 위험이 있다. 따라서 프로덕션 환경에서는 반드시 fallback 스타일을 준비해야 한다. Google은 점차 PlaceAutocompleteElement-CSS-Properties를 확대하고 있으므로, 공식 지원이 추가되는지 정기적으로 문서를 확인하는 것이 좋다. 또한 여러 PlaceAutocompleteElement를 사용하는 페이지에서는 프로토타입 오버라이드가 한 번만 적용되도록 주의해야 한다. 비슷한 상황에서 Web Component를 다룰 때는 ::part()나 CSS Custom Properties를 먼저 검토하는 습관을 들이는 것이 베스트 프랙티스다.
Conclusion
PlaceAutocompleteElement의 closed Shadow Root 때문에 스타일링이 어려웠지만, attachShadow 오버라이드를 통해 실질적인 해결이 가능하다. 간단한 스타일 변경이라면 공식 CSS Properties를, 세밀한 제어가 필요하다면 Shadow DOM 해킹을 사용하는 것을 추천한다. Google이 공식 스타일링 API를 제공할 때까지 이 접근법으로 충분히 대응할 수 있다.