상호작용을 위해 많은 작은 HTML 페이지를 내비게이션으로 이어 붙일 수 있음
(blog.jim-nielsen.com)- (L)ots of (L)ittle ht(M)l page(s) 접근은 JavaScript 기반 페이지 내부 상호작용을 여러 작은 HTML 페이지 사이의 이동으로 대체함
- 상호작용은 HTML 페이지 간 내비게이션으로 구성하고, 최신 환경에서는 CSS 뷰 전환(view transitions)으로 개선하며, 필요할 때만 약간의 JavaScript를 더함
- 블로그의 Menu는 JavaScript로 펼쳐지는 UI가 아니라
<a href="/menu/">링크를 따라 메뉴 전용 페이지로 이동하는 방식임 - 메뉴 닫기도 기본은
/로 가는 링크지만, document.referrer가 있으면 JavaScript로history.back()을 실행해 방문 기록에 메뉴 열기·닫기 항목이 쌓이지 않게 함 - 브라우저의 기본 기능인 링크 이동에 의존하면 구형 기기·구형 브라우저·JavaScript 비활성화 환경에서도 동작하고, 작은 페이지 크기를 유지할수록 상호작용이 빠르고 견고해짐
메뉴 구현 방식과 설계 결과
-
열기와 닫기 모두 링크로 처리
- 일반 페이지에는 메뉴 페이지로 가는 링크가 있고, 메뉴 페이지에서는 그 링크가 “X”로 바뀌어 메뉴를 닫는 역할을 함
- 닫기 동작도 기본은
/로 가는 링크지만,document.referrer가 있으면 JavaScript로history.back()을 실행해 브라우저 방문 기록에 메뉴 열기·닫기 항목이 추가되지 않게 함 - 단순화한 구현은 다음과 같음
<!-- Normal page --> <nav> <a href="/menu/"> <svg>...</svg> </a> </nav> <!-- Menu page --> <nav> <a href="/" onclick="document.referrer ? history.back() : window.location.href = '/'; return false;"> <svg>...</svg> </a> </nav>
-
직접 방문과 내부 이동을 구분
document.referrer로 메뉴 페이지에 블로그 내부 이동을 통해 왔는지, URL 입력 같은 직접 방문으로 왔는지 구분함- 내부 이동이면 의미 있는
history.back()을 실행할 수 있고, 직접 방문이면/로 이동함
-
접근 방식이 디자인을 형성함
- 단순해 보이는 해법이지만, 내비게이션의 본질, 여러 페이지를 가로지르는 상호작용, 작은 페이지 크기를 유지하는 방법을 함께 고려해야 함
- 페이지 크기를 작게 유지해야 상호작용이 빠르고 견고하며 직관적으로 남을 수 있음
- 브라우저를 임의의 코드를 실행하고 가져오고 컴파일해 표시하는 런타임이 아니라 문서를 탐색하는 도구로 보면, 도구들이 유도하는 것보다 훨씬 단순한 웹사이트를 만들 수 있음
Lobste.rs 의견들
-
보통은 항상 HTML로 응답하는 방식을 좋아하지만, 메뉴 같은 경우는 확신이 안 섬
토글 가능한 요소와 메뉴를 열기 위한 전체 페이지 전환 중 무엇이 더 나은지 접근성 전문가의 의견이 궁금함
여기서는 Popover API가 더 나은 해법처럼 느껴짐. 전체 왕복 요청 없이 JavaScript 없는 메뉴를 제공할 수 있기 때문임
그 외 대부분은 페이지 전환을 두려워할 필요가 없다는 데 동의함. 이제 SPA 같은 내비게이션도 SSR·정적 사이트에서 접근성을 갖추기 거의 항상 어렵지 않음- 접근성 전문가는 아니지만 웹 개발용으로 NVDA를 설치해 둔 입장에서는, 사용자 경험상 큰 차이를 못 느낌
페이지 이동은 현재 위치를 초기화하지만, 메뉴를 열 의도였고 실제로 메뉴에 도착한다면 둘은 꽤 비슷함
다만 스크린 리더 사용자가 아니어도 그렇듯, 메뉴를 여는데 새 페이지로 이동하는 건 꽤 이상하게 느껴짐 - 핵심 단어는 can이지 should가 아님. 상호작용에 HTML 페이지가 적절하면 쓰고, 다른 방식이 더 적절하면 그걸 쓰면 됨
예를 들어 컴포넌트의 펼침/접힘 상태를 서로 다른 HTML 페이지 두 개로 만들지, 아니면<details>태그를 쓸지 묻는다면 당연히 후자임
마찬가지로 Popover API를 쓰는 것도 완전히 괜찮음. 요점은 페이지 안 상호작용에 JavaScript가 필요하지 않게 피하자는 것이지, 다중 페이지 HTML 내비게이션을 고집하자는 게 아님
- 접근성 전문가는 아니지만 웹 개발용으로 NVDA를 설치해 둔 입장에서는, 사용자 경험상 큰 차이를 못 느낌
-
제시된 방식은 JavaScript와
onclick으로 메뉴를 동적으로 불러오므로 지연 시간이 생기고 사용자 여정에 데이터 포인트가 하나 더 추가됨
대신 메뉴를 각 페이지에 넣고<details>요소나:focus-withinCSS 선택자로 보이거나 숨길 수 있음
https://nlnet.nl 이 이런 방식으로 동작함 -
설명된 접근은 실제로는 제대로 동작하지 않음. JavaScript를 끄고 블로그 글을 연 뒤 메뉴를 열고 닫으면, 원래 글이 아니라 홈(
/)으로 이동함
닫기 버튼에 올바른 링크를 넣으려면 백엔드에서 메뉴를 동적으로 렌더링해야만 이 방식이 성립함
개인적으로는 가능하다면 Popover API를 선호함. 그러면 백엔드 없이도 모든 것을 정적으로 렌더링할 수 있음- 메뉴의 X 아이콘 링크는
https://blog.jim-nielsen.com/를 가리키지만, JavaScript를 켜면onclick처리기가 내비게이션을 가로채는 듯함document.referrer ? history.back() : window.location.href = '/'; return false;href에 적힌 곳과 다른 페이지로 보내므로 나쁜 사용자 경험임. 링크에 마우스를 올려 목적지를 자주 확인하는데, 이렇게 속는 느낌은 달갑지 않음
- 메뉴의 X 아이콘 링크는
-
한편으로는 정말 마음에 듦. HTML만으로도 JavaScript보다 더 매끄럽고 단순하게 많은 일을 할 수 있음
다른 한편으로는 이 방식이 주로 모바일에서 잘 맞아 보임. 데스크톱 페이지라면 메뉴가 항상 보이거나 팝아웃되는 걸 기대하지, 페이지 이동을 요구하진 않을 것임
그렇다면 이제 브라우저별로 두 벌의 페이지가 필요해지는 건가 싶음- 반대로 모바일에서 연결이 불안정하면 메뉴로 한 번 이동하고 다시 목적지로 이동해야 함
마찰이 두 배가 됨 - 비교적 젊은 편인 듯함. 20~30년 전에는 모든 웹사이트가 이런 식으로 동작했고, HTML도 어느 정도 그렇게 쓰이도록 의도됐음
JavaScript는 우발적인 산물에 가까웠음
이 방식이 어떤 JavaScript 해법보다 더 어렵거나 복잡하다고 느끼는 게 의아함. 웹사이트를 만드는 가장 단순하고 쉬운 방법임은 분명함
- 반대로 모바일에서 연결이 불안정하면 메뉴로 한 번 이동하고 다시 목적지로 이동해야 함
-
내비게이션 방식은 별로지만 전환 효과는 마음에 들었고, 이런 게 가능한 줄 몰랐음
직접 만든 C++ 정적 생성기와 템플릿 라이브러리를 쓰는 내 사이트에도 적용함: https://vittorioromeo.com/
특히 다크/라이트 테마 전환기에 잘 어울린다고 봄 -
데스크톱에서 “menu”를 클릭했는데 다른 페이지로 이동하는 건 기분이 좋지 않음. 전체 페이지 새로고침이 발생해서 기대와 달리 꽤 거슬림
개인적으로는 읽기 흐름과 생각의 흐름이 끊김. 다른 사이트로 가는 링크를 클릭할 때는 방을 나가는 느낌이라 이전 방을 버리고 이동하지만, 메뉴에서 이런 일이 생기면 문 앞에 갔더니 완전히 다른 방에 와 있는 느낌이라 불편함
아이디어 자체는 솔직히 좋지만, 실제로 쓰는 느낌은 좋지 않음
그리고 어떤 전환 효과를 말하는지도 모르겠음. 내 환경에서는 Menu 버튼을 누르면 그냥 평소처럼 Menu 페이지가 로드될 뿐임- 문서 간 뷰 전환은 아직 Firefox에서 동작하지 않음
다른 브라우저에서도 안 될 수 있지만, 주 브라우저로 Firefox 포크인 Librewolf를 쓰고 있음
Chromium에서는 전환 효과가 보임
- 문서 간 뷰 전환은 아직 Firefox에서 동작하지 않음
-
재미있는 아이디어지만 데스크톱에서는 어떻게 작동할지 궁금함
전체 페이지 메뉴는 좀 과하다고 느껴져서, 페이지 전체를 바꾸는 방식은 덜 맞아 보임 -
메뉴 페이지 로드 지연을 줄이기 위한 preload를 언급하지 않음
이걸 쓰면 얼마나 잘 동작할지 궁금함- 올바른 캐시 헤더도 넣어야 함. 여기서는 단순한 expires 헤더만으로도 충분할 가능성이 큼
그러면 보여주기 전에 서버에 검증하러 갈 필요도 없어져서 매우 빠르게 느껴질 것임
- 올바른 캐시 헤더도 넣어야 함. 여기서는 단순한 expires 헤더만으로도 충분할 가능성이 큼
-
몇 년 전 @misty가 만든 텍스트 게임을 봤는데, 단순 링크를 상호작용으로 써서 선택의 환상을 줬음
단순한 HTML과 강한 이야기가 깊이 와닿았음