Opkle(옵클) - 창작자를 위한 앱과 시스템
옵클(Opkle)은 창작자를 위한 다양한 앱과 시스템을 제공하는 개발사입니다. 전자책 에디터 앱 'Opkle editor'를 출시했고, 관련 전자책 클래스를 제공하고 있습니다.
EDITOR
CLASS
BLOG
LOGIN
표현한다는 것의
무한한 가능성,
새로운 형태로
담아내다.
새로운 형태의 콘텐츠
Opkle은 코드 없이 웹을 마음껏 만들고, 누구나 자기 화면을 그릴 수 있도록 에디터를 만들고, 그 결과물을 어디서나 즐길 수 있게 돕는 팀입니다.
텍스트와 화면과의 조화를 통해, 웹을 짓는다는 것이 그저 단순한 코딩이 아닌, 상상을 펼치고 감각을 깨우는 과정이 될 수 있도록 좋은 도구를 만들어 냅니다.
옵클 에디터 개발기: 첫 번째 구현은 코드 편집기였습니다
dev
2
옵클 에디터 개발기: 미리보기는 곧 또 하나의 편집기였습니다
dev
3
옵클 에디터 개발기: 미디어쿼리까지 편집하는 EPUB 에디터
dev
4
옵클 에디터 개발기: CSS 애니메이션으로 영상을 흡수하는 방식
dev
5
옵클 에디터 개발기: 책을 만들기 위한 LLM을 설계하다
dev
6
6
7
8
9
10
...
4
옵클 에디터 개발기: 미디어쿼리까지 편집하는 EPUB 에디터
여러 개의 Shadow DOM preview를 동시에 동기화하는 구조가 잡히고 나자, 다음 가능성이 바로 보였습니다. 이 에디터는 단순히 EPUB을 미리 보여 주는 수준에서 끝날 필요가 없었습니다. 오히려 EPUB3에서 중요한 미디어쿼리 대응을 편집 과정 안으로 끌어올 수 있었습니다. 모바일, 태블릿, 데스크탑 화면을 동시에 보면서 같은 문서를 편집하고, 각 화면 조건에서 다른 레이아웃과 이미지를 확인하는 에디터가 될 수 있었습니다.
EPUB에서 미디어쿼리는 부가 기능이 아닙니다. 독자는 휴대폰 크기의 화면에서 읽을 수도 있고, 태블릿이나 리더기에서 읽을 수도 있으며, 앱의 설정에 따라 라이트 모드와 다크 모드를 오갈 수도 있습니다. 일반 웹페이지라면 브라우저 viewport 몇 개를 기준으로 검수하면 되지만, EPUB은 reading system의 환경과 독자 설정을 더 많이 받습니다. 그래서 편집기는 단일 화면에서 예쁜지 보는 도구가 아니라, 여러 읽기 조건에서 책의 구조가 어떻게 살아남는지 확인하는 도구가 되어야 했습니다.
저는 이 구조를 모바일, 태블릿, 데스크탑이라는 viewport 축과 라이트 모드, 다크 모드라는 color scheme 축으로 나누어 잡았습니다. 이렇게 하면 사실상 여섯 가지 주요 preview target이 생깁니다. 모바일 라이트, 모바일 다크, 태블릿 라이트, 태블릿 다크, 데스크탑 라이트, 데스크탑 다크입니다. 각각의 Shadow DOM은 같은 document state를 바라보되, 서로 다른 media condition과 color condition 아래에서 렌더링됩니다. 이때부터 옵클 에디터는 본문만 편집하는 도구가 아니라, 미디어쿼리 상태까지 실시간으로 검수하고 조정하는 편집기가 되었습니다.
preview target을 화면 크기와 색상 모드로
기존 미리보기는 모바일과 태블릿을 동시에 보는 구조에서 시작했습니다. 여기에 데스크탑 preview까지 포함하면 기본 viewport 축이 세 개가 됩니다. 각 preview는 shadowRoot를 따로 갖고, 같은 XHTML과 CSS 상태를 기준으로 렌더링됩니다. 하지만 실제 EPUB 읽기에서는 화면 크기만큼이나 라이트 모드와 다크 모드도 중요합니다. 그래서 color scheme을 별도의 축으로 분리했습니다.
구조는 단순하게 잡았습니다. document state는 하나이고, preview target은 여러 개입니다. 각 target은 viewport profile과 color profile을 가집니다. viewport profile은 모바일, 태블릿, 데스크탑 같은 폭과 높이 조건을 갖고, color profile은 light 또는 dark를 가집니다. 렌더링할 때는 같은 block tree를 사용하되, shadowRoot에 주입되는 CSS context와 root attribute를 다르게 둡니다. 예를 들어 preview root에 `data-view="mobile"`과 `data-theme="dark"` 같은 상태를 부여하면, CSS는 그 조건에 맞게 적용됩니다.
이렇게 하면 편집 이벤트의 흐름이 깔끔해집니다. 사용자가 모바일 다크 preview에서 문단을 고쳐도 원본 document state가 바뀌고, 그 결과가 다른 다섯 개의 preview target에 다시 투영됩니다. 반대로 데스크탑 라이트에서 이미지 레이아웃을 바꿔도 같은 상태가 저장되고, 각 target은 자기 조건에 맞는 결과를 보여 줍니다. 화면은 여섯 개지만 문서는 하나입니다.
라이트/다크 토글도 이 구조 안에서 자연스럽게 들어왔습니다. 버튼을 누르면 단순히 에디터 UI 테마만 바꾸는 것이 아니라, EPUB 본문 preview의 color condition도 바뀌어야 했습니다. 다크 모드에서 배경, 글자색, 링크 색, 이미지 대비, 표의 선 색이 어떻게 보이는지 바로 확인할 수 있어야 했습니다. 토글은 UI 편의 기능이 아니라 EPUB의 실제 읽기 조건을 전환하는 장치였습니다.
라이트 모드와 다크 모드
다크 모드를 별도의 문서처럼 관리하면 금방 복잡해집니다. 같은 본문에 대해 라이트용 XHTML과 다크용 XHTML이 따로 생기면 안 됩니다. EPUB은 하나의 본문 구조를 유지하고, CSS 조건에 따라 표현이 달라져야 합니다. 그래서 라이트/다크는 HTML을 복제하는 방식이 아니라, CSS state와 media query, theme attribute의 조합으로 처리했습니다.
핵심은 본문 구조를 유지한 채 표현 계층만 바꾸는 것이었습니다. `prefers-color-scheme`에 대응하는 CSS를 만들고, 에디터 preview에서는 명시적인 theme state를 넣어 라이트와 다크를 강제로 전환할 수 있게 했습니다. reading system에서는 사용자 설정을 따를 수 있고, 에디터 안에서는 버튼으로 각각의 모드를 직접 확인할 수 있습니다. 이렇게 하면 실제 EPUB에 들어갈 CSS와 편집기 preview가 같은 원칙으로 움직입니다.
색상만 바꾸는 것으로는 충분하지 않았습니다. 다크 모드에서는 이미지의 밝기와 대비, 표의 border, 강조 배경, 링크 색, 캡션의 회색 단계가 모두 달라질 수 있습니다. 특히 책 안의 이미지는 라이트 배경에서는 잘 보이지만 다크 배경에서는 떠 보이거나 반대로 묻힐 수 있습니다. 그래서 이미지와 표는 일반 문단보다 더 적극적으로 media condition과 theme condition을 받아야 했습니다.
이 구조를 잡고 나니 검수가 훨씬 명확해졌습니다. 한 화면에서 모바일 라이트만 보고 “괜찮다”고 판단하지 않아도 됩니다. 같은 문단과 같은 이미지가 여섯 개 조건에서 동시에 보이고, 편집 즉시 모든 조건이 갱신됩니다. EPUB의 미디어쿼리를 코드로만 작성하는 것이 아니라, 에디터 안에서 직접 보고 조정하는 구조가 만들어졌습니다.
여섯 조건을 함께 들고 다니는 컴포넌트
가장 중요한 부분은 이미지였습니다. EPUB에서 이미지는 단순히 하나의 `img src`로 끝나지 않습니다. 모바일에서는 세로로 잘린 이미지가 더 적합할 수 있고, 태블릿에서는 여백이 있는 이미지가 좋을 수 있으며, 데스크탑에서는 더 넓은 비율의 이미지가 필요할 수 있습니다. 여기에 라이트 모드와 다크 모드까지 들어오면, 같은 장면에 대해 최대 여섯 개의 이미지 variant가 필요해집니다.
해법은 명확했습니다. 이미지를 하나의 파일 참조로 보지 않고, 여러 variant를 함께 들고 다니는 컴포넌트로 만들면 됩니다. 이미지 block은 내부적으로 모바일 라이트, 모바일 다크, 태블릿 라이트, 태블릿 다크, 데스크탑 라이트, 데스크탑 다크에 대응하는 resource reference를 가질 수 있습니다. 사용자가 이미지를 추가하거나 생성할 때부터 이 컴포넌트 구조로 들어가면, 나중에 media query 대응을 억지로 덧붙일 필요가 없습니다.
이 컴포넌트는 XHTML에서는 하나의 image block처럼 보이지만, 내부 state에는 여러 resource path가 들어 있습니다. CSS는 viewport와 theme 조건에 따라 어떤 variant를 보여 줄지 결정합니다. 구현 방식은 상황에 따라 `picture/source` 계열로 갈 수도 있고, CSS background와 class 조합으로 갈 수도 있으며, 에디터 내부에서는 data attribute를 통해 현재 target에 맞는 resource를 선택할 수도 있습니다. 중요한 것은 “이미지 하나를 넣는다”는 사용자 행동 뒤에, 여러 읽기 조건을 품은 이미지 모델이 있다는 점이었습니다.
OPF manifest도 이 구조에 맞춰 갱신되어야 했습니다. variant가 여섯 개라면 여섯 리소스가 모두 패키지에 포함되어야 하고, 각각의 media-type과 path가 정확히 등록되어야 합니다. 이미지 생성이나 교체가 일어나면 component state, resource store, manifest state, preview DOM이 함께 바뀝니다. 3편에서 만든 동기화 구조가 있었기 때문에 이 흐름은 자연스럽게 이어졌습니다.
이 방식은 아주 단단했습니다. 사용자는 모바일 다크용 이미지를 바꾸고, 동시에 데스크탑 라이트에서는 다른 이미지를 유지할 수 있습니다. 에디터는 각 preview target에서 올바른 variant를 보여 주고, 저장 시에는 component state와 manifest를 함께 보존합니다. 미디어쿼리 CSS만 철저하게 작성하면, EPUB 안에서도 같은 원칙이 유지됩니다.
이미지 생성도 컴포넌트 기준으로
이미지 컴포넌트를 표준으로 잡고 나니, 이미지 생성 자체도 바뀌어야 했습니다. 예전처럼 하나의 이미지를 만들고 본문에 넣는 방식이면 반응형 EPUB에 충분하지 않습니다. 처음부터 이 이미지가 어떤 조건에서 쓰일지 알고 있어야 합니다. 모바일에서 필요한 비율, 태블릿에서 필요한 여백, 데스크탑에서 필요한 해상도, 다크 모드에서 필요한 대비를 함께 생각해야 합니다.
그래서 이미지 생성 흐름도 component state를 기준으로 설계했습니다. 사용자가 하나의 이미지 block을 만들면, 그 block은 단일 파일이 아니라 variant container가 됩니다. 이후 각 조건에 맞는 이미지를 생성하거나 교체할 수 있고, preview target을 보며 바로 확인할 수 있습니다. 모바일 다크 preview에서 이미지가 너무 밝으면 해당 variant만 교체하고, 데스크탑 라이트 preview는 그대로 둘 수 있습니다.
이 구조는 창작자에게도 좋고, EPUB 패키지에도 좋습니다. 창작자는 “어떤 화면에서 어떤 이미지가 보이는지”를 직접 보며 조정할 수 있고, 내부적으로는 모든 variant가 명시적인 resource로 관리됩니다. export할 때도 어떤 이미지가 어디에서 쓰이는지 추적하기 쉽습니다. manifest 누락이나 잘못된 참조가 생기지 않도록, component state에서 OPF 등록까지 하나의 흐름으로 묶을 수 있습니다.
결과적으로 이미지는 EPUB 안에서 훨씬 더 적극적인 표현 단위가 되었습니다. 단일 이미지가 모든 화면에 억지로 맞춰지는 것이 아니라, 읽기 환경에 따라 다른 이미지를 보여 줄 수 있는 구조가 되었습니다. 이 부분은 옵클 에디터가 EPUB3의 장점을 실제 제작 경험으로 끌어온 중요한 지점이었습니다.
flex layout과 반응형 구조
표도 중요한 문제였습니다. EPUB에서 표는 작은 화면에서 자주 무너집니다. 데스크탑이나 태블릿에서는 가로로 나란히 놓인 구조가 자연스럽지만, 모바일에서는 같은 구조가 너무 좁아지고 글자가 작아지거나 가로 스크롤을 만들 수 있습니다. 일반적인 HTML table을 그대로 쓰면 reading system마다 표현 차이도 커질 수 있습니다.
그래서 표와 표 비슷한 레이아웃은 flex 기반의 component로 다루는 쪽이 안정적이었습니다. 데스크탑과 태블릿에서는 `flex-direction: row`로 각 cell이나 column을 나란히 두고, 모바일에서는 `flex-direction: column`으로 세로 흐름을 만들 수 있습니다. 같은 정보 구조를 유지하면서도, 읽기 조건에 따라 배치만 바뀝니다. 이 방식은 EPUB의 reflowable reading과도 잘 맞았습니다.
중요한 것은 표를 단순히 “예쁘게 보이는 박스”로 만들지 않는 것이었습니다. 내부적으로는 row, column, cell의 의미를 유지하고, preview에서는 block처럼 편집할 수 있어야 했습니다. 사용자가 모바일 preview에서 표를 보면 각 항목이 세로로 차분히 이어지고, 태블릿이나 데스크탑에서는 비교하기 좋게 나란히 놓입니다. CSS media query는 이 구조의 표현만 바꿉니다.
이 표 컴포넌트도 이미지와 같은 원칙으로 움직였습니다. document state에는 정보 구조가 있고, CSS state에는 viewport별 배치 규칙이 있으며, preview target은 그 조합을 렌더링합니다. 사용자가 표의 내용을 고치면 모든 preview에 반영되고, 사용자가 레이아웃 옵션을 바꾸면 CSS rule이 갱신됩니다. `row`와 `column`의 전환은 단순한 스타일 변경처럼 보이지만, 실제로는 EPUB에서 작은 화면을 안정적으로 지원하는 핵심 장치였습니다.
미디어쿼리를 직접 편집 경험으로
이 단계에서 옵클 에디터는 미디어쿼리를 개발자가 코드로 작성한 뒤 나중에 확인하는 방식에서 벗어났습니다. 모바일, 태블릿, 데스크탑 preview가 동시에 보이고, 라이트/다크 모드가 버튼으로 전환되며, 이미지와 표 컴포넌트가 각 조건에 맞게 반응합니다. 사용자는 결과를 보면서 편집하고, 에디터는 그 결과를 XHTML, CSS, resource store, OPF manifest, IndexedDB에 일관되게 반영합니다.
기술적으로는 상태 축을 잘 나누는 것이 핵심이었습니다. document state는 본문의 의미 구조를 담당합니다. media state는 viewport 조건을 담당합니다. theme state는 라이트/다크 모드를 담당합니다. resource state는 이미지와 폰트 variant를 담당합니다. CSS serialization은 이 state들을 EPUB 안에서 재현 가능한 규칙으로 바꿉니다. 각 Shadow DOM preview는 이 state 조합을 렌더링한 결과입니다.
이렇게 정리하면 시스템은 매우 견고해집니다. 어떤 preview에서 편집하든 원본은 하나이고, 어떤 모드로 보든 각 조건은 명확합니다. 모바일 다크에서 이미지가 바뀌어도 데스크탑 라이트가 흔들리지 않고, 표의 모바일 column layout을 바꿔도 태블릿 row layout은 자기 규칙을 유지합니다. 동시에 모든 리소스와 CSS는 export 가능한 EPUB 구조 안으로 들어갑니다.
결과적으로 미디어쿼리 대응은 완성도 있게 잡혔습니다. 모바일, 태블릿, 데스크탑과 라이트, 다크 조합을 동시에 검수하면서 편집할 수 있었고, 이미지 variant와 flex 기반 표 레이아웃도 EPUB 패키지 안에서 안정적으로 동작했습니다. 반복 검수에서도 preview, CSS, manifest, IndexedDB 저장 상태가 일관되게 맞아 들어갔습니다. 이때부터 옵클 에디터는 단순히 EPUB을 만드는 도구가 아니라, EPUB3의 반응형 표현력을 실제로 편집할 수 있는 시스템이 되었습니다.
이전글
목록으로
다음글
저작권 고시
Copyright Notice
본 웹사이트의 모든 디자인 결과물 및 영상에 대한 저작권은 Abstract Cloud에 있으며, 저작권법 및 관련 법령에 의해 보호받습니다. 웹, 영상, 본문, 표지, 내지 디자인을 포함한 모든 콘텐츠는 저작권자의 자산으로, 사전 동의 없이 무단 복제, 배포, 2차 저작물 제작, 온라인 공유 등을 금지합니다. 이를 위반할 시, 저작권법에 따라 민형사상 책임을 질 수 있습니다. 정당한 구매와 저작권 보호는 창작자의 권리를 지키며, 더 나은 작품으로 보답할 힘이 됩니다.
저작권자: Abstract Cloud | 대표자: 배창규(uragen)
© Abstract Cloud. All Rights Reserved.
HOME
FAQ
이용 약관
개인정보 이용방침
help@opkle.app
010-2747-3403
상호 :
추상적 형상 디자인(Abstract cloud) |
대표자 :
배창규
사업자등록번호 :
249-74-00533
통신판매업 신고번호 :
2025-의정부송산-0634
주소 :
경기도 의정부시 부용로 49, 108동 402호
웹의 모든 콘텐츠, 디자인, 소스 코드에 대한
저작권은 Opkle에게 있습니다.