LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLAB Coreteam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

DevLogSEO Jing

Day 10 - 프레젠테이션 모드 안정화

2026년 3월 23일·6분 읽기

프레젠테이션 모드, 문제투성이

어제 만든 프레젠테이션 모드를 모바일에서 실제로 써보니 문제가 한두 개가 아니었다. 퀴즈, 코드블록, 이미지 같은 인터랙티브 요소들이 슬라이드 높이를 제대로 계산하지 못해서 잘리거나 겹쳤고, 롱프레스 UX도 어색했다. 하나씩 잡아나갔다.


퀴즈 → 미지원 안내 메시지

퀴즈 컴포넌트는 React 상태 기반이라 DOM 클로닝 방식의 프레젠테이션 모드에서는 동작할 수가 없다. ArticleQuiz에 data-article-quiz 속성을 추가하고, extractSlides()에서 감지하면 안내 메시지로 교체하도록 했다.

"프레젠테이션 모드에서는 퀴즈를 지원하지 않습니다. 프레젠테이션 모드를 종료 후 이용해 주세요." 라는 플레이스홀더가 표시된다.


코드블록 → 조건부 전체보기 버튼

코드블록도 높이 계산이 안 돼서 슬라이드를 넘쳐버리는 문제가 있었다. 코드블록을 만나면 무조건 새 페이지로 분기하고, 빈 페이지에서도 높이가 넘치면 "코드 전체 보기" 버튼으로 교체하는 방식으로 해결했다.

버튼을 누르면 기존의 FullscreenView와 동일한 전체화면 코드 뷰어가 열린다. DOM 클로닝 환경이라 React 이벤트를 쓸 수 없어서, data-code-html과 data-code-language 속성에 원본 코드를 저장해두고, 슬라이드 렌더 후 addEventListener로 클릭 리스너를 직접 부착하는 방식을 사용했다.

네비게이션 오버레이가 버튼 클릭을 가로채는 문제도 있었다. 부모에 pointer-events-none을 걸고 양쪽 1/4 영역만 pointer-events-auto로 설정해서, 가운데 영역의 버튼이 클릭되도록 수정했다.


이미지 비율 유지 축소

이미지도 코드블록과 같은 문제가 있었다. 두 이미지가 한 슬라이드에 겹쳐 나오는 문제. 이미지(figure 요소)를 만나면 무조건 새 페이지로 분기하고, max-height를 슬라이드 가용 높이에서 캡션 높이를 뺀 값으로 제한해서 비율을 유지하며 축소되도록 했다.


포스트 목록 제거 및 마지막 페이지 종료

글 하단의 PostExplorer 컴포넌트가 프레젠테이션 슬라이드에 포함되면서 모바일에서 잘리는 문제가 있었다. 프레젠테이션에서 보여줄 필요가 없는 요소라 data-presentation-skip 속성을 추가해서 슬라이드 추출 시 제외시켰다.

마지막 슬라이드에서 오른쪽을 누르면 바로 프레젠테이션이 종료되도록 goToNext에 종료 로직을 추가했다. 이 과정에서 두 가지 버그를 잡았다.

  • setCurrentSlide updater 안에서 onClose()를 호출하면 렌더 중 부모 컴포넌트의 setState가 트리거되는 React 경고가 발생한다. updater 밖에서 currentSlide 값을 직접 비교하는 방식으로 수정. - 프레젠테이션이 닫히면서 포탈이 제거되면, 같은 이벤트 사이클에서 아래 DOM의 링크나 버튼이 눌려버리는 버블링 문제. requestAnimationFrame으로 다음 프레임에서 종료하도록 지연시켜 해결.

롱프레스 UX 개선

모바일에서 화면을 탭할 때마다 "놓지 마세요..."가 잠깐 깜빡이는 문제가 있었다. 롱프레스 판단 전에 최소 300ms의 threshold를 두어, 빠른 탭에서는 메시지가 아예 표시되지 않도록 수정했다.

하단 바도 손봤다. 페이지 카운터를 absolute left-1/2 -translate-x-1/2로 고정해서 좌측 텍스트 길이와 무관하게 항상 중앙에 위치하도록 했고, 모바일 하단 바 높이를 48px에서 36px로 축소해서 콘텐츠 영역을 넓혔다.


모바일 뷰포트 문제

모바일 브라우저에서 프레젠테이션 모드를 열면 주소창과 하단 네비게이션 바 뒤로 콘텐츠가 가려지는 문제가 있었다. 원인은 두 가지였다.

