개발자들은 날카로운 칼날 하나만 있으면 되는데도 맥가이버 칼을 만들려는 나쁜 습관이 있습니다. HTML 첫 줄을 쓰기도 전에 무거운 프론트엔드 프레임워크를 찾습니다. 애니메이션 라이브러리, 상태 관리 도구, 그리고 작은 기업 하나를 운영할 수 있을 만큼 강력한 빌드 파이프라인을 덕지덕지 붙입니다. 그러고는 왜 우리 포트폴리오 사이트가 화면을 그리는 데 3초나 걸리는지, 왜 모바일에서 내비게이션이 깨지는지, 왜 채용 담당자들이 우리가 몇 달 동안 만든 프로젝트를 보기도 전에 페이지를 이탈하는지 의아해합니다.
저는 최근 포트폴리오에서 다른 길을 택했습니다. 끝없는 의존성(dependencies)의 생태계에서 벗어나 시맨틱 HTML과 깔끔한 CSS만으로 사이트 전체를 구축했습니다. JavaScript 프레임워크도, 빌드 단계도, 서드파티 애니메이션 엔진도 사용하지 않았습니다. 오직 플랫폼 그 자체와 CSS Grid 및 Flexbox로 처리한 레이아웃, 그리고 속도와 명확성을 사후 고려 사항이 아닌 핵심 기능으로 다루는 디자인 철학만을 담았습니다.
결과물은 가볍고, 빠르며, 전문적입니다. 제가 어떤 방식으로 접근했는지 구체적으로 소개합니다.
기초부터 시작하기
대부분의 과잉 엔지니어링(over-engineering)은 기초 단계에서 시작됩니다. 포트폴리오는 싱글 페이지 애플리케이션(SPA)일 필요가 없습니다. 작업물을 보여주고, 연락 방법을 알리고, 방해되지 않게 존재하면 됩니다. 저는 시맨틱 HTML을 사용했습니다. 브라우저는 이미 nav, article, footer를 어떻게 렌더링해야 하는지 알고 있기 때문입니다. 적절한 작업에 적절한 요소를 사용하면 접근성, 검색 엔진 최적화(SEO), 반응형 동작을 사실상 무료로 얻을 수 있습니다. 또한 코드 양도 줄어듭니다. 5개의 ARIA 속성을 가진 div는 그저 button을 장황하게 흉내 낸 것에 불과합니다. 저는 그런 방식을 완전히 피했습니다.
레이아웃의 경우, CSS Grid와 Flexbox만으로도 충분합니다. Grid는 거시적 구조, 즉 전체 페이지 섹션, 프로젝트 갤러리, 주요 블록의 정렬을 담당합니다. Flexbox는 미시적 상호작용, 즉 캡슐 내부의 내비게이션 링크, 카드 내 텍스트 중앙 정렬, 뷰포트 하단으로 푸터 밀어내기 등을 관리합니다. 이 둘을 함께 사용하면 2018년에 12컬럼 그리드 프레임워크를 임포트해야 했던 모든 이유를 대체할 수 있습니다. 코드는 읽기 쉬운 상태를 유지하고, CSS 파일 크기는 작게 유지됩니다.
색상, 타이포그래피, 그리고 절제
저는 포트폴리오가 로드되는 순간 차분한 느낌을 주길 원했습니다. 배경은 은은한 라디얼 그라데이션(radial gradients)이 들어간 밝은 베이스를 사용합니다. 공격적인 요소는 없습니다. 그라데이션은 낮은 불투명도로 적용되어, 페이지가 평면적으로 보이지 않게 부드러운 깊이감을 주면서도 시선을 강요하지 않습니다. 순수 CSS이기 때문에 즉시 로드됩니다. 압축해야 할 히어로 이미지도, 관리해야 할 WebP 폴백(fallback)도, 설정해야 할 JavaScript 지연 로딩(lazy-loading) 라이브러리도 없습니다.
타이포그래피가 개성을 부여합니다. 저는 Outfit과 Ovo를 조합했습니다. 기하학적 산세리프(geometric sans-serif)인 Outfit은 내비게이션 레이블, 버튼 텍스트, 본문, 메타 정보 등 모든 UI 텍스트를 담당합니다. 화면에서 선명하게 보이며 작은 크기에서도 가독성이 유지됩니다. 중간 정도의 대비를 가진 세리프(serif)인 Ovo는 헤더와 주요 제목에 사용됩니다. 이 조합은 페이지에 차분한 에디토리얼(editorial) 느낌을 줍니다. 테마를 입힌 것이 아니라 디자인된 것처럼 보입니다. 가장 중요한 점은, 두 폰트 모두 폰트 서비스 호출 한 번이나 셀프 호스팅된 파일로 로드된다는 것입니다. 레이아웃 시프트(layout shift)나 스타일이 적용되지 않은 텍스트가 깜빡이는 현상(FOUT), 초기 렌더링 후 스크립트가 폰트 두께를 교체하는 현상이 발생하지 않습니다.
플로팅 캡슐 메뉴
내비게이션은 포트폴리오가 스스로의 무게를 이기지 못하고 무너지는 지점입니다. 전체 화면 오버레이 메뉴, 단계별 애니메이션 스크립트, 그리고 클래스를 토글하기 위해 40줄의 JavaScript가 필요한 햄버거 아이콘 같은 것들 말이죠. 저는 그런 것들을 전혀 원하지 않았습니다.
저는 플로팅 글래스모피즘(glassmorphic) 캡슐 메뉴를 만들었습니다. 가장자리가 둥근 단일 가로 컨테이너이며, 뷰포트 상단 근처에 fixed로 배치됩니다. 글래스모피즘 효과는 반투명한 배경색과 backdrop-filter: blur() 속성에서 나옵니다. 콘텐츠를 가리지 않으면서 그 위에 떠 있으며, 모든 섹션에 즉시 접근할 수 있게 해주고, 전체적인 재설계 없이도 작은 뷰포트에서 우아하게 축소됩니다. 캔버스(canvas) 라이브러리가 아닌 브라우저가 합성(compositing)을 처리하기 때문에 효과가 현대적으로 보입니다.
