随着平板电脑变得越来越普及,融合了阅读体验的应用很快就会变得流行起来。 下面我们重点介绍了可用来创建优秀阅读器应用的新 CSS 和 HTML5 功能。 阅读本文后,你将对在这些应用中使用的主要布局功能有一个全面的了解,而且还可以获得一个基本的阅读器应用引导你入门。现在,我们了解一下在 Windows 中营造卓越阅读器体验的详细信息。
简介
Windows 8 为开发人员和设计者提供了一系列最新的 HTML5 和 CSS3 功能,用于创建新颖独特的阅读体验。具体而言,由于诸如 CSS 区域和 CSS 网格等新技术,你可以创建数字出版物,让这些出版物结合 HTML 的优势—流体布局、基于标记的样式、可访问的内容、交互性—与到目前为止仅在印刷领域中可用的创新布局。
传统网页内容的呈现形式为单列竖排。段落堆放在段落和其他图像之上,偶尔插入的浮动元素可呈现出一些视觉多样化。“页面”仅通过将内容分段为不同的 HTML 文档来创建;不存在任何基于标记的方式来获取一连串的内容并将内容分段为单个的文本屏幕。缺少用于创建列和适应屏幕大小的强大控件表示许多页面仅针对特定 分辨率(如 1024 × 768)进行优化。在高分辨率、宽屏幕监视器上呈现为小分辨率优化的文本时,你会看到糟糕体验的一个好示例。 以下图像显示了纵横比为 4:3 的监视器上的单列布局。
以下图像显示了宽屏幕监视器上具有空白区域的相同布局。
相比之下,设计用于充分利用页面可用空间的页面可能会以多列文本为特征,从而在填充屏幕的同时确保文本的各行不会太长,易于阅读。 通过一些小的优化措施,标题可以增加其大小以更加抢眼,并且当文本环绕在图像周围时可以为图像提供更加显眼的位置。
以下图像显示了用于宽屏幕监视器的改进阅读器布局。
印刷设计者长久以来都可以轻松设计这样的布局,因为他们只需要应付预先已知的固定页面大小。适应性布局的设计者必须使用诸如 CSS 网格和媒体查询等工具来创建页面,这些页面智能地适应不同的屏幕大小。
本文章与动态 CSS 区域模板示例一起介绍如何创建适应各种屏幕大小的美观布局来进行阅读。在查看新的 CSS 阅读功能中,我们仔细查看了几个新功能,你可以使用这些功能以创新性的新方式呈现文本和图像。在汇聚多个功能以创建良好的阅读体验中,我们通过说明如何组合这些功能来构建适应性阅读体验来继续,该体验结合了优秀设计与流体和美观布局。
查看新 CSS 阅读功能
我们了解一下你可能会在阅读器应用中使用的新 CSS 功能:多列、断字、网格、区域以及排除项。
多列
通过 CSS 多列,设计人员可以将元素 — 例如,div 元素或页面的 body— 的内联内容(如文本)设置为尺寸相同且相邻的多个连续列格式。例如,只需将 CSS 属性 column-count: 2; 添加到 div,即可生成如下图所示的布局。
但是,多列也确实有一些限制。所有列必须具有相同的尺寸,而且相互之间相邻放置。而且,多列元素的内容遵守 CSSoverflow 属性;即它剪切、添加滚动条,或通过在原始元素旁边创建其他列来溢出。 由于这些原因,CSS 区域在以下这些情形下可能是更好的文本布局选项:需要更多变的页面布局,或元素的内联内容可能溢出元素。下图显示了通过溢出多列元素创建的新列。
Note CSS 多列有一个“平衡”选项,可以确保所有列的长度相同,而且最后一列不会显著短于其他列。此功能不能确保这些列具有相同的行数,也不能确保这些行在各列中都是对齐的。应当为多列元素中的内容设置格式,以使所有元素都是单行高度的倍数,包括段落和图像的补白。
下图显示了经过平衡的多列布局(淡蓝色外框)与未经平衡的布局(红色外框)相比较,如何设置内容的格式。
#p#
Note 此示例经过了适当的平衡,因为列内的元素根据列尺寸和间距进行了匹配。
下列代码显示了这两种布局的创建方法。
- <!DOCTYPEHTML>
- <html>
- <head>
- <style>
- #div1{
- width: 180px;
- height: 300px;
- column-fill: balance;
- column-count: 2;
- float: left;
- border: solid 2px lightblue;
- margin-right: 8px;
- }
- #div2{
- width: 180px;
- height: 300px;
- column-fill: auto;
- column-count: 2;
- float: left;
- border: solid 2px red;
- margin-right: 8px;
- }
- </style>
- </head>
- <body>
- <div id="div1" class="div1">
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- </div>
- <div id="div2">
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- Hi friend! Hi friend! Hi friend! Hi friend!
- </div>
- </body>
- </html>
断字
多列使我们可以将内联内容(如文本)布置在相对较窄的列中。但是这些列的内容看起来可能会参差不齐,特别是在平均单词长度占列宽度的较大比例时。尤其是,当列与 text-align: justify 属性结合使用时,单词之间可能会出现较大的空白间隙,从而使内容的外观不规则且不美观,如下所示。
相应地,我们现在提供自动断字功能,这样多行的排列更紧密,同时还提供强大的阅读体验,如下所示。
断字在 W3C CSS 文本级别 3 规范的部分中定义。CSS 断字提供了以下能力:
- 指定断字分隔符前后的最小字词片段长度。
- 指定连续断字行的最大数量。
- 避免段落和列中最后的字词被断字。
- 指定自定义断字字符。
大量语言支持在 Windows 8 和 Internet Explorer 10 中进行断字,且建议将断字用于 CSS 多列和区域。
网格
CSS 网格布局的核心理念是,将页面划分成定义好的一组行和列,然后根据这些行和列使用 CSS 设置元素的位置和尺寸。因为行和列的尺寸可以定义为固定、灵活或按内容调整大小,所以很容易构建一个完全填满整个屏幕的布局,无论屏幕尺寸如何。
例如,下图显示了一个阅读器示例,它划分为带有多个元素的两列和三行。在浏览器窗口的尺寸更改时,某些元素必须保持不变,而其他元素会增大或缩小。
通过 CSS 网格布局,你可以通过以下列标记开始实现此设计。
- <div id="grid">
- <div id="logo">Reader Logo</div>
- <div id="page">Page</div>
- <div id="bookmarks">Bookmarks</div>
- <div id="content">Reader Content</div>
- <div id="controls">Controls</div>
- </div>
名为 grid
的 div 元素通过应用 CSS 样式 display: grid 设置为 grid 容器。你可以将各个行和列定义为“灵活”,它基于可用的空间增大或缩小行和列,也可以将其定义为“自动调整大小”,它调整行或列的大小以适应放在其中的最大元素的宽度或高度。
- #grid {
- display: -ms-grid;
- -ms-grid-columns: auto 1fr;
- -ms-grid-rows: auto 1fr auto;
- }
定义网格后,你可以将各个元素放在特定的网格单元格中。显示下列标记时,你不仅可以指定将元素放置在 CSS 中特定的行和列中,而且还可以指定让一个元素跨多个行和列放置,并指定元素在一个单元格或一系列单元格中水平或垂直对齐。
- #logo { -ms-grid-column: 1; -ms-grid-row: 1 }
- #page { -ms-grid-column: 1; -ms-grid-row: 3 }
- #bookmarks { -ms-grid-column: 1; -ms-grid-row: 2; -ms-grid-row-align: start }
- #content { -ms-grid-column: 2; -ms-grid-row: 1; -ms-grid-row-span: 2 }
- #controls { -ms-grid-column: 2; -ms-grid-row: 3; -ms-grid-column-align: center }
可以指定元素具有固定尺寸,或填充它们所在单元格的可用宽度或高度。在前面的示例中,content
元素随着屏幕增大,而其他元素(如 logo
元素)保持尺寸不变。
#p#
Note 因为新层叠样式表级别 3 (CSS3) 仍为一个新兴规范,所以在 Internet Explorer 10 中使用时,所有网格属性都带有前缀 "-ms-"。
通过将网格布局功能与 CSS3 媒体查询相结合,你可以为不同的分辨率、纵横比和屏幕方向指定完全不同的布局。例如,你可以针对不同的屏幕尺寸定义不同的行数或列数,从而为垂直“纵向”布局指定较少的列,为水平“横向”布局指定较多的列。你还可以指定行和列按不同方式调整大小。
此外,因为网格中元素的位置与指定它们的顺序无关 — 即它们的位置单纯由 CSS 指定,而不是由 HTML 标记中的顺序指定— 所以很容易在不同屏幕尺寸上为元素指定不同的排列,甚至可以完全避免在某些布局上显示某些元素。
区域
CSS 区域支持设计人员将内容从一个包含元素流入另一个元素,这样可以将一个页面或多个页面中不同区域的内容流连接在一起。此功能使新设计和创新设计成为可能。 例如,下图显示文本跨页面内两个区域流动。请注意,与 CSS 多列不同,区域允许容器有不同的尺寸,也不需要相互直接紧密相邻。
区域也可用于跨多个虚拟页流动单个内容流(例如一篇文章的文本),如下图所示。
请注意,此上下文中的“页面”不是通过打印过程创建的页面(例如使用“@page”CSS 规则设置样式的页面),而是包含一个或多个区域的 div 元素。通过在可滚动区域(通常使用贴靠点来模拟翻页)中放置这些 div 元素,我们可以创造一种分页阅读体验,其中单个内容流显示在多个全屏页面上,而不是显示为单个内容滚动区域。此外,区域可以与 CSS 网格和媒体查询结合使用,以创建准确符合特定屏幕尺寸的页面,并生成显示特定内容流所需的准确页数。
下图显示了区域工作原理的高级概述。来自源文档 (Content.html) 的内容流入主模板文档 (Master.html) 的多个区域。
需要注意,区域不参与文档的 CSS 样式层叠,因此在特定区域上放置的样式规则(如 text-color: red)不影响区域中的内容。但是对内容文档本身放置的样式规则一定会影响内容,尽管这些规则不影响主模板文档中的任何元素。
同样,主模板中区域显示的内容不存在于主模板的文档对象模型 (DOM) 中;通过 Microsoft Visual Studio 中的 DOM 资源管理器查看 Master.html,例如,将显示每个区域为空。相反,区域显示的内容存在于 Master.html 中的隐藏 iframe 元素中,并指向 Content.html。
排除项
CSS 排除项提供了一种使内联内容环绕元素(如图像、标题或文本标注)的方法。排除项与 CSS 浮动类似,但是排除项不是被推到包含块的一侧或另一侧,而是可以放置在包含块的中间,并且使内容围绕两侧流动,如下所示。
排除项一次可以与多个环绕元素交互。例如,排除项可以由多个区域环绕,并且使每个区域中的内容都围绕它。有关如何执行此操作的详细信息,请参阅结合使用多个功能以营造完美阅读体验。
请注意,在 Internet Explorer 10 中,区域只能是矩形块。但是,多个区域可以放置为排列在一起,以创建非矩形的区域。
结合使用多个功能以营造完美阅读体验
现在,我们已经了解可用来在 Windows 8 中营造完美阅读体验的各项技术,让我们来讨论一下如何结合使用这些技术。我们通过查看动态 CSS 区域模板示例来 完成这些操作。首先,我们介绍如何结合使用网格、媒体查询、区域及排除项来创建各个页面模板。接着,我们查看实例化这些页面模板,直到已显示源文档中的所 有内容的 JavaScript 代码。最后,我们查看可以基于屏幕尺寸或字体大小更改来调整页数的附加 JavaScript 代码。
布置页面模板
以下图像显示示例的第 1 页,其中包括:
- 一个标题(“动态区域模板示例”)。
- 作为两个并行列布置的两个区域。
- 位于页面中间的一个排除集(土星的图片),这会导致两个区域中周围的内容环绕该排除集。
#p#
下图显示了页面 1 的网格结构。
尤其是,页面 1 包含单个 div 元素,此元素通过使用 display: -ms-grid 属性变为一个网格。其他元素(如区域和排除项)放在此单个 div 上。为此网格指定应用程序区域的整个宽度和高度,如果应用处于填充或贴靠模式,则该区域可能是整个屏幕或屏幕的一部分。
页面 1 划分为 4 列 5 行。每一列的大小是 1 个分数单位 (1FR),它表示在布置固定尺寸和自动调整尺寸的轨迹(行或列)后,可用于网格的所有空间的其中一份。在此例中,因为没有固定尺寸或自动调整尺寸的轨迹,所以每一列占有应用程序区域的 25% 宽度。
与之相比,页面 1 上 5 行中的第一行是自动调整尺寸行,而其余的行只有微小的尺寸调整。页面标题在第 1 行,它将占用显示“Dynamic region Templates Sample”标题所需的空间。应用程序区域的其余高度被其余行占用,其中每行只有不到应用程序区域的 25%。
网格内包含两个区域。每个区域跨两列四行:第一个区域位于第 2 行,第 1 列(CSS 网格 1 索引),第二个区域位于第 2 行,第 3 列。每个区域只是一个设置了 -ms-flow-from: content 属性的 div 元素。因为每个区域共用同一个流名称,所以内容流从第一个区域开始,继续到下一个,然后前进到不同页面的后续区域。
网格还用于将排除项放置在页面的中间。在此例中,排除项是一个 div 元素,通过 CSSflexbox 显示属性将一张土星图像放置在中间。此排除项通过设置 -ms-wrap-flow: both 属性创建。当排除项放置在网格中间(第 3 行,第 2 列,跨两行两列)后,与排除项相交的任何内联内容将环绕它分布。此行为与传统的浮动元素不同,后者必须放置在页面的一侧。
请注意,区域和排除项的放置都是跨行和列延伸的。出现这种情况,是因为应用运行的设备具有不同的屏幕分辨率,或者因为应用已经在全屏幕和填充模式之 间进行切换。随着应用分辨率更改尺寸,屏幕上的元素也相应增大和缩小。这明显是区域的最优行为,因为我们希望文本区域填满应用程序区域,但是不要溢出。没 有填入区域的任何文本仅简单移入到下一个区域。根据内容,设计人员可能不希望图像随着屏幕尺寸进行拉伸,而希望保留图像的纵横比或绝对尺寸。这可以通过更 改 –ms-grid-row-align 和 –ms-grid-column-align 属性的 stretch 默认值来轻松实现。
接下来的两个图像显示了 Dynamic Region Templates Sample 的页面 2 和页面 3 的网格划分。这两个页面布局都是 4 × 4 的网格,其中每一行和每一列都等于可用空间的相等分数尺寸。这两个页面的唯一实质性差别(除了背景图像的明显不同)是页面 2 具有单一区域跨越页面中间的两行两列,而页面 3 具有多个区域,在整个页面上交错分布。总体而言,所有这些页面演示了单个内容流通过 CSS 区域分布到多个页面。
下面是页面 2。
下面是页面 3。
Note 上面所有三个页面中显示的内容都完全对齐而且应用了断字。这些样式属性是在内容(来自 content.html 文件)上设置的,而不是在任何区域本身上设置的。如前面所提到的,这是因为样式层叠不会渗透进入区域。
实例化页面模板
我们已经讨论了如何使用区域、网格和排除项来创建页面。你可以在动态 CSS 区域模板示例项 目中看到这些页面,分别为 page1.html、page2.html 和 page3.html。但是,我们还没有检查在激活应用时,这些页面是如何动态创建的。由于根据屏幕尺寸和字体大小,显示内容文档所需的页数会发生变化 — 较小的屏幕或较大的字体意味着每页容纳的单词更少,因此需要更多的页数 – 必须在运行时动态实例化页面。现在,我们讨论如何在 Windows 应用商店应用中实例化预定义的模板,一次一个,直到显示整个内容文档。之后,我们将讨论如何根据屏幕尺寸或字体大小的运行时变化采用适合的页数。
下面的示例显示了 Dynamic CSS Region Templates Sample 的结构。特别是,带有 appContainer
的 id 属性的 div 元素同时包含源 iframe 元素和包含各个页面的 pageContainer
div 元素。iframe 指向 content.html 文档,此文档将在多个页面中跨多个区域显示。因为 iframe 具有 -ms-flow-into: content 属性,所以不会显示它。appContainer
div 和各个页面将占用分配给应用的所有可用屏幕空间,因为它们的宽度和高度都设置为 100% 的应用程序区域。
#p#
通过使用 display: -ms-box 属性,已经将 pageContainer
div 配置为 flexbox,并且已经将 body 元素设置为 overflow: scroll。因为 flexbox 的默认行为是将其中的所有元素相邻放置,从而达到按需要水平增长,所以用户可以通过鼠标或触控输入水平平移来滚动浏览页面。
Note 设计人员通过设置 -ms-box-orient: vertical 属性,可以轻松切换到垂直分页模式。同时,为了使触控滚动能正确工作,iframe 元素必须与正在滚动的页面位于同一个父元素中。如果滚动元素是 body 元素本身,这显然不是问题,但是在 iframe 和页面的其他配置中,这可能会出现问题。
现在我们已了解阅读应用最终将如何构建,接下来我们讨论页面在应用中是如何放置的。下面的示例代码来自 regionTemplatePage.js,显示了 pageTemplates
阵列。
- var pageTemplates = [
- '/html/page1.html',
- '/html/page2.html',
- '/html/page3.html',
- '/html/pageDefault.html'
- ];
pageTemplates
阵列指向应用包中与将要实例化的页面对应的各个文件及 createPages
函数使用的引用文件。createPages
函数被源 iframe 的 load 事件触发的事件侦听器函数调用。
下列代码显示了 createPages
,从 pageTemplates
阵列选择和实例化页面模板的函数。
- unction createPages() {
- var targetPage;
- if (currentPage > (pageTemplates.length - 1)) {
- targetPage = pageTemplates[pageTemplates.length - 1];
- } else {
- targetPage = pageTemplates[currentPage];
- }
- var flexboxElement = document.getElementById('pageContainer');
- WinJS.UI.Fragments.render(targetPage, flexboxElement).then(function () {
- msSetImmediate(function () {
- currentPage += 1;
- var flexboxElement = document.getElementById('pageContainer');
- var pages = flexboxElement.querySelectorAll('.page');
- var lastPage = pages[pages.length - 1];
- var regions = lastPage.querySelectorAll(searchClass);
- var lastRegion = regions[regions.length - 1];
- if (lastRegion.msRegionOverflow === 'overflow') {
- createPages();
- }
- });
- });
- }
此函数执行三个主要步骤:选择模板、呈现模板并确定是否需要其他模板。在第一步中,根据当前呈现的页码将 targetPage 变量设置为适当的页面模板。通过按 createPages
递增的计数器方法,将 SDK 示例设置为呈现 pageTemplates
阵列中的每一页一次,然后再呈现下一页。如果示例已达到阵列末尾,则使用最后一页模板,直到内容呈现完毕。
确定页面模板后,createPages
将从适用于 JavaScript 的 Windows 库调用片段加载程序函数,以便将所选模板呈现到 pageContainer
元素。片段加载程序将获取目标页面文件(此示例中的 page1.html)的 body 元素中的所有内容,并将其插入到指定的元素(在此例中为 pageContainer
元素)中。因为片段加载程序是异步调用,所以其余的 createPages
函数必须等待,直到激活 then 函数。
激活 then 之后,createPages
导航 DOM 以查找最后一页上的最后区域。createPages
测试此区域,以查看是否仍有来自内容文档的其他内容要呈现。如果未将 msRegionOverflow 属性设置为 "overflow",则内容文档已完全呈现在最后一个区域中或最后一页的其他区域中。如果将 msRegionOveflow 属性设置为 "overflow",则其他内容将保留等待呈现。在这种情况下,将调用 createPages
并重新开始。
Note 由于 msSetImmediate 调用,在激活 then 函数之前存在初始 createPages
调用。这意味着 createPages
不是真正的递归,因为一次只有一个 createPages 实例放置在调用堆栈上。
Note 显然,createPages 使用的模板选择机制可供设计人员调整以满足自己的需求。例如,不用一次又一次重复使用上次使用的模板,只要还有其他内容需要显示,则可以改变函数以重复循环使用模板阵列。此外,createPages
使用的简单阵列和模板选择机制可由任意复杂逻辑取代,复杂逻辑可能基于其他因素选择页面模板,例如正在呈现的源内容部分或主机设备的特定分辨率或方向。
最后,createPages
函数适合每一页都与下一页不同的阅读器应用。但是,某些应用(如电子书)可能需要更多的页面,但完全不同的页面类型较少。对于这些应用,尤其是源内容很长 (例如,长篇大作的完整文本)时,建议一次加载多个页面模板。例如,电子书阅读应用不使用包含单个模板的 Page1.html 文件,而使用包含多个模板的 Pages.html 文件,每个模板是简单的两列或三列布局。通过将这些页面全部一起加载到内存中,可以显著提升整体性能。请注意,遵循此方法可能导致 createPages
"超过"所需的页数,并使某些页面没有内容。此问题可通过使用 resizePages
函数来修复,此函数将在下一部分进行详细介绍。
#p#
调整页面模板大小
前面我们介绍了如何使用网格、区域和排除项来创建页面模板,以及如何在运行时实例化应用内的这些页面模板。然而,能够响应外部事件,在运行时更改页 数也是很重要的。即使内容文档保持不变,更改应用程序区域可能导致应用的视图状态从全屏更改为填充或贴靠模式,从而导致页面缩小或增大。更改应用程序区域 可能导致每个页面装入不同的内容量,并且可能要求在应用中添加或删除页面。
下列代码示例显示了 resizePages
函数,此函数支持添加或删除页面以响应外部事件。在动态 CSS 区域模板示例中,调用 resizePages
以响应应用视图状态更改,但是也可以调用此函数响应诸如调整字体大小等事件。
- function resizePages() {
- var flexboxElement = document.getElementById('pageContainer');
- var pages = flexboxElement.querySelectorAll('.page');
- var lastPage = pages[pages.length-1];
- var regions = lastPage.querySelectorAll(searchClass);
- var lastRegion = regions[regions.length-1];
- if (lastRegion.msRegionOverflow === 'overflow') {
- createPages();
- }
- else {
- var firstRegion = regions[0];
- while (firstRegion.msRegionOverflow === 'empty')
- {
- flexboxElement.removeChild(lastPage);
- currentPage = currentPage - 1;
- lastPage = pages[currentPage-1];
- regions = lastPage.querySelectorAll(searchClass);
- firstRegion = regions[0];
- }
- }
- }
resizePages
函数首先定位最后一页上最后的区域。与 createPages
函数一样,它接着测试此区域以确定是否还有更多内容需要更多页面来显示。如果有要显示的内容,resizePages
将调用 createPages
。此外,如果最后一个区域上没有更多内容,此函数将查找最后一页上的第一个区域。如果 msRegionOverflow 属性指示此区域不为空,我们知道内容文档是在最后一页结束的;不会执行进一步的操作,因为至少在最后一页的第一个区域中有内容,而且没有内容溢出最后一个区域。此外,如果最后一页上的第一个区域为空,则最后一页没有内容,它完全是空的。resizePages
函数删除最后一页,并调用它本身来测试新的最后一页。
结合使用 resizePages
和 createPages
,便足以在应用中添加和删除页面。示例页面模板设计可以灵活伸缩以填充各种屏幕尺寸,但是设计人员可能需要页面能够在不同的视图状态、方向或屏幕分辨率下重新调整布局结构本身,而不是简单地调整以填充多余的空间。动态 CSS 区域模板示例显 示了如何创建能够在不同视图状态下重新调整布局结构本身的页面模板。下图显示了示例如何将布局结构本身调整为垂直堆叠的页面,其中每一页都是贴靠模式下的 一个单独区域。此方法涉及隐藏所有内容,除了每个页面模板仅显示一个区域,从而在贴靠模式下仅设置一个元素作为区域,并重新设置 pageContainer
元素的方向以垂直显示页面。
若要了解这是如何实现的,请查看 Page1.html 的标记。页面 1 中有两个区域,每个区域都分配有一个特定的 ID 和类。两个区域都属于 fullregion
类,而只有第一个区域属于 snappedregion
类。fullregion
类将它的元素定义为将 –ms-flow-from 属性设置为 content,这意味着 iframe 元素内的材料将显示在它们内。snappedregion
类开始也是以相同的方式设置。
激活媒体查询中辅屏视图状态的规则后,只有 snappedregion
类仍将 –ms-flow-from 属性设置为 content;而 fullregion
类将属性设置为 null。这样的效果是页面中只有一个 div 元素成为区域;内容从该区域流到其他页的区域中。而且,由于应用中的其他页面也仅在其第一个区域元素上设置 snappedregion
类,因此当应用置于贴靠模式时,每页只有一个区域显示来自源文档的内容。下列代码显示页面 1 的 HTML 和 CSS。
- <body>
- <div id="page1" class="page">
- <div id="logoContainer">
- <img id="floatLogo" src="/images/Saturn.jpg" />
- </div>
- <h1 id="title">Dynamic region Templates Sample</h1>
- <div id="page1region1" class="fullregion snappedregion"></div>
- <div id="page1region2" class="fullregion"></div>
- </div>
- </body>
- .fullregion {
- -ms-flow-from: content;
- }
- .snappedregion
- {
- -ms-flow-from: content;
- }
- /*In snapped mode the fullregion class no longer receives content from the content stream, but the snappedregion class does.*/
- @media (-ms-view-state: snapped)
- {
- .fullregion
- {
- -ms-flow-from: null;
- }
- .snappedregion
- {
- -ms-flow-from: content;
- }
- /*Change the navigation direction to vertical for RTL and LTR languages*/
- #pageContainer
- {
- -ms-box-orient: block-axis;
- }
样式类,结合在下面的代码中设置的样式规则,显示应用在贴靠模式中如何转换。尤其是,除了第一个区域,所有元素都设置为 display: none,而第一个区域设置为占满整个页面(第一行除外,此行留给文章标题使用)。在所有页面复制此流程,并且将 pageContainer
阵列设置为按块方向(在下面的代码示例中为垂直方向)布置页面时,应用将转换为一系列整页区域,显示同一内容文档的不同部分。应用结合前面介绍的 resizePages
和 createPages
算法,将在贴靠模式下创建足够的页面以完全呈现源文档。
- /* In snapped mode we set the first region to take up the entire page, and hide all other regions. */
- @media all and (-ms-view-state: snapped)
- {
- #page1region1
- {
- -ms-grid-row: 2;
- -ms-grid-column: 1;
- -ms-grid-row-span: 4;
- -ms-grid-column-span: 4;
- padding: 0;
- }
- #page1region2
- {
- display: none;
- }
- #logoContainer
- {
- display: none;
- }
- }
Note 前面介绍的调整页面布局的基本机制也适用于其他设计。例如,设计人员可能需要根据页面在 16:9 还是 4:3 模式从页面添加或删除区域。可以使用 CSS 媒体查询,根据需要修改 –ms-flow-from 和 display 属性,从而实现此调整。媒体查询还可用来更改 CSS 网格的结构。例如,根据屏幕是纵向还是横向模式,内容布局可从 2 × 4 网格转换为 4 × 2 网格。设计人员可能还使用 CSS 媒体查询,根据屏幕分辨率和方向来显示或不显示各个图像或其他元素。
原文链接:http://msdn.microsoft.com/zh-cn/library/windows/apps/hh780610.aspx