---
title: "네이티브 select 화살표를 전 플랫폼에서 통일하기 (iOS 는 왜 양방향 화살표일까)"
description: "iOS Safari 에서만 양방향 화살표로 보이는 select 를 appearance 리셋으로 통일하고, data-uri SVG 에는 CSS 변수가 먹지 않아 DOM 오버레이를 쓰게 된 이유를 정리했습니다."
date: 2026-10-25
updated: 2026-10-25T00:16:44.368Z
tags: [css, ios-safari, design-system, accessibility]
canonical: https://blog.wooncloud.com/posts/native-select-arrow-ios-appearance
---

같은 `<select>` 마크업인데 기기마다 드롭다운 화살표 모양이 달랐습니다. 데스크톱 Chrome 과 안드로이드 Chrome 은 아래 방향 화살표(⌄)인데, iOS Safari 만 위아래 양방향 화살표(↕)였습니다.

![같은 select 마크업도 기본값은 기기마다 화살표 모양이 다르지만, appearance: none 으로 지우고 직접 그리면 전 플랫폼이 통일된다.](/images/posts/native-select-arrow-ios-appearance/d5032b34-1cc6-447c-83c9-f3a785f56a1f.webp)

코드가 틀린 건 아닙니다. 브라우저와 OS 가 native form control 을 각자 다르게 그리는 것뿐이죠. 디자인을 맞추고 싶으면 직접 그려야 합니다.

## 먼저 기본 모양부터 지웁니다

```css
select {
  appearance: none;
  -webkit-appearance: none; /* iOS Safari 의 ↕ 제거에 필수 */
  -moz-appearance: none;
  padding-right: 28px;      /* 커스텀 화살표 자리 */
}
```

`appearance: none` 이 OS 기본 화살표를 없앱니다. 그다음 화살표를 직접 얹으면 되는데, 방법이 둘입니다.

![appearance none 으로 기본 화살표를 지운 뒤 data-uri SVG 는 CSS 변수를 읽지 못해 색이 고정되고, DOM 오버레이 SVG 는 변수가 적용되어 다크모드까지 반영된다.](/images/posts/native-select-arrow-ios-appearance/f28199b7-d5ed-4d51-8c6a-0cd4ae119317.svg)

## 방법 A, background-image 에 SVG data-uri

```css
select {
  background-image: url("data:image/svg+xml,<svg ...><path stroke='%23888' .../></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
```

간단하지만 함정이 하나 있습니다. 바로 아래에서 다룹니다.

## 방법 B, DOM 오버레이

```jsx
<span style={{ position: "relative", display: "inline-flex" }}>
  <select style={{ appearance: "none", paddingRight: 28 }}>…</select>
  <ChevronDown
    style={{ position: "absolute", right: 10, top: "50%",
             transform: "translateY(-50%)", pointerEvents: "none" }}
    color="var(--icon-color)"
  />
</span>
```

`pointer-events: none` 을 줘서 화살표가 클릭을 가로채지 않게 하면 select 가 정상으로 동작합니다.

## data-uri SVG 에는 CSS 변수가 안 먹습니다

디자인 시스템이 색을 CSS 변수(`var(--c-gray)`)로 관리한다면, 방법 A 의 data-uri `stroke` 에 그 변수를 넣어도 적용되지 않습니다.

```css
/* 작동 안 함: data-uri 안의 var() 는 페이지 CSS 변수를 못 본다 */
background-image: url("data:image/svg+xml,<svg><path stroke='var(--c-gray)'/></svg>");
```

data-uri 로 불러온 SVG 는 별도 문서(resource document)라서, 임베드한 페이지의 CSS 커스텀 프로퍼티를 상속하지 않습니다. `currentColor` 도 안 먹는 경우가 많습니다.

**결국 data-uri 방식은 색을 하드코딩해야 하고, 다크모드에서 화살표만 안 바뀌는 버그로 이어집니다.**

그래서 색을 토큰이나 다크모드에 묶고 싶다면 방법 B(실제 DOM 의 인라인 SVG 오버레이)를 씁니다. 실제 DOM 요소의 `stroke` 와 `color` 는 페이지 CSS 변수를 정상적으로 해석하거든요.

## 메모

폼 컨트롤 모양이 기기마다 다르면 십중팔구 native appearance 차이입니다. `appearance: none` 으로 지우고 직접 그리면 됩니다.

화살표 색을 디자인 토큰에 묶어야 하면 DOM 오버레이로, 그 오버레이에는 `pointer-events: none` 을 잊지 않는 것까지 한 세트입니다.

## 참고

- [MDN appearance](https://developer.mozilla.org/en-US/docs/Web/CSS/appearance)
