개발

블로그 스킨 패치 노트 — 목차를 오른쪽으로, 그리고 내가 만든 회귀 하나

이 블로그는 직접 만든 워드프레스 테마 clean-gallery 로 돌아간다. 며칠 쓰면서
눈에 걸린 것들을 고쳤고, 그 기록이다. 각 항목은 무엇이 바뀌었는지
왜 그랬는지를 함께 적었다.

버전 바뀐 것
2.1.0 카테고리가 화면 맨 아래에서 오른쪽 단으로
2.2.0 목차가 본문 위에서 오른쪽 단으로 · 읽기 진행바 3px
2.2.1 카테고리 칩과 글 목록이 붙어 있던 여백
2.3.0 휴대폰에서도 목차가 따라오게
2.3.1 목차 강조가 아예 안 켜지던 회귀 수정
PC 화면. 오른쪽 목차에서 지금 읽는 항목이 파랗게 켜져 있고, 화면 맨 위에 읽기 진행바가 차 있다
PC 화면. 오른쪽 목차에서 지금 읽는 항목이 파랗게 켜져 있고, 화면 맨 위에 읽기 진행바가 차 있다

2.1.0 — 카테고리를 오른쪽으로#

카테고리 목록이 화면 맨 아래에 나왔다. 오른쪽 단은 원래 있었는데, 위젯
영역이 비면 통째로 사라지도록 되어 있었다. 새로 설치한 블로그는 당연히
비어 있으니 아무도 그 단을 못 봤다.

두 갈래로 고친다.

  • 위젯이 비면 테마가 직접 카테고리(글 수 포함)와 최근 글을 그린다. 위젯을 하나라도 넣으면 물러난다.
  • 워드프레스가 새 설치 때 만드는 기본 위젯 묶음이 테마의 영역 이름과 맞지 않으면 푸터로 흘러 들어간다. 사이드바가 비어 있을 때에 한해 한 번만 오른쪽으로 옮긴다. 나중에 일부러 푸터로 되돌려 놓으면 그대로 둔다.

참고

그리드 아이템의 자동 최소 크기는 min-content 다. 그래서 긴 제목 하나가
단 전체를 화면 밖으로 밀어낼 수 있다. .layout > *min-width: 0
두면 막힌다.

2.2.0 — 목차를 오른쪽 단으로#

목차가 본문 맨 위에 상자로 있었다. 한 번 지나가면 다시 안 보인다. 오른쪽으로
옮겨 스크롤을 따라오게 한다.

같은 목차를 두 벌 그려 두고 화면 너비로 하나만 보여 준다.

  • 넓은 화면: 오른쪽 단에 붙어 따라온다. 상자 대신 왼쪽 세로선을 기준선으로 삼고, 지금 읽는 자리가 그 선 위에서 도드라진다.
  • 좁은 화면: 오른쪽 단이 본문 아래로 내려가 버리므로 예전처럼 본문 앞에 둔다.

두 벌 그린다고 화면 낭독기가 두 번 읽지는 않는다. display: none 인 쪽은
접근성 트리에서도 빠지기 때문이다. 다만 제목에 id 를 달아 두면 문서에
같은 id 가 둘 생기므로, aria-labelledby 대신 aria-label 로 바꿔야 한다.

오른쪽 단이 화면보다 길어지면 그 안에서만 스크롤되게 했다. 안 그러면 붙어
있는 동안 아래쪽 위젯에 영영 닿을 수 없다.

현재 위치 계산을 바꿨다#

처음에는 IntersectionObserver 로 "지금 띠 안에 들어온 제목"을 잡았다.
그런데 제목 사이가 긴 구간에서는 띠 안에 아무 제목도 없어서 아무 데도
안 칠해진다.

화면 위쪽 기준선을 지난 마지막 제목을 고르는 방식으로 바꾼다. 항상 하나가
칠해진다.

var active = headings[0];
for (var i = 0; i < headings.length; i++) {
    if (headings[i].getBoundingClientRect().top <= line) active = headings[i];
    else break;
}

맨 아래까지 내려간 경우는 따로 처리한다. 짧은 마지막 절은 기준선까지 못
올라와서 영영 안 칠해지기 때문이다.

읽기 진행바#

새로 만든 줄 알았는데 이미 있었다. 2px 라 눈에 안 띄었을 뿐이라 3px 로 키웠다.

2.2.1 — 카테고리 칩 아래 여백#

카테고리 목록 페이지에서 칩 바로 아래에 글 카드가 붙어 있었다.

.term-chips 에는 위 여백만 있었다. 홈에서는 칩이 .hero 안 마지막
요소라 hero 의 padding-bottom 이 아래 여백을 대신 내주고 있었는데,
카테고리 페이지에서는 칩이 아무 상자에도 안 들어가고 글 목록 바로 위에
놓여서 아래를 받쳐 주는 게 없었다.