첫째, 컨테이너 크기에 100vh/100vw를 사용하고 있었는데, 모바일 브라우저에서 100vh는 브라우저 UI를 포함한 전체 뷰포트 높이다. 실제로 보이는 영역보다 크다. 100dvh/100dvw(dynamic viewport height)로 교체해서 브라우저 UI가 차지하는 영역을 제외한 실제 보이는 높이만 사용하도록 수정했다.

둘째, 슬라이드 높이 계산에서 window.innerWidth를 쓰고 있었는데, 이것도 브라우저 UI를 고려하지 않는다. window.visualViewport을 우선 참조하도록 변경해서 실제 가용 영역을 정확하게 반영하도록 했다.


채움 비율 조정

뷰포트 문제를 수정한 뒤에도 콘텐츠가 하단 바에 너무 붙어 보이는 문제가 있었다. getFillRatio()의 비율을 전체적으로 낮춰서 여유 공간을 확보했다.

화면 높이이전변경
600px 이하 (모바일)0.920.82
601~900px (노트북)0.620.55
901~1200px (데스크탑)0.720.60
1200px 초과 (대형)0.65

리스트 분할 조건 완화

스터디 자료처럼 Paragraph와 ul이 번갈아 나오는 구조에서 슬라이드가 넘치는 문제가 있었다. 기존에는 리스트 전체 높이가 availableHeight를 초과할 때만 li 단위 분할이 동작했는데, 앞에 다른 콘텐츠가 있어서 합산 높이가 넘치는 경우에는 리스트를 통째로 넣어버렸다.

분할 조건을 currentHeight + elementHeight > availableHeight로 완화해서, 현재 슬라이드에 넣으면 넘치는 경우에도 li 단위로 분할되도록 수정했다. 리스트가 가용 높이의 50% 이상일 때만 기존 슬라이드를 먼저 flush하는 가드도 추가했다.


포스트 탐색기 자연 정렬

포스트 탐색기에서 "Day 10"이 "Day 1" 바로 뒤에 정렬되는 문제가 있었다. localeCompare가 문자열 사전순 정렬을 하기 때문에 "1" 다음에 "10"이 오고 그 다음 "2"가 오는 순서였다. localeCompare에 numeric: true 옵션을 추가해서 숫자 부분을 수치 기준으로 비교하도록 수정했다. Day 1, Day 2, ..., Day 9, Day 10 순서로 정렬된다.

Post Q&A

오케이징에게 물어보기

Day 10 - 프레젠테이션 모드 안정화 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!

0/500

포스트 목록

/SEOJing/devLog
파일 14개, 폴더 1개
Day 1 - 디자인 컨셉과 디자인 시스템Day 2 - 블로그 스켈레톤과 MDX 파싱Day 3 - MDX 이슈, 반응형, 다크모드Day 4 - 배포와 CI/CDDay 5 - shiki 제거, MDX 모듈화, 그리고 대량 포스팅Day 6 - 스터디 자료 작성과 데스크탑 비율 수정Day 7 - Front Matter CMS와 관련 게시물 탐색기Day 8 - 아티클 퀴즈와 스터디 자료Day 9 - 프레젠테이션 모드, 코드블럭 개선, 테스팅Day 10 - 프레젠테이션 모드 안정화Day 11 - 프레젠테이션 확대 기능, FullscreenView 개선Day 12 - 테스트 커버리지 개선, 모바일 프레젠테이션 버그 2건 수정기술 블로그를 직접 제작하게 된 이유왜 자꾸 프로젝트가 중단되는지

같은 섹션의 대표 이미지

24 posts · latest first
SEO Jing26. 04. 01.

Day 12 - 테스트 커버리지 개선, 모바일 프레젠테이션 버그 2건.

SEO Jing 개발 열두째 날. code-block 테스트 14개 추가로 커버리지 대폭 개선, 모바일 프레젠테이션에서 FullscreenView 방향 전환 문제와 스크롤 멈춤 버그 수정.

26. 04. 01.SEOJing
SEO Jing26. 03. 25.

Day 11 - 프레젠테이션 확대 기능,.

SEO Jing 개발 열한째 날. PC 프레젠테이션 확대/축소 컨트롤 추가, 모바일 orientation 판단 로직 개선, FullscreenView를 독립 컴포넌트로 분리 및 PC 대응.

26. 03. 25.SEOJing
0.55
SEO Jing26. 03. 23.

Day 10 - 프레젠테이션 모드 안정화.

SEO Jing 개발 열째 날. 프레젠테이션 모드의 모바일 UX 문제들을 전면 수정. 퀴즈·코드블록·이미지·포스트목록 처리 개선, 롱프레스 UX 및 하단 바 레이아웃 안정화. 모바일 뷰포트·리스트 분할 문제 수정, 채움 비율 보수적으로 조정, 포스트 탐색기 자연 정렬 적용.

