Giới thiệu
Web là một nền tảng cực kỳ mạnh mẽ cho văn bản, một lĩnh vực mà Adobe có rất nhiều kinh nghiệm và chuyên môn. Do đó, khi Adobe tìm cách giúp web phát triển, việc nâng cao hơn nữa khả năng xử lý văn bản của web có vẻ là một điểm khởi đầu hiển nhiên cho chúng tôi. Web thường giả định một cột, hướng dọc cho văn bản. Mặc dù có thể cho văn bản chạy quanh hình ảnh và thậm chí định dạng văn bản thành nhiều cột bằng CSS, nhưng vẫn rất khó để có được bố cục giống như tạp chí thực sự trên web. Với CSS Regions và CSS Exclusions, Adobe đang đi đầu trong nỗ lực mang sức mạnh của tính năng xuất bản trên máy tính đến các trình duyệt hiện đại. Ví dụ: trong ảnh chụp màn hình bên dưới, CSS Exclusions đang được dùng để văn bản chạy dọc theo đường viền của ngọn núi:
Tài liệu trong ảnh chụp màn hình bên dưới cũng sử dụng CSS Exclusions để cho phép văn bản ngắt dòng xung quanh các hình dạng trong hình ảnh, cũng như CSS Regions để định dạng văn bản thành các cột và xung quanh một đoạn trích dẫn:
Khu vực CSS
Trước khi đi vào chi tiết về Vùng CSS, tôi muốn trình bày cách bật vùng trong Google Chrome. Sau khi bật CSS Regions, bạn có thể thử một số mẫu được tham chiếu trong bài viết này và tạo mẫu của riêng bạn.
Bật CSS Regions trong Google Chrome
Kể từ phiên bản 20 của Chrome (chính xác là phiên bản 20.0.1132.57), CSS Regions được bật thông qua giao diện chrome://flags. Để bật CSS Regions, hãy làm theo các bước sau:
- Mở một thẻ hoặc cửa sổ mới trong Chrome.
- Nhập
chrome://flagsvào thanh vị trí. - Sử dụng tính năng tìm trong trang (control/command + f) rồi tìm mục "experimental Web Platform features" (các tính năng thử nghiệm của Nền tảng web).
- Nhấp vào đường liên kết Bật.
- Nhấp vào nút Khởi chạy lại ngay ở dưới cùng.
Để biết thêm thông tin về cờ của Chrome, hãy xem bài đăng trên blog của tôi về Tất cả về cờ Chrome.
Sau khi khởi chạy lại trình duyệt, bạn có thể bắt đầu thử nghiệm với CSS Regions.
Tổng quan về CSS Regions
CSS Regions cho phép một khối văn bản được đánh dấu theo ngữ nghĩa tự động chuyển vào "hộp" (hiện là các phần tử). Sơ đồ dưới đây minh hoạ việc tách văn bản (luồng) và hộp (vùng mà văn bản chảy vào):
Hãy cùng xem một trường hợp sử dụng CSS Regions thực tế. Ngoài việc là nhà phát triển tại Adobe, tôi còn là một nhà văn viết truyện khoa học viễn tưởng. Tôi thường xuyên xuất bản tác phẩm của mình trên mạng theo giấy phép Creative Commons. Để tác phẩm có thể hoạt động trên nhiều thiết bị và trình duyệt nhất có thể, tôi thường sử dụng một định dạng cực kỳ đơn giản như sau:
Bằng cách sử dụng CSS Regions, tôi có thể tạo ra một trải nghiệm vừa thú vị hơn về mặt hình ảnh, vừa hữu ích hơn nhiều vì dễ điều hướng và dễ đọc hơn:
Để minh hoạ, tôi đã thêm khả năng hiển thị Vùng CSS trong nguyên mẫu này. Ảnh chụp màn hình bên dưới cho thấy cách sắp xếp các vùng để tạo cảm giác như các cột bao quanh một hình ảnh và một đoạn trích dẫn ở giữa:
Bạn có thể thử nghiệm nguyên mẫu này (cũng như xem mã nguồn) tại đây. Dùng các phím mũi tên để di chuyển và nhấn phím Esc để hiện các khu vực. Bạn cũng có thể xem các nguyên mẫu trước đó tại đây.
Tạo luồng có tên
CSS cần thiết để một khối văn bản di chuyển qua các vùng là cực kỳ đơn giản. Đoạn mã dưới đây chỉ định một luồng có tên là "article" cho một div có mã nhận dạng là "content" và chỉ định cùng một luồng có tên là "article" cho bất kỳ phần tử nào có lớp "region". Kết quả là văn bản có trong phần tử "content" sẽ tự động chuyển qua bất kỳ phần tử nào có lớp "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>
Kết quả sẽ có dạng như sau:
Lưu ý rằng văn bản bên trong div "nội dung" không có bất kỳ thông tin nào về cách trình bày. Nói cách khác, dữ liệu có thể giữ nguyên ngữ nghĩa ngay cả khi được truyền qua nhiều khu vực. Ngoài ra, vì các vùng chỉ là phần tử, nên chúng được định vị và định kích thước bằng CSS giống như mọi phần tử khác, do đó hoàn toàn tương thích với các nguyên tắc thiết kế đáp ứng. Việc chỉ định các phần tử là một phần của luồng được đặt tên chỉ đơn giản là văn bản được chỉ định sẽ tự động chạy qua các phần tử đó.
Mô hình đối tượng CSS
Mô hình đối tượng CSS (CSSOM) xác định các API JavaScript để làm việc với CSS. Dưới đây là danh sách các API mới liên quan đến CSS Regions:
document.webkitGetNamedFlows(): Hàm trả về tập hợp các luồng được đặt tên có trong tài liệu.document.webkitGetNamedFlows().namedItem("article"): Hàm trả về tệp đối chiếu đến một luồng cụ thể có tên. Đối số tương ứng với tên được chỉ định làm giá trị của thuộc tính CSSflow-intovàfrom-from. Để tham chiếu đến luồng được đặt tên trong đoạn mã ở trên, bạn cần truyền chuỗi "article".WebKitNamedFlow: Biểu diễn đối tượng của một tảng băng trôi có tên với các thuộc tính và hàm sau:firstEmptyRegionIndex: Một giá trị số nguyên trỏ đến chỉ mục của vùng trống đầu tiên liên kết với luồng được đặt tên. Hãy xemgetRegions()bên dưới để tìm hiểu cách lấy tập hợp các khu vực.name: Giá trị chuỗi có tên của luồng.overset: Thuộc tính boolean:falsekhi nội dung của luồng được đặt tên vừa với các vùng liên kếttruekhi nội dung không vừa và cần thêm vùng để chứa tất cả nội dung.
getContent(): Hàm trả về một tập hợp có tham chiếu đến các nút chuyển vào luồng được đặt tên.getRegions(): Hàm trả về một tập hợp có tham chiếu đến các vùng chứa nội dung của luồng được đặt tên.getRegionsByContentNode(node): Hàm trả về tệp đối chiếu đến vùng chứa nút đã chỉ định. Điều này đặc biệt hữu ích khi tìm các vùng chứa những nội dung như neo được đặt tên.
webkitregionoversetchangesự kiện. Sự kiện này được kích hoạt trênWebkitNamedFlowbất cứ khi nào bố cục của nội dung liên quan thay đổi vì bất kỳ lý do gì (nội dung được thêm hoặc xoá, cỡ chữ thay đổi, hình dạng của vùng thay đổi, v.v.) và khiến thuộc tínhwebkitRegionOversetcủa một vùng thay đổi. Sự kiện này rất hữu ích khi theo dõi các thay đổi về bố cục thô. Đây là chỉ báo cho biết đã xảy ra một sự kiện quan trọng và bố cục có thể cần chú ý, chẳng hạn như: cần thêm vùng, một số vùng có thể trống, v.v.webkitregionfragmentchangesự kiện. Chưa được triển khai tại thời điểm chỉnh sửa này. Sự kiện này được kích hoạt trênWebkitNamedFlowbất cứ khi nào bố cục của nội dung liên quan thay đổi vì bất kỳ lý do gì, tương tự nhưwebkitregionoversetchange, nhưng bất kể có thay đổi nào trong các thuộc tínhwebkitRegionOversethay không. Sự kiện này rất hữu ích khi bạn muốn theo dõi những thay đổi nhỏ về bố cục mà không nhất thiết ảnh hưởng đến toàn bộ bố cục của luồng được đặt tên, ví dụ: nội dung di chuyển từ vùng này sang vùng khác, nhưng nội dung tổng thể vẫn vừa với tất cả các vùng.Element.webkitRegionOverset: Các phần tử trở thành vùng khi được chỉ định thuộc tính CSSflow-from. Các phần tử này có thuộc tínhwebkitRegionOverset. Nếu các phần tử này thuộc một luồng có tên, thì thuộc tính này cho biết nội dung của một luồng có tràn ra khỏi vùng hay không. Các giá trị có thể có của webkitRegionOverset là:- "overflow" nếu có nhiều nội dung hơn mức mà khu vực có thể chứa
- "vừa" nếu nội dung dừng trước khi kết thúc vùng
- "empty" nếu nội dung chưa đến vùng
Một trong những mục đích sử dụng chính của CSSOM là theo dõi các sự kiện webkitregionoversetchange và tự động thêm hoặc xoá các vùng để phù hợp với nhiều lượng văn bản. Ví dụ: nếu lượng văn bản cần định dạng không thể dự đoán trước (có thể do người dùng tạo), nếu cửa sổ trình duyệt được đổi kích thước hoặc nếu cỡ chữ thay đổi, thì có thể cần phải thêm hoặc xoá các vùng để phù hợp với thay đổi trong luồng. Ngoài ra, nếu muốn sắp xếp nội dung thành các trang, bạn sẽ cần một cơ chế để sửa đổi DOM cũng như các vùng của bạn một cách linh động.
Đoạn mã JavaScript sau đây minh hoạ cách sử dụng CSSOM để thêm các khu vực một cách linh động khi cần. Xin lưu ý rằng để đơn giản, lớp này không xử lý việc xoá vùng hoặc xác định kích thước và vị trí của vùng; lớp này chỉ dành cho mục đích minh hoạ.
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.
}
Bạn có thể xem thêm các bản minh hoạ trên trang mẫu CSS Regions.
Mẫu trang CSS
Việc tận dụng CSSOM có lẽ là cách mạnh mẽ và linh hoạt nhất để triển khai những thứ như phân trang và bố cục thích ứng, nhưng Adobe đã làm việc với các công cụ xuất bản văn bản và máy tính đủ lâu để biết rằng các nhà thiết kế và nhà phát triển cũng sẽ muốn có một cách dễ dàng hơn để có được các chức năng phân trang tương đối chung chung. Do đó, chúng tôi đang nghiên cứu một đề xuất có tên là Mẫu trang CSS, cho phép xác định hành vi phân trang hoàn toàn theo cách khai báo.
Hãy cùng xem một trường hợp sử dụng phổ biến cho Mẫu trang CSS. Đoạn mã dưới đây cho thấy cách sử dụng CSS để tạo hai luồng có tên: "article-flow" và "timeline-flow". Ngoài ra, nó còn xác định một bộ chọn thứ ba có tên là "combined-articles" (bài viết kết hợp) chứa hai luồng. Việc chỉ cần thêm thuộc tính overflow-style vào bên trong bộ chọn "combined-articles" cho biết rằng nội dung sẽ tự động được phân trang dọc theo trục x hoặc theo chiều ngang:
<style>
#article {
{ % mixin flow-into: article-flow; % }
}
#timeline {
{ % mixin flow-into: timeline-flow; % }
}
#combined-articles {
overflow-style: paged-x;
}
</style>
Giờ đây, khi đã xác định được các luồng và chỉ định hành vi tràn mong muốn, chúng ta có thể tạo mẫu trang:
@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; % }
}
}
Mẫu trang được xác định bằng cú pháp "at" mới. Trong đoạn mã trên, chúng ta xác định 3 vùng, mỗi vùng tương ứng với một cột. Văn bản từ "article-flow" sẽ xuất hiện trong các cột ở bên trái và bên phải, còn văn bản từ "timeline-flow" sẽ xuất hiện trong cột ở giữa. Kết quả có thể có dạng như sau:
Lưu ý rằng văn bản của bài viết (văn bản ở cột bên trái và bên phải) là tiếng Anh, còn dòng thời gian ở giữa là tiếng Đức. Ngoài ra, tài liệu sẽ phân trang theo chiều ngang mà không cần mã JavaScript. Mọi thứ đều được thực hiện hoàn toàn theo cách khai báo trong CSS.
Mẫu trang CSS vẫn là một đề xuất, tuy nhiên, chúng tôi có một nguyên mẫu sử dụng "shim" JavaScript (còn gọi là polyfill) để cho phép bạn thử nghiệm ngay bây giờ.
Để tìm hiểu thêm về CSS Regions nói chung, hãy xem trang CSS Regions trên html.adobe.com.
Tiêu chí loại trừ CSS
Để có được bố cục giống như tạp chí thực sự, chỉ có thể chuyển văn bản qua các vùng là chưa đủ. Một yếu tố quan trọng của việc xuất bản trên máy tính có chất lượng cao và hấp dẫn về mặt hình ảnh là khả năng làm cho văn bản chạy xung quanh hoặc bên trong các hình ảnh và hình dạng không đều. CSS Exclusions đang mang chất lượng sản xuất này lên web.
Ảnh chụp màn hình bên dưới là từ một nguyên mẫu CSS Exclusions và cho thấy văn bản tự động chạy xung quanh một đường dẫn khớp với đường viền của một khối đá lớn:
Ảnh chụp màn hình tiếp theo minh hoạ điều ngược lại: văn bản nằm trong các đa giác có hình dạng không đều:
Bước đầu tiên để có thể đưa văn bản vào xung quanh hoặc bên trong các hình dạng tuỳ ý là phát triển và tối ưu hoá các thuật toán cần thiết. Adobe hiện đang nỗ lực triển khai các tính năng sẽ được đóng góp trực tiếp cho WebKit. Sau khi được tối ưu hoá, các thuật toán này sẽ trở thành nền tảng để xây dựng phần còn lại của CSS Exclusions.
Để biết thêm thông tin về CSS Exclusions, hãy xem trang CSS Exclusions trên html.adobe.com. Để biết thêm thông tin chi tiết về công việc của Adobe đối với công nghệ cơ bản cho CSS Exclusions, hãy xem bài đăng trên blog của Hans Muller có tiêu đề Horizontal Box: Polygon Intersection for CSS Exclusions (Hộp ngang: Giao điểm đa giác cho CSS Exclusions).
Trạng thái của CSS Regions và CSS Exclusions (2012)
Lần đầu tiên tôi nói về CSS Regions và CSS Exclusions công khai là tại Adobe Developer Pod tại Google I/O 2011. Vào thời điểm đó, tôi đang trình diễn các bản minh hoạ trong trình duyệt nguyên mẫu tuỳ chỉnh của riêng chúng tôi. Mọi người đón nhận rất nhiệt tình, tuy nhiên, có một cảm giác thất vọng rõ rệt khi người xem phát hiện ra rằng chưa có chức năng nào mà tôi đang trình bày có sẵn trong bất kỳ trình duyệt chính nào.
Năm nay (2012), tôi lại tham dự Google I/O, lần này với tư cách là người trình bày cùng với đồng nghiệp Vincent Hardy và Alex Danilo của Google (bạn có thể xem bản trình bày tại đây). Chỉ một năm sau, khoảng 80% thông số kỹ thuật của CSS Regions đã được triển khai trong WebKit và đã có trong phiên bản mới nhất của Google Chrome (lưu ý rằng CSS Regions hiện phải được bật thông qua chrome://flags). Hỗ trợ sơ bộ cho CSS Regions thậm chí đã có trong Chrome dành cho Android:
Ngoài ra, cả CSS Regions và CSS Exclusions đều được triển khai trong bản xem trước Internet Explorer 10 và hiện nằm trong lộ trình năm 2012 của Mozilla cho Firefox. Phiên bản lớn tiếp theo của Safari sẽ hỗ trợ phần lớn thông số kỹ thuật của CSS Regions và các bản cập nhật tiếp theo sẽ bao gồm phần còn lại.
Dưới đây là tiến trình chi tiết về những tiến bộ mà chúng tôi đã đạt được với CSS Regions và CSS Exclusions kể từ đề xuất ban đầu của chúng tôi cho W3C vào tháng 4 năm 2011:
Kết luận
Adobe có rất nhiều kinh nghiệm về văn bản, phông chữ và xuất bản trên máy tính nói chung thông qua các công cụ như InDesign. Mặc dù web đã là một nền tảng rất mạnh mẽ cho văn bản, nhưng chúng tôi muốn sử dụng kiến thức và kinh nghiệm của mình để đẩy mạnh việc trình bày văn bản hơn nữa. Vùng CSS và Loại trừ CSS cho phép nội dung duy trì cấu trúc ngữ nghĩa, đồng thời cho phép bố cục giống như tạp chí thực sự và cuối cùng là một trang web biểu cảm hơn nhiều.