코딩 모르는 7년차 디자이너가 AI랑 게임 만든 이야기
저는 7년차 디자이너예요. 그리고 코딩은 못 해요. Claude한테 말로 설명하면서 게임 UI, 브랜드, 블로그까지 만들었어요. 색상 시스템, 타이포그래피, 그리고 프롬프트로 안 됐던 것들에 대한 이야기예요.
- 문제: 외부 위젯(Giscus) 로딩 시 발생하는 널뛰기 현상(Layout Shift)과 이질적인 스피너 노출. - 해결: CSS Grid 겹치기(`grid-area: overlap`) 기법과 `postMessage` 이벤트 가로채기로 렌더링 타이밍 완벽 통제. - 결과: 단 1px의 오차나 깜빡임 없이 디자인 시스템에 100% 동화된 댓글창 구현 완료.
정적 블로그나 Next.js 블로그를 만들 때 GitHub Discussions 기반의 Giscus는 최고의 선택입니다. 서버도 필요 없고, 마크다운도 지원하니까요.
하지만 디자이너인 제 눈을 심하게 거슬리게 하는 문제가 있었습니다. 바로 Iframe 비동기 로딩 시 발생하는 화면 꿀렁거림(Layout Shift)과 내 디자인 시스템과 전혀 어울리지 않는 이질적인 로딩 스피너였습니다.
보통 개발자들이라면 "기능 잘 돌아가네, 원래 외부 위젯이 다 그렇지 뭐" 하고 넘어갔겠지만, 픽셀 하나, 패딩 값 하나 어긋나는 꼴을 못 보는 디자이너에게 이 0.5초의 '펄럭임'은 용납할 수 없는 재앙이었습니다.
오늘은 제가 브라우저 개발자 도구(DevTools)를 직접 켜서 패딩과 보더 값을 픽셀 단위로 뜯어보고, 결국 Giscus를 내 블로그에 100% 완벽하게 동화시키도록 설계한 '집착의 기록'을 공유합니다.
보통 개발자들은 Giscus를 붙일 때, Iframe이 로딩되는 시간 동안 빈 공간이 생기는 걸 막기 위해 흔히 스켈레톤 UI(Skeleton UI)를 띄워둡니다.
// ❌ 기능만 생각한 (그리고 눈에 거슬리는) 방식
{isLoading ? <SkeletonUI /> : <Giscus />}
이 방식의 치명적인 단점은 컴포넌트가 교체되는 그 짧은 찰나에 높이(height)가 0이 되거나 틀어지면서 페이지 하단의 푸터가 위로 휙 올라왔다 다시 내려가는 현상이 발생한다는 점입니다. 스크롤을 내리며 글의 여운을 느끼던 유저의 UX를 완전히 박살 내는 주범이죠.
이 문제를 해결하기 위해 고안한 방법은 스켈레톤과 Iframe이 서로 자리를 '교대'하는 게 아니라, 애초에 같은 공간에 겹쳐 있도록 설계하는 것이었습니다.
부모 컨테이너에 display: grid를 주고, 두 요소를 같은 grid-area에 욱여넣도록 했습니다.
.giscus-grid {
display: grid;
grid-template-areas: "overlap";
}
.skeleton-wrapper, .giscus-frame {
grid-area: overlap;
transition: opacity 0.5s ease-in-out;
}
이렇게 하면 Iframe이 로딩을 마쳐도 DOM 구조가 무너지지 않습니다. 단순히 스켈레톤의 opacity는 0으로, Iframe의 opacity는 1로 부드럽게 크로스페이드(Cross-fade)될 뿐입니다. 푸터는 단 1px도 미동하지 않습니다. 디자이너로서 가장 편-안해지는 순간입니다.
레이아웃 시프트는 잡았지만, 또 다른 문제가 보였습니다. Iframe이 로딩되자마자 GitHub 기본 로딩 스피너(문어 고양이)가 잠깐 보였다가 실제 댓글창으로 전환되는 현상이었죠.
제 블로그의 사이버 틱한 네온 디자인 톤앤매너와 너무 따로 놀았습니다. 게다가 로딩 전 스켈레톤 UI와 로딩 후 실제 UI의 간극이 너무 컸습니다.
직접 브라우저 DevTools를 열고 Giscus Iframe 내부의 .gsc-comment 패딩 값과 보더, 마진 값을 픽셀 단위로 모조리 찍어봤습니다. 그리고 제 스켈레톤 UI를 실제 댓글이 0개 달렸을 때의 Giscus UI와 1px의 오차도 없이 동일하게 그리도록 맞췄습니다.
postMessage 가로채기Giscus는 emitMetadata="1" 설정을 켜면 Iframe 내부 상태를 postMessage로 부모 창에 쏴줍니다.
보통은 resizeHeight 이벤트만 오면 로딩이 끝났다고 판단해버리지만, 이때는 아직 데이터 로딩 중이라 고양이 스피너가 뜹니다. 저는 완벽한 전환 타이밍을 잡기 위해 실제 댓글 데이터인 discussion 메타데이터가 도착할 때까지 끈질기게 기다렸다가 스켈레톤을 페이드 아웃 시키도록 로직을 짰습니다.
이제 유저는 이질적인 스피너를 볼 틈도 없이, 완벽하게 계산된 스켈레톤 UI에서 실제 UI로 스르륵 전환되는 마법을 경험하게 됩니다.
끝난 줄 알았죠? 모바일(500px 이하)에서 확인해 보니 이번엔 Giscus 헤더 영역 요소들이 엉망으로 엉켜 있었습니다. [댓글 수]와 [정렬 드롭다운]이 중구난방으로 줄 바꿈이 되더군요.
당장 커스텀 CSS 테마(giscus-dark.css)를 열고 모바일 레이아웃을 전면 뜯어고쳤습니다. flex로 대충 넘어가려는 걸 용납할 수 없어서 CSS Grid를 도입해 위계를 확실하게 잡았습니다.
@media (max-width: 500px) {
.gsc-header {
display: grid !important;
grid-template-columns: 1fr auto !important;
gap: 12px 16px !important;
}
/* 댓글 수와 반응 버튼의 내부 flex를 해제하여 grid 직접 배치 */
.gsc-left-header { display: contents !important; }
.gsc-comments-count { grid-column: 1 / 2 !important; } /* 좌측 상단 */
.gsc-right-header { grid-column: 2 / 3 !important; } /* 우측 상단 */
.gsc-reactions { grid-column: 1 / 3 !important; } /* 하단 전체 */
}
이제 모바일에서도 좌측 상단엔 댓글 수, 우측 상단엔 정렬 메뉴, 그리고 그 아래로 반응(Reactions)들이 깔끔하게 100% 너비로 들어맞습니다. 덤으로 text-center로 떠돌던 "powered by giscus" 문구도 깔끔하게 좌측 정렬시켰습니다.
아마 대부분의 방문자는 이 모든 디테일을 눈치채지 못할 겁니다.
하지만 디자이너에게 '보이지 않는 디테일'은 타협의 대상이 아니라 완성도의 척도라고 생각합니다. 개발자 도구로 수십 번 패딩 값을 찍어보며 픽셀 단위로 스켈레톤을 맞추고, Iframe 통신을 뜯어내 타이밍을 조절한 끝에, 이 블로그의 댓글창은 드디어 제 디자인 시스템의 일부로 완벽하게 녹아들었습니다.
디자인과 코드가 타협하지 않고 완벽하게 맞물려 돌아가는 걸 보는 것, 그게 바로 우리 디자이너들이 집착을 멈출 수 없는 이유 아닐까요?
무료 네온 블록 퍼즐. 설치 없이 웹에서 바로 즐기세요!
저는 7년차 디자이너예요. 그리고 코딩은 못 해요. Claude한테 말로 설명하면서 게임 UI, 브랜드, 블로그까지 만들었어요. 색상 시스템, 타이포그래피, 그리고 프롬프트로 안 됐던 것들에 대한 이야기예요.
군대 연등시간에 깃허브 퍼블릭 레포지토리에 보안 키를 올렸던 아찔한 경험과 그로부터 배운 교훈을 솔직하게 공유합니다.
군대에 있는 디자이너가 아이패드와 휴대폰으로 AI를 이용해 브라우저 게임을 만들었습니다. 그리고 Reddit에 올리자마자 테트리스 커뮤니티에서 산산조각이 났죠. 그 과정에서 배운 것들, 망한 것들, 그리고 왜 그게 오히려 중요했는지에 대한 솔직한 이야기입니다.