具有 CSS 区域和排除的 Web 杂志式布局

发布于 2022-04-16 13:47:50 字数 15018 浏览 1071 评论 0

Web 是一个极其强大的文本平台,Adobe 在这一领域拥有丰富的经验和专业知识。 因此,当 Adob​​e 正在寻找帮助推动 Web 向前发展的方法时,进一步提升 Web 的文本功能似乎是我们显而易见的起点。
Web 通常采用单列、垂直方向的文本。 尽管可以在图形周围排列文本,甚至可以使用 CSS 将文本格式化为多列,但在 Web 上实现真正的杂志式布局仍然非常困难。 借助 CSS Regions CSS Exclusions ,Adobe 率先将桌面发布的强大功能引入现代浏览器。 例如,在下面的屏幕截图中,CSS Exclusions 被用于沿着山的轮廓流动文本:

Example of CSS Exclusions in action

CSS 排除在行动中的示例

下面屏幕截图中的文档还使用 CSS Exclusions 来允许文本环绕图像中的形状,以及 CSS Regions 来将文本格式化为列和拉引号:

Example of CSS Regions in action

CSS Regions 实例

CSS 区域

在深入了解 CSS Regions ,我想先介绍一下如何在 Google Chrome 中启用区域。 启用 CSS 区域后,您可以尝试本文中引用的一些示例,并创建自己的示例。

在 Google Chrome 中启用 CSS 区域

从 Chrome 的第 20 版(确切地说是 20.0.1132.57 版)开始,CSS 区域通过 chrome://flags界面。 要启用 CSS 区域,请执行以下步骤:

  1. 在 Chrome 中打开新标签页或窗口。
  2. 类型 chrome://flags 在位置栏中。
  3. 使用 find in page (control/command + f) 并搜索 “experimental Web Platform features” 部分。
  4. 单击 启用 链接。
  5. 单击 立即重新启动 底部

有关 Chrome 标志的更多信息,请参阅我 关于 Chrome 标志的所有

重新启动浏览器后,您就可以开始尝试使用 CSS 区域了。

CSS 区域概览

CSS Regions 允许语义标记的文本块自动流入“框”(当前为元素)。 下图演示了文本(流)和框(文本流入的区域)的分离:

Content flows into defined regions

内容流入定义的区域

让我们看一个实际的 CSS 区域用例。 除了作为 Adob​​e 的开发人员之外,我还是一名科幻作家。 我经常在 Creative Commons 许可下在线发布我的作品,为了让它能够在最大数量的设备和浏览器上工作,我经常使用类似于以下的极其简单的格式:

Unstyled Human Legacy Project Example

无样式的人类遗产项目示例

使用 CSS 区域,我能够创建一种视觉上更有趣、功能性更强的体验,因为它更易于导航且阅读起来更舒适:

Human Legacy Project showing Regions

与地区的人类遗产项目。 试试看:http://christiancantrell.com/adobe/hlp/callout.html

出于演示目的,我在此原型中添加了显示 CSS 区域的功能。 下面的屏幕截图显示了这些区域的排列方式,使得它们给人的印象是围绕图形的列和中心的拉引号:

Human Legacy Project showing Regions

显示区域的人类遗产项目

试验这个原型(以及查看源代码) 这里 。 使用箭头键进行导航,然后按 Esc显示区域的关键。 早期的原型也可 在此处

创建命名流

使文本块流经区域所需的 CSS 非常简单。 下面的代码片段将名为“article”的命名流分配给 id 为“content”的 div,并将相同的名为 flow 的“article”分配给任何具有“region”类的元素。 结果是包含在“content”元素中的文本将自动流经任何具有“region”类的元素。

