내부 동작 원리: 드래그, 터치, 그리고 CSS 캐스케이드
크기 조절이 가능한 UI 패널을 만드는 것은 보기보다 어렵습니다. 레이아웃, 터치 이벤트, CSS 규칙을 동시에 관리해야 하기 때문입니다.
최근 진행한 비주얼 디프(visual-diff) UI 리디자인 과정에서 얻은 세 가지 기술적 교훈을 소개합니다.
- 레이아웃에 window 너비를 사용하는 것을 중단하세요
레이아웃이 세로인지 가로인지 결정하기 위해 window.innerWidth를 사용하지 마세요. 사용자가 창 크기를 조절하면 로직이 깨질 수 있습니다.
대신 실제 CSS 상태를 사용하세요. getComputedStyle을 사용하여 flex-direction을 확인하세요. 이렇게 하면 모든 미디어 쿼리가 적용된 후의 실제 값을 읽어올 수 있습니다. 이를 통해 드래그 로직이 사용자가 실제로 보는 화면과 일치하도록 보장할 수 있습니다.
- 터치와 마우스 이벤트를 함께 처리하세요
데스크톱과 모바일 모두에서 드래그가 작동하게 하려면 통합된 접근 방식이 필요합니다.
- 옵셔널 체이닝(optional chaining)을 사용하여 좌표를 추출하세요. 이를 통해 하나의 함수로 마우스와 터치 이벤트를 모두 처리할 수 있습니다.
touchmove에{ passive: false }를 사용하세요. 브라우저는 스크롤을 돕기 위해 터치 이벤트의 기본값을passive로 설정합니다. 이를false로 설정하지 않으면e.preventDefault()를 호출할 수 없습니다. 이 호출이 없으면 드래그를 시도하는 동안 페이지가 스크롤됩니다.move및end리스너를document에 연결하세요. 사용자가 손가락을 너무 빨리 움직이면 구분선(divider)을 벗어날 수 있습니다.document에 연결하면 포인터가 벗어나더라도 드래그가 계속 유지됩니다.
- 가시성(visibility) 시스템과 싸우지 마세요
CSS 명시도(specificity) 버그를 겪은 적이 있습니다. 패널을 숨기는 클래스와 레이아웃 방향을 설정하는 클래스가 각각 따로 있었습니다.
문제점:
.view-panel { display: none; }.diff-layout { display: flex; }
이 두 클래스의 명시도가 동일했기 때문에 파일의 마지막에 있는 클래스가 적용되었습니다. 이로 인해 패널이 숨겨져야 할 상황에서도 계속 표시되는 문제가 발생했습니다.
해결 방법:
레이아웃 보조 클래스가 display 속성을 설정하게 두지 마세요. display 속성은 가시성 클래스가 담당하도록 해야 합니다.
다음 대신:
.diff-layout { display: flex; flex-direction: column; }
이렇게 사용하세요:
.view-panel.diff-layout { flex-direction: column; }
이렇게 하면 명시도가 높아져 레이아웃 클래스가 가시성이 아닌 방향만 변경하도록 보장할 수 있습니다.
출처: https://dev.to/bonzai2carn/under-the-hood-drag-touch-and-css-cascade-in-a-real-diff-ui-1b66
