공용 CSS 클래스 이름 하나가 두 게임의 '나가기' 창을 망가뜨렸습니다 — .sheet 충돌기
두더지 잡기에서 '나가기/계속하기' 버튼이 왼쪽으로 쏠리고, 가위바위보에서는 같은 창이 화면 가운데로 끌려와 아래가 잘렸습니다. 원인은 게임 화면의 시트와 공용 UI 패키지의 확인 창이 같은 클래스 이름 .sheet 를 쓴 것이었습니다. 찾은 과정과 고친 방법, 그리고 같은 이름이 남은 곳
10월 2일, 사용자 제보가 하나 들어왔습니다. 두더지 잡기에서 게임 도중 뒤로 가기를 누르면 “나가시겠어요?” 창이 뜨는데, 버튼 두 개가 왼쪽으로 쏠려 있다는 내용이었습니다. 다음 날에는 가위바위보에서 같은 창이 화면 가운데로 끌려와 아래가 잘려 보이는 걸 찾았습니다.
두 게임 모두 그 창을 직접 만들지 않습니다. 창은 공용 UI 패키지가 띄우는데, 게임마다 다르게 망가졌습니다.
같은 창, 두 게임, 두 가지 모양
제 게임들은 저장소 하나(모노레포)에 들어 있고, 화면 부품은 공용 패키지(@mini/ui)를 같이 씁니다. 게임 도중 뒤로 가기를 누르면 나오는 나가기 확인 창도 그중 하나입니다. 이 창은 HTML로 이렇게 만들어집니다.
1
2
3
<div class="sheet">
<div class="sheet-body"> … 나가기 / 계속하기 … </div>
</div>
그런데 두 게임에도 각자 .sheet라는 이름의 화면 조각이 있었습니다.
- 두더지 잡기: 시간이 다 되면 “광고 보고 15초 더 하기”를 묻는 시트. 그 안의 버튼 폭을 줄이는 규칙
.sheet .btn { width: min(80%, 260px); }이 있었습니다. - 가위바위보: 지면 “부활하기”를 묻는 시트.
.sheet { position: absolute; … }로 판 한가운데에 띄웠습니다.
CSS는 클래스 이름만 보고 규칙을 붙입니다. 누가 만든 요소인지는 따지지 않습니다. 그래서 공용 확인 창이 뜨는 순간, 그 게임의 .sheet 규칙이 확인 창에도 그대로 적용됐습니다. 두더지 잡기에서는 버튼 폭 규칙이 붙어 버튼이 줄어들며 왼쪽으로 쏠렸고, 가위바위보에서는 위치 규칙이 붙어 창이 가운데로 끌려왔습니다. 같은 원인이 게임마다 다른 증상으로 나타난 겁니다.
고친 방법
게임 쪽 시트의 이름을 각자 고유하게 바꿨습니다.
- 두더지 잡기:
.sheet→.extend-sheet - 가위바위보:
.sheet→.lost-sheet
HTML의 클래스 이름과 CSS 규칙만 바꾸면 끝입니다. 화면 코드는 요소를 클래스가 아니라 id로 찾고 있어서 건드릴 게 없었습니다. 그리고 다음 사람이 같은 실수를 하지 않게 CSS 주석에 “공용 .sheet와 이름을 겹치지 말 것, 이유는 이것”을 적어 두었습니다.
같은 이름이 더 있었다
두 게임만 그럴 리 없다고 보고 저장소 전체를 검색했습니다. 클래스 이름이 정확히 .sheet인 규칙을 가진 게임이 두 개 더 나왔습니다. 헤드리스 브라우저로 직접 띄워 확인해 보니 두 곳 모두 ‘지금은 멀쩡한’ 이유가 따로 있었습니다.
- 순서 기억: 뒤로 가기를 누르면 확인 창이 실제로 뜨고, 게임의
.sheet규칙도 그대로 붙습니다. 그런데도 모양이 멀쩡했던 건 공용 확인 창의 스타일이 원래 이 게임에서 복사해 간 것이라 값이 똑같았기 때문입니다. 어느 한쪽만 고치는 순간 깨지는 상태였습니다. - 타로: ‘판 진행 중’ 화면이 없어서 확인 창이 아예 뜨지 않습니다. 같은 창을 억지로 띄워 보면 화면 가운데 떠 있는 상자로 바뀌었습니다.
증상은 없었지만 둘 다 이름을 바꿔 두었습니다(.again-sheet, .heart-sheet). 고장 난 뒤에 고치는 것보다 지금이 훨씬 쌉니다.
.sheet-box처럼 .sheet로 시작하는 이름은 걸리지 않습니다. CSS 클래스는 단어 전체가 같아야 맞기 때문입니다. 검색할 때는 이 둘을 구분해야 숫자가 부풀지 않습니다(처음에 그냥 “sheet”로 찾았더니 열 개가 나왔습니다).
더 근본적인 방법
게임마다 이름을 피하는 건 임시방편에 가깝습니다. 새 게임을 만들 때마다 누군가 또 .sheet를 쓸 수 있으니까요. 더 확실한 쪽은 공용 패키지가 아무도 안 쓸 이름을 쓰는 것입니다. 예를 들어 .mini-sheet처럼 패키지 접두어를 붙이면 게임 쪽 이름과 겹칠 일이 거의 없습니다. 찾아보니 공용 패키지 안에서도 하트 충전 창과 보드게임 규칙 창이 맨 .sheet를 쓰고 있었습니다. 그래서 미루지 않고 공용 부품 세 곳의 이름을 전부 .mini-sheet로 바꿨습니다. 게임 48개를 전부 타입 검사하고, 확인 창·규칙 창을 바꾸기 전과 후에 헤드리스 브라우저로 찍어 모양과 좌표가 같은지 비교했습니다. 공용 이름을 일부러 빌려 쓰던 게임이 하나 있어서(로또 대신 저축의 설정 창) 그 게임만 같이 고쳤습니다. 각 게임의 다음 업데이트부터 새 이름으로 나갑니다.
배운 것
- 공용 부품은 흔한 이름을 쓰면 안 됩니다.
.sheet,.modal,.btn같은 이름은 각 게임이 반드시 한 번은 쓰고 싶어지는 이름입니다. - 같은 원인이 다른 증상으로 보이면 원인 찾기가 늦어집니다. 두 제보를 따로 봤다면 각각 다르게 고쳤을 겁니다. 증상이 비슷한 화면에서 나오면 공통 부품부터 의심합니다.
- 하나를 고치면 저장소 전체를 검색합니다. 같은 실수는 거의 언제나 한 군데에만 있지 않습니다.