칩 자체에 아래 여백을 주고, 홈에서는 hero 의 padding 과 겹치지 않게 0 으로
되돌린다.

카테고리 페이지   0px → 32px
홈                40px 그대로

2.3.0 — 휴대폰에서도 목차가 따라오게#

넓은 화면에서는 되는데 휴대폰에서는 안 됐다. 당연했다 — 좁은 화면에서는
오른쪽 단이 숨겨지고, 본문 앞 목차는 글 맨 위에 있어 스크롤하면 화면 밖으로
사라진다. 켜질 목차 자체가 화면에 없었다.

좁은 화면의 목차를 접힌 채 헤더 밑에 붙어 따라오게 바꾼다. 펼치지 않아도
요약 줄에 지금 읽는 절 이름이 파랗게 나오고, 눌러 펼치면 전체 목록에서 그
항목이 켜져 있다. 목록이 길면 그 안에서만 스크롤된다.

휴대폰 화면. 헤더 바로 밑에 접힌 목차가 붙어 있고 요약 줄에 지금 읽는 절 이름이 파랗게 나온다
휴대폰 화면. 헤더 바로 밑에 접힌 목차가 붙어 있고 요약 줄에 지금 읽는 절 이름이 파랗게 나온다

넓은 화면은 목록 전체가 늘 보이므로 접을 이유가 없어 그대로 둔다.

2.3.1 — 목차 강조가 아예 안 켜지던 회귀#

여기부터는 내가 만든 버그다.

2.2.0 과 2.3.0 을 넣고 확인까지 마쳤는데, 실제 블로그에서는 넓은 화면에서도
불이 안 들어왔다. 원인은 한 줄이었다.

제목 idsanitize_title() 이 만든다. 한글 제목은 그 안에서 퍼센트
인코딩
된다.

"준비물"  →  id="%EC%A4%80%EB%B9%84%EB%AC%BC"

그런데 내가 넣은 코드는 hrefdecodeURIComponent풀어서 찾고
있었다. 문서에 실제로 있는 id 는 인코딩된 쪽이라 getElementById 가 전부
null 을 돌려줬고, 제목이 하나도 안 잡혀 함수가 그대로 빠져나갔다.

있는 그대로 먼저 찾고, 없을 때만 한 번 풀어서 찾는다.

var el = document.getElementById(raw);
if (!el) {
    try { el = document.getElementById(decodeURIComponent(raw)); } catch (e) { el = null; }
}

주의

더 뼈아픈 건 앞선 확인이 통과했다는 것이다. 시험 페이지의 제목 id
h-1, h-2 같은 ASCII 로 직접 만들어 썼기 때문이다. 진짜 id 모양을 안
쓴 시험이 통과를 보증해 줬다.
화면에 그려지는 값을 시험할 때는 그 값을 만드는 함수와 같은 규칙으로
만들어야 한다. 손으로 그럴듯하게 지어낸 입력은 통과를 보증해 주지 않는다.

고친 뒤 같은 페이지로 다시 재면 이렇게 나온다.

고치기 전 (퍼센트 인코딩 id)
  0% · 25% · 55% · 100%   →  강조 (없음)

고친 뒤
  0%     준비물
  25%    3. DNS 레코드 넣기
  55%    5. dig 로 전파 확인
  100%   정리

확인#

글 하나를 열어 놓고 스크롤해 보면 된다.

  • 넓은 화면 — 오른쪽 목차의 항목이 절이 바뀔 때마다 파랗게 옮겨 붙는다. 화면 맨 위 진행바가 글 길이만큼 찬다.
  • 좁은 화면 — 헤더 밑에 목차가 붙어 따라오고, 요약 줄의 절 이름이 바뀐다.
  • 스킨이 안 바뀐 것 같으면 테마 버전을 확인한다. 브라우저가 옛 CSS 를 들고 있을 수 있다.
curl -s https://autops.run/ | grep -o 'clean-gallery/style.css?ver=[0-9.]*'

정리#

세 가지가 남는다.

  • 이미 있는 걸 먼저 확인한다. 읽기 진행바는 만들 필요가 없었다. 2px 라 안 보였을 뿐이다.
  • 좁은 화면은 따로 본다. 오른쪽 단에 무언가를 두면 휴대폰에서는 그게 본문 아래로 내려간다. 넓은 화면에서 잘 된다고 끝난 게 아니다.
  • 시험 입력은 진짜와 같은 규칙으로 만든다. 손으로 지어낸 ASCII id 가 통과를 보증해 주는 바람에, 아예 동작하지 않는 코드를 두 번이나 배포했다.
공유

댓글

댓글 남기기