소개
웹은 텍스트를 위한 매우 강력한 플랫폼이며, Adobe는 이 분야에서 풍부한 경험과 전문성을 보유하고 있습니다. 따라서 Adobe가 웹을 발전시킬 방법을 찾고 있을 때 웹의 텍스트 기능을 더욱 발전시키는 것이 당연한 출발점인 것처럼 보였습니다. 웹은 일반적으로 텍스트에 대해 단일 열, 세로 방향을 가정합니다. 그래픽 주위에 텍스트를 배치하고 CSS를 사용하여 텍스트를 여러 열로 서식 지정할 수도 있지만, 웹에서 실제 잡지와 같은 레이아웃을 구현하는 것은 여전히 매우 어렵습니다. Adobe는 CSS 영역과 CSS 제외를 통해 데스크톱 게시 기능을 최신 브라우저에 도입하는 데 앞장서고 있습니다. 예를 들어 아래 스크린샷에서는 CSS Exclusions를 사용하여 산의 윤곽선을 따라 텍스트를 흐르게 합니다.
아래 스크린샷의 문서에서는 CSS Exclusions를 사용하여 텍스트가 이미지의 도형을 감싸도록 하고, CSS Regions를 사용하여 텍스트를 열로 서식 지정하고 인용문을 감싸도록 합니다.
CSS 지역
CSS 영역에 대해 자세히 알아보기 전에 Google Chrome에서 영역을 사용 설정하는 방법을 살펴보겠습니다. CSS 리전을 사용 설정하면 이 도움말에서 참조하는 샘플을 사용해 보고 직접 만들 수 있습니다.
Chrome에서 CSS 영역 사용 설정
Chrome 버전 20 (정확히는 버전 20.0.1132.57)부터 CSS 영역은 chrome://flags 인터페이스를 통해 사용 설정됩니다. CSS 영역을 사용 설정하려면 다음 단계를 따르세요.
- Chrome에서 새 탭 또는 창을 엽니다.
- 위치 표시줄에
chrome://flags를 입력합니다. - 페이지에서 찾기 (Ctrl/Cmd + f)를 사용하여 'experimental Web Platform features' 섹션을 검색합니다.
- 사용 설정 링크를 클릭합니다.
- 하단의 지금 다시 실행 버튼을 클릭합니다.
Chrome 신고에 관한 자세한 내용은 Chrome 신고에 관한 모든 것 블로그 게시물을 참고하세요.
브라우저를 다시 실행하면 CSS 영역을 자유롭게 실험할 수 있습니다.
CSS 리전 개요
CSS 영역을 사용하면 의미론적으로 마크업된 텍스트 블록이 '상자' (현재 요소)로 자동으로 흐를 수 있습니다. 아래 다이어그램은 텍스트 (흐름)와 상자 (텍스트가 흐르는 영역)의 분리를 보여줍니다.
실제 CSS 영역 사용 사례를 살펴보겠습니다. 저는 Adobe의 개발자이자 공상과학 작가이기도 합니다. 저는 크리에이티브 커먼즈 라이선스에 따라 온라인에 제 작품을 자주 게시하며, 최대한 많은 기기와 브라우저에서 작동하도록 하기 위해 다음과 같이 매우 간단한 형식을 자주 사용합니다.
CSS 영역을 사용하여 시각적으로 더 흥미롭고 탐색하기 쉽고 읽기 편하기 때문에 훨씬 더 기능적인 환경을 만들 수 있었습니다.
데모를 위해 이 프로토타입에 CSS 영역을 표시하는 기능을 추가했습니다. 아래 스크린샷은 중앙의 그래픽과 인용구를 감싸는 열처럼 보이도록 영역이 정렬된 모습을 보여줍니다.
여기에서 이 프로토타입을 실험하고 소스 코드를 확인할 수 있습니다. 화살표 키를 사용하여 탐색하고 Esc 키를 눌러 지역을 표시합니다. 이전 프로토타입은 여기에서 확인할 수 있습니다.
이름이 지정된 흐름 만들기
텍스트 블록이 영역을 통해 흐르도록 하는 데 필요한 CSS는 매우 간단합니다. 아래 스니펫은 'article'이라는 이름의 명명된 흐름을 ID가 'content'인 div에 할당하고, 동일한 'article'이라는 이름의 명명된 흐름을 클래스가 'region'인 모든 요소에 할당합니다. 그 결과 'content' 요소 내에 포함된 텍스트가 'region' 클래스가 있는 모든 요소를 통해 자동으로 흐르게 됩니다.
<!DOCTYPE html>
<html>
<head>
<style>
#content {
{ % mixin flow-into: article; % }
}
.region {
{ % mixin flow-from: article; % }
box-sizing: border-box;
position: absolute;
width: 200px;
height: 200px;
padding: 10px;
}
#box-a {
border: 1px solid red;
top: 10px;
left: 10px;
}
#box-b {
border: 1px solid green;
top: 210px;
left: 210px;
}
#box-c {
border: 1px solid blue;
top: 410px;
left: 410px;
}
</style>
</head>
<body>
<div id="box-a" class="region"></div>
<div id="box-b" class="region"></div>
<div id="box-c" class="region"></div>
<div id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleifend dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, molestie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat consequat....
</div>
</body>
</html>
결과는 다음과 같습니다.
'content' div 내의 텍스트는 표시 방식에 관한 정보를 포함하지 않습니다. 즉, 여러 리전을 거치더라도 의미론적으로 완전히 온전하게 유지될 수 있습니다. 또한 영역은 요소일 뿐이므로 다른 요소와 마찬가지로 CSS를 사용하여 위치와 크기를 지정하므로 반응형 디자인 원칙과 완벽하게 호환됩니다. 요소를 이름이 지정된 흐름의 일부로 지정하면 지정된 텍스트가 자동으로 흐름을 통해 흐르게 됩니다.
CSS 객체 모델
CSS 객체 모델(CSSOM)은 CSS 작업을 위한 JavaScript API를 정의합니다. 다음은 CSS 영역과 관련된 새로운 API 목록입니다.
document.webkitGetNamedFlows(): 문서에서 사용할 수 있는 이름이 지정된 흐름의 컬렉션을 반환하는 함수입니다.document.webkitGetNamedFlows().namedItem("article"): 특정 이름이 지정된 흐름에 대한 참조를 반환하는 함수입니다. 인수는flow-into및from-fromCSS 속성의 값으로 지정된 이름에 해당합니다. 위 코드 스니펫에 지정된 명명된 흐름에 대한 참조를 가져오려면 문자열 'article'을 전달합니다.WebKitNamedFlow: 다음 속성과 함수가 있는 이름이 지정된 floe의 객체 표현입니다.firstEmptyRegionIndex: 이름이 지정된 흐름과 연결된 첫 번째 빈 영역의 색인을 가리키는 정숫값입니다. 리전 컬렉션을 가져오는 방법은 아래의getRegions()를 참조하세요.name: 흐름 이름이 포함된 문자열 값입니다.overset: 다음과 같은 불리언 속성입니다.false: 명명된 흐름의 콘텐츠가 연결된 영역에 맞는 경우true: 콘텐츠가 맞지 않고 모든 콘텐츠를 포함하는 데 더 많은 영역이 필요한 경우
getContent(): 이름이 지정된 흐름으로 유입되는 노드에 대한 참조가 포함된 컬렉션을 반환하는 함수입니다.getRegions(): 명명된 흐름의 콘텐츠를 보유하는 영역에 대한 참조가 포함된 컬렉션을 반환하는 함수입니다.getRegionsByContentNode(node): 지정된 노드가 포함된 리전에 대한 참조를 반환하는 함수입니다. 이는 이름이 지정된 앵커와 같은 항목이 포함된 영역을 찾는 데 특히 유용합니다.
webkitregionoversetchange이벤트 이 이벤트는 어떤 이유로든 (콘텐츠가 추가되거나 삭제됨, 글꼴 크기가 변경됨, 영역의 모양이 변경됨 등) 연결된 콘텐츠의 레이아웃이 변경되고 그로 인해 영역의webkitRegionOverset속성이 변경될 때마다WebkitNamedFlow에서 트리거됩니다. 이 이벤트는 대략적인 레이아웃 변경사항을 수신 대기하는 데 유용합니다. 이는 중요한 일이 발생했으며 레이아웃에 확인이 필요할 수 있음을 나타내는 지표입니다(예: 더 많은 영역이 필요함, 일부 영역이 비어 있을 수 있음 등).webkitregionfragmentchange이벤트 이 수정 시점에는 구현되지 않았습니다. 이 이벤트는webkitregionoversetchange과 유사하게 어떤 이유로든 연결된 콘텐츠의 레이아웃이 변경될 때마다WebkitNamedFlow에서 트리거되지만webkitRegionOverset속성의 변경과는 관계가 없습니다. 이 이벤트는 이름이 지정된 흐름의 전체 레이아웃에 영향을 미치지 않는 세분화된 레이아웃 변경사항을 수신 대기하는 데 유용합니다. 예를 들어 콘텐츠가 한 영역에서 다른 영역으로 이동하지만 전체 콘텐츠는 여전히 모든 영역에 맞습니다.Element.webkitRegionOverset: 요소에flow-fromCSS 속성이 할당되면 영역이 됩니다. 이러한 요소에는webkitRegionOverset속성이 있으며, 이 속성은 명명된 흐름의 일부인 경우 흐름의 콘텐츠가 영역을 오버플로하는지 여부를 나타냅니다. webkitRegionOverset의 가능한 값은 다음과 같습니다.- 영역에 담을 수 있는 것보다 더 많은 콘텐츠가 있는 경우 'overflow'
- 콘텐츠가 영역 끝 이전에 중지되는 경우 'fit'
- 콘텐츠가 리전에 도달하지 않은 경우 'empty'
CSSOM의 주요 용도 중 하나는 webkitregionoversetchange 이벤트를 수신 대기하고 다양한 양의 텍스트를 수용하기 위해 영역을 동적으로 추가하거나 삭제하는 것입니다. 예를 들어 서식을 지정할 텍스트의 양을 예측할 수 없거나 (사용자가 생성한 경우), 브라우저 창의 크기가 조절되거나, 글꼴 크기가 변경되는 경우 흐름의 변화를 수용하기 위해 영역을 추가하거나 삭제해야 할 수 있습니다. 또한 콘텐츠를 페이지로 구성하려면 DOM과 영역을 동적으로 수정하는 메커니즘이 필요합니다.
다음 JavaScript 코드 스니펫은 CSSOM을 사용하여 필요에 따라 영역을 동적으로 추가하는 방법을 보여줍니다. 간단히 설명하기 위해 영역을 삭제하거나 영역의 크기와 위치를 정의하는 작업은 처리하지 않습니다. 이 예시는 데모용입니다.
var flow = document.webkitGetNamedFlows().namedItem("article")
flow.addEventListener("webkitregionoversetchange", onLayoutUpdate);
function onLayoutUpdate(event) {
var flow = event.target;
// The content does not fit
if (flow.overset === true) {
addRegion();
} else {
regionLayoutComplete();
}
}
function addRegion() {
var region = document.createElement("div");
region.style = "flow-from: article";
document.body.appendChild(region);
}
function regionLayoutComplete() {
// Finish up your layout.
}
CSS 영역 샘플 페이지에서 더 많은 데모를 확인할 수 있습니다.
CSS 페이지 템플릿
CSSOM을 활용하는 것은 페이징 및 반응형 레이아웃과 같은 기능을 구현하는 가장 강력하고 유연한 방법일 수 있지만, Adobe는 디자이너와 개발자가 비교적 일반적인 페이징 기능을 더 쉽게 구현할 수 있는 방법을 원한다는 것을 알 수 있을 만큼 오랫동안 텍스트 및 데스크톱 게시 도구를 사용해 왔습니다. 따라서 Google은 페이징 동작을 완전히 선언적으로 정의할 수 있는 CSS 페이지 템플릿이라는 제안을 개발하고 있습니다.
CSS 페이지 템플릿의 일반적인 사용 사례를 살펴보겠습니다. 아래 코드 스니펫은 CSS를 사용하여 'article-flow'와 'timeline-flow'라는 두 개의 명명된 흐름을 만드는 방법을 보여줍니다. 또한 두 흐름이 포함될 'combined-articles'라는 세 번째 선택기를 정의합니다. 'combined-articles' 선택기 내에 overflow-style 속성을 포함하기만 하면 콘텐츠가 x축을 따라 또는 가로로 자동으로 페이징됩니다.
<style>
#article {
{ % mixin flow-into: article-flow; % }
}
#timeline {
{ % mixin flow-into: timeline-flow; % }
}
#combined-articles {
overflow-style: paged-x;
}
</style>
이제 흐름이 정의되고 원하는 오버플로 동작이 지정되었으므로 페이지 템플릿 자체를 만들 수 있습니다.
@template {
@slot left {
width: 35%;
float: left;
{ % mixin flow-from: article-flow; % }
}
@slot time {
width: 25%;
float: left;
{ % mixin flow-from: timeline-flow; % }
}
@slot right {
width: 35%;
float: left;
{ % mixin flow-from: article-flow; % }
}
}
페이지 템플릿은 새로운 'at' 문법을 사용하여 정의됩니다. 위의 코드 스니펫에서는 각각 열에 해당하는 슬롯 3개를 정의합니다. 'article-flow'의 텍스트는 왼쪽과 오른쪽 열을 통해 흐르고 'timeline-flow'의 텍스트는 가운데 열을 채웁니다. 결과는 다음과 같습니다.
기사 텍스트(왼쪽 및 오른쪽 열의 텍스트)는 영어이고 중앙의 타임라인은 독일어입니다. 또한 JavaScript 코드 없이도 문서가 가로로 페이지를 나눕니다. 모든 작업이 CSS에서 완전히 선언적으로 이루어졌습니다.
CSS 페이지 템플릿은 아직 제안 단계이지만, 지금 바로 실험해 볼 수 있도록 자바스크립트 '심' (일명 폴리필)을 사용하는 프로토타입이 있습니다.
일반적인 CSS 영역에 대해 자세히 알아보려면 html.adobe.com의 CSS 영역 페이지를 확인하세요.
CSS 제외
진정한 잡지 같은 레이아웃을 구현하려면 영역을 통해 텍스트를 흐르게 하는 것만으로는 충분하지 않습니다. 고품질의 시각적으로 흥미로운 데스크톱 출판의 중요한 요소는 불규칙한 그래픽과 도형 주위 또는 내부에 텍스트를 흐르게 하는 기능입니다. CSS Exclusions는 이러한 수준의 제작 품질을 웹에 제공합니다.
아래 스크린샷은 CSS 제외 프로토타입에서 가져온 것으로, 큰 암석의 윤곽과 일치하는 경로를 따라 텍스트가 동적으로 흐르는 모습을 보여줍니다.
다음 스크린샷은 불규칙한 모양의 다각형 내부에 흐르는 텍스트를 보여줍니다.
임의의 도형 주위나 내부에 텍스트를 배치할 수 있도록 하는 첫 번째 단계는 필요한 알고리즘을 개발하고 최적화하는 것입니다. Adobe는 현재 WebKit에 직접 기여할 구현을 개발 중입니다. 이러한 알고리즘이 최적화되면 나머지 CSS 제외가 구축되는 기반이 됩니다.
CSS 제외에 대한 자세한 내용은 html.adobe.com의 CSS 제외 페이지를 참고하고, CSS 제외의 기본 기술에 대한 Adobe의 작업에 대한 자세한 내용은 Hans Muller의 블로그 게시물 Horizontal Box: Polygon Intersection for CSS Exclusions를 참고하세요.
CSS 영역 및 CSS 제외 상태 (2012)
CSS 영역과 CSS 제외에 대해 처음 공개적으로 이야기한 것은 Google I/O 2011의 Adobe Developer Pod에서였습니다. 당시 저는 자체 커스텀 프로토타입 브라우저에서 데모를 보여주고 있었습니다. 반응은 매우 열광적이었지만, 제가 보여준 기능 중 어느 것도 아직 주요 브라우저에서 사용할 수 없다는 사실을 알게 된 사람들은 실망감을 감추지 못했습니다.
올해 (2012년)에도 Google I/O에 참석했는데, 이번에는 동료인 빈센트 하디와 Google의 알렉스 다닐로와 함께 발표자로 참석했습니다(여기에서 프레젠테이션을 시청할 수 있습니다). 불과 1년 후, CSS Regions 사양의 약 80% 가 WebKit에 구현되었으며 이미 최신 버전의 Chrome에 포함되어 있습니다 (CSS Regions는 현재 chrome://flags를 통해 사용 설정해야 함). CSS Regions에 대한 예비 지원은 Android용 Chrome에도 적용되었습니다.
또한 CSS 영역과 CSS 제외는 모두 Internet Explorer 10 프리뷰에 구현되어 있으며 현재 Mozilla의 2012년 Firefox 로드맵에 포함되어 있습니다. Safari의 다음 메이저 버전은 CSS Regions 사양의 대부분을 지원해야 하며, 이후 업데이트에는 나머지 부분이 포함되어야 합니다.
다음은 2011년 4월 W3C에 처음 제안한 이후 CSS 영역 및 CSS 제외와 관련하여 진행된 진행 상황의 자세한 타임라인입니다.
결론
Adobe는 InDesign과 같은 도구를 통해 텍스트, 글꼴, 데스크톱 출판 전반에 관한 풍부한 경험을 보유하고 있습니다. 웹은 이미 텍스트를 위한 매우 강력한 플랫폼이지만, Google은 지식과 경험을 활용하여 텍스트 표시를 더욱 발전시키고자 합니다. CSS 영역과 CSS 제외를 사용하면 콘텐츠의 의미론적 구조를 유지하면서 실제 잡지와 같은 레이아웃을 구현할 수 있으며, 궁극적으로는 훨씬 더 표현력이 풍부한 웹을 만들 수 있습니다.