<!DOCTYPE html>
<html>
<head>
  <style>
    #content {
      +flow-into: article;
    }

    .region {
      +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 class="region"></div>
  <div class="region"></div>
  <div class="region"></div>
  <div>
    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>

结果如下所示:

Result of above code

上述代码的结果

请注意,“内容” div 中的文本对其表示方式一无所知。 换句话说,即使它流经各个区域,它也可以在语义上保持完整。 此外,由于区域只是元素,因此它们使用 CSS 进行定位和调整大小就像任何其他元素一样,因此与响应式设计原则完美兼容。 将元素指定为命名流的一部分仅仅意味着指定的文本会自动流经它们。

CSS 对象模型

简而言之,本节仅使用一个供应商前缀 ( webkit),
但是您应该编写跨[支持](http://html.adobe.com/webplatform/enable/)此功能的浏览器的代码!

CSS 对象模型 或 CSSOM 定义了用于处理 CSS 的 JavaScript API 以下是与 CSS 区域相关的新 API 列表:

  • document.webkitGetNamedFlows():返回文档中可用的命名流集合的函数。
  • document.webkitGetNamedFlows().namedItem("article"):返回对特定命名流的引用的函数。 参数对应于指定为值的名称 flow-intofrom-fromCSS 属性。 要获取对上述代码片段中指定的命名流的引用,您需要传入字符串“article”。
  • WebKitNamedFlow:具有以下属性和功能的命名浮体的对象表示:
    • firstEmptyRegionIndex:一个整数值,指向与命名流关联的第一个空区域的索引。 看 getRegions()下面学习如何获取区域的集合。
    • name:带有流名称的字符串值。
    • overset: 一个布尔属性,即:
      • false当命名流的内容适合相关区域时
      • true当内容不适合并且需要更多区域来包含所有内容时。
    • getContent():一个函数,它返回一个集合,其中包含对流入命名流的节点的引用。
    • getRegions():一个函数,它返回一个集合,其中包含对包含命名流内容的区域的引用。
    • getRegionsByContentNode(node):返回对包含指定节点的区域的引用的函数。 这对于查找包含命名锚点等内容的区域特别有用。
  • webkitregionoversetchange事件。 此事件在 WebkitNamedFlow每当相关内容的布局因任何原因发生变化(添加或删除内容、字体大小变化、区域形状变化等) 导致 webkitRegionOverset区域属性发生变化。 此事件对于侦听粗略的布局更改很有用。 它表明发生了一些重要的事情并且布局可能需要注意,例如:需要更多区域,某些区域可能是空的等。
  • webkitregionfragmentchange事件。 在本次编辑时未实施。 此事件在 WebkitNamedFlow每当相关内容的布局因任何原因发生变化时,类似于 webkitregionoversetchange, 但 无论 webkitRegionOverset特性。 此事件对于侦听不一定影响命名流的整个布局的细粒度布局更改很有用,例如:内容从一个区域移动到另一个区域,但整体内容仍然适合所有区域。
  • Element.webkitRegionOverset:当元素具有 flow-from分配的 CSS 属性。 这些元素具有 webkitRegionOverset属性,如果它们是命名流的一部分,则指示来自流的内容是否溢出该区域。 webkitRegionOverset 的可能值有:
    • 如果内容多于该区域可以容纳的内容,则“溢出”
    • 如果内容在区域结束之前停止,则为“适合”
    • 如果内容尚未到达该区域,则为“空”

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 可能是实现分页和响应式布局等功能的最强大和最灵活的方式,但 Adob​​e 一直在使用文本和桌面发布工具足够长的时间,知道设计师和开发人员也会想要一种更简单的方式来获得相对通用分页功能。 因此,我们正在制定一个名为 CSS 页面模板的提案,该提案允许完全以声明方式定义分页行为。

让我们看一下 CSS 页面模板的常见用例。 下面的代码片段显示了使用 CSS 创建两个命名流:“article-flow”和“timeline-flow”。 此外,它定义了第三个选择器,称为“combined-articles”,两个流将包含在其中。 简单的包含 overflow-style“combined-articles”选择器内的属性指示内容应自动沿 x 轴或水平分页:

<style>
  #article {
    +flow-into: article-flow;
  }

  #timeline {
    +flow-into: timeline-flow;
  }

  #combined-articles {
    overflow-style: paged-x;
  }
</style>

现在已经定义了流程并指定了所需的溢出行为,我们可以创建页面模板本身:

@template {
  @slot left {
    width: 35%;
    float: left;
    +flow-from: article-flow;
  }

  @slot time {
    width: 25%;
    float: left;
    +flow-from: timeline-flow;
  }

  @slot right {
    width: 35%;
    float: left;
    +flow-from: article-flow;
  }
}

