가로로 흐르는 탭 줄이나 칩 목록에서 스크롤바를 숨기고 싶을 때, 채팅창 옆의 두꺼운 회색 스크롤바를 얇고 옅은 것으로 바꾸고 싶을 때, 지금까지는 이렇게 썼다.
.tabs::-webkit-scrollbar { display: none; } /* Chrome·Safari */
.tabs { -ms-overflow-style: none; } /* 옛 Edge·IE */
.tabs { scrollbar-width: none; } /* Firefox */
세 줄이 전부 같은 일을 한다. ::-webkit-scrollbar 는 표준이 아니라 WebKit 이 2009년에 넣은 의사 요소이고, Firefox 는 처음부터 지원하지 않아서 scrollbar-width·scrollbar-color 라는 표준 속성을 2018년(Firefox 64)에 따로 만들었다. 이 표준 속성을 Chrome 이 2024년 1월(121), Safari 가 scrollbar-width 는 18.2, scrollbar-color 는 26.2 에서 받으면서 세 줄이 마지막 한 줄로 합쳐진다.
이 글은 두 속성이 Safari 26.5 와 Chrome 153 에서 실제로 몇 픽셀을 만들고 무엇을 무시하는지 재 본 기록이다. 특히 표준 속성을 한 줄이라도 쓰는 순간 그 요소의 ::-webkit-scrollbar 스타일이 통째로 꺼진다는 점은 옮겨 갈 때 알고 있어야 한다.
두 속성이 하는 일
.chat-log {
scrollbar-width: thin; /* auto | thin | none */
scrollbar-color: #999 transparent; /* 썸(잡는 부분) 트랙 — 두 값 필수 */
}
값이 정말 이게 전부다. scrollbar-width 는 키워드 셋 중 하나이고 픽셀은 못 쓴다. scrollbar-color 는 썸 색과 트랙 색 두 개를 순서대로 쓰거나 auto 다. 실측에서 scrollbar-width: 12px 과 scrollbar-color: #c00(한 값)은 두 브라우저 모두 선언 자체를 버렸다 — 계산값이 auto 로 남았다.
키워드가 실제로 몇 픽셀이 되는지는 브라우저가 정한다.
scrollbar-width |
Chrome 153 | Safari 26.5 |
|---|---|---|
auto | 15px | 17px |
thin | 11px | 13px |
none | 0px | 0px |
offsetWidth - clientWidth 로 잰 값이다(마우스가 연결된 macOS 라 항상 보이는 고전 스크롤바 기준). thin 은 "4px 정도" 가 아니라 기본에서 4px 줄어드는 정도이고, 두 브라우저가 2px 다르다. 픽셀 단위로 레이아웃을 맞춰야 한다면 scrollbar-gutter: stable 로 자리를 예약하는 쪽이 맞지, 스크롤바 두께를 가정하면 안 된다.
none 은 스크롤바만 없애고 스크롤은 그대로 된다. 휠·터치·키보드·JS scrollTop 전부 동작했다. 위의 세 줄짜리 코드가 하던 일이 정확히 이것이다.
한 줄이라도 쓰면 ::-webkit-scrollbar 는 전부 꺼진다
여기가 옮길 때 걸리는 자리다. 같은 요소에 두 방식을 섞어 보았다.
/* 기존 코드 */
.box::-webkit-scrollbar { width: 30px; background: #0f0; }
/* 색만 표준으로 바꿔 보자 — 하고 한 줄 추가 */
.box { scrollbar-color: #c00 #fdd; }
| 선언 | Chrome | Safari |
|---|---|---|
::-webkit-scrollbar 30px 만 | 30px, 초록 | 30px, 초록 |
위 + scrollbar-color | 15px, 빨강/분홍 | 17px, 빨강/분홍 |
scrollbar-color 한 줄을 넣자 30px 이 기본 두께로 돌아가고 초록도 사라졌다. 색만 바꾼 게 아니라 ::-webkit-scrollbar 계열 규칙 전체가 무효가 된 것이다. 스펙이 그렇게 정해 두었고(표준 속성이 auto 가 아니면 비표준 의사 요소를 무시한다) 두 브라우저가 똑같이 따른다.
그러니 요소 단위로 둘 중 하나만 골라야 한다. 기존 ::-webkit-scrollbar 스타일이 둥근 모서리·호버 색·화살표 버튼 숨김처럼 표준 속성이 못 하는 것을 하고 있다면, 그 요소에는 표준 속성을 한 줄도 넣지 말고 그대로 둔다. 두께와 두 가지 색으로 충분한 요소만 옮긴다. "일단 scrollbar-width: thin 만 추가해 보자" 가 기존 디자인을 통째로 날린다.
색은 상속되고 두께는 상속되지 않는다
스크롤 영역 안에 또 스크롤 영역이 있는 경우(채팅창 안의 코드 블록, 모달 안의 표)를 재 봤다.
.outer { scrollbar-color: #c00 #fdd; } → 안쪽 스크롤 영역도 빨강/분홍
.outer { scrollbar-width: thin; } → 안쪽은 그대로 기본 두께
scrollbar-color 는 상속 속성이라 :root 나 body 에 한 번 쓰면 페이지의 모든 스크롤바 색이 바뀐다. scrollbar-width 는 상속되지 않아서 얇게 만들 요소마다 써야 한다. 사이트 전체 스크롤바를 얇게 하려면 * { scrollbar-width: thin } 처럼 전체 선택자가 필요하다는 뜻이다. 두 속성의 상속 여부가 다르다는 것을 모르면 "왜 안쪽 것만 두껍지" 하고 헤맨다.
다크 모드는 색을 안 적어도 된다
다크 테마에서 스크롤바가 하얗게 튀는 문제는 scrollbar-color 없이도 풀린다. color-scheme: dark 를 선언하면 브라우저가 폼 컨트롤과 함께 기본 스크롤바를 어두운 것으로 바꾼다. 이 방식은 ::-webkit-scrollbar 도 무효화하지 않는다. 색을 정확히 맞춰야 할 때만 scrollbar-color 를 쓰고, "어두운 배경에 어두운 스크롤바" 정도면 color-scheme 이 짧고 부작용도 없다.
:root { color-scheme: light dark; } /* OS 설정 따라 스크롤바도 바뀜 */
/* 색을 꼭 맞춰야 하면 */
:root { scrollbar-color: light-dark(#bbb, #555) light-dark(#f2f2f2, #222); }
모바일에서 실제로 쓰는 자리
iOS Safari 와 Android Chrome 은 스크롤바가 원래 오버레이라 자리를 차지하지 않고 스크롤 중에만 잠깐 보인다. 그래서 모바일에서 이 속성이 필요한 곳은 사실상 하나다 — 가로 스크롤 줄에서 스크롤바를 아예 안 보이게 하는 것. 탭 줄, 카테고리 칩, 카드 캐러셀에서 스크롤할 때마다 아래에 가는 막대가 나타나는 걸 없애는 용도다.
.chips {
display: flex;
overflow-x: auto;
scrollbar-width: none; /* 세 줄이던 것이 이 한 줄 */
}
Safari 18.2 미만이 남아 있다면 ::-webkit-scrollbar { display: none } 을 같이 두어도 된다. 표준 속성을 아는 브라우저는 표준 쪽을 따르고 의사 요소를 무시하며, 모르는 브라우저는 의사 요소만 읽는다. 결과가 같은 "숨김" 이라 이 경우만은 섞어 써도 충돌이 없다.
숨길 때 한 가지는 챙겨야 한다. 스크롤바가 없으면 더 있다는 표시도 없어진다. 마지막 항목을 반쯤 잘리게 배치하거나 오른쪽 끝에 그라데이션을 깔아 "옆으로 더 있음" 을 다른 방식으로 알려 줘야 한다. 마우스만 있는 데스크톱 사용자는 가로 스크롤바가 없으면 Shift+휠을 모르는 한 스크롤할 방법이 없으니, 데스크톱에서는 thin 에서 멈추는 편이 안전하다.
정리
scrollbar-width(auto·thin·none)와 scrollbar-color(썸 트랙 두 값)가 Chrome 121·Safari 18.2/26.2 에서 되면서, 스크롤바를 숨기거나 얇게 하는 세 줄짜리 코드가 표준 한 줄로 줄어든다. thin 은 Chrome 11px·Safari 13px 로 브라우저마다 다르고, none 은 스크롤 기능은 남긴 채 막대만 없앤다.
옮길 때 규칙은 하나다 — 요소 하나에 표준 속성과 ::-webkit-scrollbar 를 섞지 않는다. 표준 속성이 한 줄이라도 있으면 의사 요소 스타일은 전부 무시된다. 둥근 모서리나 호버 색이 필요한 요소는 옛 방식 그대로 두고, 두께와 색 두 가지면 되는 요소만 옮긴다. 색은 상속되고 두께는 안 되며, 다크 모드는 color-scheme 이 먼저다.