26. 03. 23.SEOJing
SEO Jing26. 03. 22.

Day 9 - 프레젠테이션 모드, 코드블럭 개선, 테스팅.

SEO Jing 개발 아홉째 날. 프레젠테이션 기능 추가, 퀴즈 구조 변경, 모바일 반응형, 코드블럭 사용성, 테스팅 도입.

26. 03. 22.SEOJing
SEO Jing26. 03. 21.

Day 8 - 아티클 퀴즈와 스터디 자료.

SEO Jing 개발 여덟째 날. 아티클 퀴즈 디자인시스템 구현과 스터디 대면 자료 작성.

26. 03. 21.SEOJing
SEO Jing26. 03. 20.

Day 7 - Front Matter CMS와 관련 게시물.

SEO Jing 개발 일곱째 날. Front Matter CMS 설치와 관련 게시물 이동 탐색기 구현.

26. 03. 20.SEOJing
SEO Jing26. 03. 18.

Day 6 - 스터디 자료 작성과 데스크탑 비율 수정.

SEO Jing 개발 여섯째 날. 데스크탑 비율 수정과 씨랩 스터디 사전 진단 자료 작성.

26. 03. 18.SEOJing
SEO Jing26. 03. 17.

Day 5 - shiki 제거, MDX 모듈화, 그리고.

SEO Jing 개발 다섯째 날. shiki를 rehype-prism-plus로 교체하고, gray-matter 직접 구현, MDX 모듈화, 페이지 내 검색, 테이블 디자인시스템까지.

26. 03. 17.SEOJing
SEO Jing26. 03. 16.

Day 4 - 배포와 CI/CD.

SEO Jing 개발 넷째 날. lint, codecov, Cloudflare 배포, fs 런타임 이슈.

26. 03. 16.SEOJing
SEO Jing26. 03. 15.

엄청난 피드백.

CLI 코드 리뷰에서 받은 피드백과 전체 코드 수정 계획을 정리했다.

26. 03. 15.SEOJing
SEO Jing26. 03. 15.

생각보다 어려웠던 댓글, 완독 로컬스토리지.

localStorage만으로 글 읽기 추적, 스크롤 진행률, 댓글 감지를 구현한 과정을 정리했다.

26. 03. 15.SEOJing
SEO Jing26. 03. 15.

MDX 관련 이슈 노트.

블로그 디테일 페이지에서 MDX를 렌더링하기 위해 검토한 라이브러리들과 최종 선택 과정.

26. 03. 15.SEOJing
SEO Jing26. 03. 15.

Day 3 - MDX 이슈, 반응형, 다크모드.

SEO Jing 개발 셋째 날. MDX 라이브러리 이슈, 반응형, 코드블럭, 댓글, 다크모드, 코드 리뷰.

26. 03. 15.SEOJing
SEO Jing26. 03. 14.

디자인 시스템을 구축할 때 주의할 점.

디자인 시스템 구현 시 파일 구조, 디자인 토큰, 유의 사항을 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

폰트는 왜 메인 페이지에서만 적용이 안되고 있었을까?.

Tailwind v4 환경에서 폰트가 메인 페이지에서만 적용되지 않던 원인과 Hydration Mismatch 이슈를 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

MDX DOM 트리 파싱하기.

MDX 파일의 경로 탐색 로직과 콘텐츠 트리 생성 과정을 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

결국 Node.js 까지 와버렸다.

MDX 파일 구조를 JSON으로 변환하기 위해 Node.js의 fs 모듈을 배워봤다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

Day 2 - 블로그 스켈레톤과 MDX 파싱.

SEO Jing 개발 둘째 날. 디자인 시스템 확장, 블로그 스켈레톤, 폰트 이슈 해결.

26. 03. 14.SEOJing
SEO Jing26. 03. 13.

전체적인 플로우.

SEO Jing 프로젝트의 기술 스택 선정과 전체적인 개발 플로우 정리.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

Storybook으로 디자인 시스템 테스팅하기.

Storybook의 사용법과 디자인 시스템 개발에서의 장점을 정리했다.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

MDX가 뭘까?.

MDX의 개념과 블로그에서 활용하는 이유를 정리했다.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

Day 1 - 디자인 컨셉과 디자인 시스템.

SEO Jing 개발 첫째 날. 디자인 컨셉 설정과 디자인 시스템 구축을 시작했다.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

기술 블로그를 직접 제작하게 된 이유.

SEO Jing을 개발하게 된 이유입니다.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

왜 자꾸 프로젝트가 중단되는지.

프로젝트가 중단되는 이유에 대한 자기 회고입니다.

26. 03. 13.SEOJing