页面模板是使用新的“at”语法定义的。 在上面的代码片段中,我们定义了三个插槽,每个插槽对应一列。 “文章流”中的文本将流经左右列,“时间线流”中的文本将填充中间的列。 结果可能如下所示:

Page templates example

页面模板示例

请注意,文章文本(左右栏中的文本)是英文的,中间的时间线是德文的。 此外,无需任何 JavaScript 代码,文档就可以横向翻页。 一切都是在 CSS 中完全以声明方式完成的。

CSS 页面模板仍然是一个提议,但是我们有一个 原型 使用 JavaScript “shim”(又名 polyfill 以便您现在可以试验它们。

要全面了解有关 CSS 区域的更多信息,请查看 html.adobe.com 上的 CSS 区域页面

CSS 排除

为了实现真正的杂志式布局,仅仅能够通过区域流动文本是不够的。 高质量和视觉上有趣的桌面出版的一个关键要素是能够使文本在不规则图形和形状周围或内部流动。 CSS Exclusions 将这种水平的生产质量带到了网络上。

下面的屏幕截图来自 CSS Exclusions 原型,显示了围绕与大型岩层轮廓匹配的路径动态流动的文本:

Example of CSS Exclusions in action

CSS 排除在行动中的示例

下一个屏幕截图中说明了相反的情况:在不规则形状的多边形内流动的文本:

Text flowing into irregularly shaped polygons

流入不规则多边形的文本

能够在任意形状周围或内部流动文本的第一步是开发和优化所需的算法。 Adobe 目前正在开发将直接贡献给 WebKit 的实现。 一旦优化了这些算法,它们将成为构建其余 CSS 排除项的基础。

有关 CSS 排除的更多信息,请参阅 html.adobe.com 上的 CSS 排除页面 ,更详细地了解 Adob​​e 在 CSS 排除的底层技术方面的工作,请参阅 Hans Muller 的博客文章,标题为“ 水平框:CSS 排除的多边形交集” .

CSS 区域和 CSS 排除的现状

我第一次公开谈论 CSS 区域和 CSS 排除是在 2011 年 Google I/O 的 Adob​​e Developer Pod 上。当时,我正在我们自己的自定义原型浏览器中展示演示。 招待会非常热情,但是当旁观者发现我展示的功能在任何主要浏览器中都没有可用时,有一种明显的失望感。

今年(2012 年)我再次参加了 Google I/O,这次是与我的同事 Vincent Hardy Alex Danilo 来自 Google 在此处观看演示文稿 )。 仅仅一年之后,大约 80% 的 CSS Regions 规范已经在 WebKit 中实现,并且已经在 Google Chrome 的最新版本中(注意 CSS Regions 目前必须通过 chrome://flags)。 对 CSS Regions 的初步支持甚至登陆了 Chrome for Android:

Regions on Chrome for Android

适用于 Android 的 Chrome 上的区域

此外,CSS 区域和 CSS 排除都在 Internet Explorer 10 预览版中实现,并且目前在 Mozilla 的 2012 年 Firefox 路线图中。 Safari 的下一个主要版本应该支持大部分 CSS 区域规范,后续更新应该包括其余部分。

以下是自 2011 年 4 月我们向 W3C 提出初步提案以来,我们在 CSS 区域和 CSS 排除方面取得的进展的详细时间表:

Region and Exclusion Progress

区域和排除进度

结论

Adobe 在文本、字体和桌面出版方面拥有丰富的经验,通常通过 InDesign 等工具进行。 尽管网络已经是一个非常强大的文本平台,但我们希望利用我们的知识和经验进一步推动文本呈现。 CSS Regions 和 CSS Exclusions 允许内容保持语义结构,同时也支持真正的杂志式布局,最终实现更具表现力的网络。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

坏尐絯

暂无简介

0 文章
0 评论
605 人气
更多

推荐作者

娇女薄笑

文章 0 评论 0

biaggi

文章 0 评论 0

xiaolangfanhua

文章 0 评论 0

rivulet

文章 0 评论 0

我三岁

文章 0 评论 0

薆情海

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文