这些 Web 平台功能与现有观点(例如视口和媒体查询)集成,因此开拓职员和设计职员可以花更多韶光思考如何利用两个显示器来创建增强体验,而不是学习一组新代码来构建它们。
利用新的 CSS 媒体功能检测可折叠设备双屏和可折叠设备只是相应式设计的下一步,因此它们被视为另一个相应式设计目标,我们可以利用媒体功能为其设计样式。我们本日已经利用媒体功能和查询来定位台式机、平板电脑和手机,现在我们拥有 CSS Viewport Segments 媒体功能来定位我们的可折叠和双屏设备。
视口分段媒体查询可以有两个值。第一个是horizontal-viewport-segments,这表示设备铰链垂直且视口被硬件铰链拆分或折叠成列时的设备状态。

当horizonal-viewport-segment铰链处于垂直折叠姿势时,目标是设备。
为了专门为这种方向的可折叠设备供应样式,我们将编写以下内容:
@media (horizontal-viewport-segments: 2) {// Styles specific to the device in this orientation}
整数表示设备方向中存在的视口数量。当设备像一本书一样处于垂直折叠姿势时,我们在水平方向有两个不同的视口,在垂直方向只有一个视口。
我们还可以结合我们的媒体查询来定位双屏设备和某些视口宽度,以供应特定的样式:
@media (horizontal-viewport-segments: 2) and (min-width: 540px) { body { background: yellow; }}
vertical-viewport-segments
我们的视口分段媒体功能的第二个值是vertical-viewport-segments,这是设备铰链水平时设备的状态,并且硬件铰链将我们的视口分成行。
vertical-viewport-segments目标设备处于水平折叠姿势。
要定位在这个方向旋转的设备,我们将利用以下代码:
@media (vertical-viewport-segments: 2) { // Styles specific to the device in this orientation}
利用 JavaScript 检测可折叠设备
在某些情形下,您可能无法或不想利用 CSS 媒体查询来检测您的用户是否在可折叠设备上,这便是 JavaScript API 的用武之地。最初,提出了一个名为 Windows Segments Enumeration 的全新 API ,但在开拓者社区通过原始试验得到反馈后,在现有的Visual Viewport API 草案规范的根本上构建更故意义。
视口段属性视口段表示位于彼此相邻的单独显示器上的窗口区域。要检测双屏设备,您可以利用以下代码查询 segments 属性:
const segments = window.visualViewport.segments;
此查询返回的值将是一个数组DOMRects,指示有多少视口。如果只有一个视口段,则查询将返回null,并以这种办法实现以防止将来涌现兼容性问题,以免开拓职员开始利用visualViewport.segments[0]针对单屏设备。
在双屏设备上,查询将返回 2 DOMRects,表示当浏览器窗口超过折叠时可用的 2 个视口。
我们存储在segments常量中的这个值是查询属性时设备状态的不可变快照,如果浏览器窗口调度大小或设备旋转,之前检索到的视口段不再有效,须要查询再次通过调度大小或方向事宜(或两者)。
如果您调度浏览器窗口的大小以仅超过一个显示区域,我们将触发调度大小事宜。
如果您旋转设备,这将触发调度大小和方向事宜,您可以利用这些事宜再次查询属性以获取浏览器显示区域确当前状态。
window.addEventListener("resize", function() { const segments = window.visualViewport.segments; console.log(segments.length); // 1});
何时利用 JAVASCRIPT API 与 CSS 媒体功能来检测 设备
CSS 媒体功能和 JavaScript 段属性都将检测双屏设备,但 JavaScript 属性最好在没有利用 CSS 时利用,当您在 Canvas2D 和 WebGL 中处理工具时可能会发生这种情形。例如,您正在开拓的游戏可以同时利用两个屏幕。
利用 CSSenv()变量除了 CSS 媒体功能之外,还引入了六个新的 CSS 环境变量,以帮助开拓职员打算显示区域的几何形状,打算铰链区域在被 Surface Duo 等物理硬件功能遮挡时的几何形状,以及它们还可用于帮助将内容放置在每个显示区域的边界内。
六个新的环境变量如下:
env(viewport-segment-width <x> <y>);env(viewport-segment-height <x> <y>);env(viewport-segment-top <x> <y>);env(viewport-segment-left <x> <y>);env(viewport-segment-bottom <x> <y>);env(viewport-segment-right <x> <y>);x和位置表示由分隔每个视口段的硬件功能创建的y二维网格,坐标0,0从左上段开始。
当您的设备处于垂直折叠姿势且视口并排时,左侧的视口段将由 表示env(viewport-segment-width 0 0),而右侧的视口段将由 表示env(viewport-segment-width 1 0)。如果您将设备转换为水平折叠姿势,视口堆叠,顶部将由 表示env(viewport-segment-height 0 0),底部视口由表示env(viewport-segment-height 0 1)。
利用env(viewport-segment-width)andenv(viewport-segment-width)时,除了索引之外,我们还可以设置一个后备值,如下所示:
env(viewport-segment-width 0 0, 100%);
但是这个额外的后备值是可选的,由作者自行决定,如果他们想包含它。
打算铰链宽度当您的设备的铰链被硬件功能遮挡时,您可以利用供应的环境变量来打算它。
我们可以利用环境变量打算设备铰链。
在我们的示例中,我们有一个处于垂直姿势的设备,并且想要找到铰链宽度,这样就不会遮挡任何内容。我们将从左显示器的右视口段中减去右显示器的左视口段:
calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));
利用 CSSenv()变量 放置内容
我们可以利用 CSS 环境变量在显示区域边界内放置内容,如果您想将内容直接放置在铰链或折叠处,这些特殊有用。
不才面的示例中,我们将在左侧第一个显示区域的铰链上直接放置图像。该区域是视口的右侧部分,因此我们将利用viewport-segment-right以下代码放置它:
img { max-width: 400px;}@media (horizontal-viewport-segments: 2) { img { position: absolute; left: env(viewport-segment-right 0 0); }}
如果我们在 Surface Duo 模式下在 Edge 开拓职员工具中仿照我们的屏幕,我们将得到以下布局:
最初利用环境变量将图像放置在我们的布局中会将其放置在缺点的显示区域中。
这不是我们想要的。图像应位于左侧的显示区域中。
由于图像是利用属性绝对定位的left,以是图像的左边缘终极与viewport-segment-right显示区域对齐。
然后,我们须要从环境变量中减去图像的宽度,以使图像与精确的铰链边缘对齐:
img { max-width: 400px;}@media (horizontal-viewport-segments: 2) { img { position: absolute; left: calc(env(viewport-segment-right 0 0) - 400px); }}
从视口段中减去图像宽度会将其沿左侧显示中的铰链放置。
现在我们将图像放置在我们想要的位置。有关如何沿铰链对齐项目的其他示例,您可以查看这个大略的盒子演示。打开Edge Developer Tools>Device Emulation然后选择Surface Duo并确保您Duo emulation处于校正方向姿势。
把它们放在一起:让我们构建一个适应双屏设备的食谱页面作为一个在做饭时常常利用手机的人,当我在我的双屏设备上时会适应的食谱网站会非常有帮助。让我们来看看如何考虑为它调度一个单独的食谱页面。
我想考虑我将如何分块我的紧张内容。常日情形下,我至少会看到食谱标题、制作的份量、烹饪须要多永劫光、一张或多张图片、配料以及制作菜肴的步骤。
当我画出我的线框时,我得到以下信息:
桌面上食谱页面的标准布局
我希望我的标题和食谱详细信息在最顶部,然后是一个霸占全体内容宽度的图像,然后是成分列表和食谱步骤。我不想堆叠后两个内容组,由于如果我堆叠它们,成分列表的右侧会有很多空缺,以是我希望步骤坐在身分阁下,给我两列图片下方。
用于布局的 CSS 网格或 FLEXBOX?我知道我想如何在普通桌面屏幕上支配这个食谱,并且有多种方法可以对这个布局进行编码和对内容进行分组,但我如何对其进行分组,以及我想在双屏上实现什么布局在我编码之前须要考虑设备。根据我为桌面视图所做的草图,我可以利用 flexbox 和 CSS Grid 的组合来实现我想要的布局,我将身分和步骤分组到一个 flex 容器中。但是让我勾勒一下我希望我的页面如何在双屏上显示。
垂直折叠位置的可折叠设备上的空想布局通过显示屏将内容分开,因此不会被铰链遮挡。
如果我想在布局上有更大的灵巧性,那么我不能将我的身分和步骤分组到一个 flex 容器中,否则,无论图像没有进入哪一列,都会有很大的空缺。
如果我只在这个布局中利用 flexbox,它会产生一些我想避免乱用的间距。
添加我们的内容我将在桌面和双屏布局中只利用 CSS Grid。以是,让我们构建我们的内容。
<main> <section class="recipe"> <div class="recipe-meta"> … <!—Contains our recipe title, yield and servings --> </div> <img src="imgs/pasta.jpg" alt="Pasta carbonara photographed from above on a rustic plate" /> <div class="recipe-details__ingredients"> …<!— Contains our ingredients list --> </div> <div class="recipe-details__preparation"> … <!— Contains our list of steps to put the ingredients together --> </div> </section></main>
接下来,让我们构建页面的构造。我要定义我的网格:我只想要三列,并且我希望它们是容器的相等部分。
.recipe {display: grid;grid-template-columns: repeat(3, 1fr);
接下来,我将定义我的行,并且我将利用grid-auto-rowswith minmax,这样我的行是最小的,175px但可以增长到最大内容高度的最大值。
grid-auto-rows: minmax(175px, max-content);
然后我将添加更多属性: my grip-gap、我的最大内容宽度和一个边距,以使我的布局在页面上居中。
grid-gap: 1rem;max-width: 64rem;margin: 0 auto;}
然后,我将把我的内容放入我定义的网格中:
.recipe-meta { grid-column: 1 / 4;}.recipe-meta p { margin: 0;}img { width: 100%; grid-column: 1 / 4;}.recipe-details__ingredients { grid-row: 3;}.recipe-details__preparation { grid-column: 2 / 4; grid-row: 3;}
这将根据我的草图为我供应布局:
布局在桌面上按预期呈现
伟大的!
但是我的双屏布局呢?让我们深入理解我们的horizontal-viewport媒体功能和双屏网格。
首先,这是我现在在双屏上的布局:
在没有实现任何双屏代码的情形下,如果用户想要将浏览器跨过两个显示器,那么页面将是这样的。
如果我们向下滚动:
如果用户选择超过两个显示器,则内容会被铰链遮挡。
不是很好。我们的内容被铰链遮住了,以是让我开始重新定义我的网格。
对付我的网格列,我仍将利用三列,但我希望一列霸占左侧的第一个视口段,其余两列霸占右侧视口段,因此我将利用我的 CSS环境变量env(viewport-segment-width 0 0)见告浏览器,对付我的第一列,我希望它霸占第一个显示区域的全体视口。
@media (horizontal-viewport-segments: 2) {/ Body styles for smaller screens /body { font: 1.3em/1.8 base, 'Playfair Display', serif; margin: 0; }.recipe { grid-template-columns: env(viewport-segment-width 0 0 1fr 1fr; grid-template-rows: repeat(2, 175px) minmax(175px, max-content);}}
对付我的行,我希望在放置上更灵巧一点,以是我将重复两行175px,这是关于带有配方标题、产量和韶光信息的容器的高度,之后的行该当匹配我最初在网格中定义的内容。
如果我在 DevTools 中检讨我的设计,我可以看到我在配方容器上设置的width和margin最初将我想要与我的视口段对齐的网格线推到精确的视口段中。
添加我的代码后,我的内容不再被遮挡,但仍须要一些间距调度。
要重置它,我将重置我的marginand max-width。
@media (horizontal-viewport-segments: 2) {.recipe { grid-template-columns: env(viewport-segment-width 0 0) 1fr 1fr; grid-template-rows: repeat(2, 175px) minmax(175px, max-content); margin: 0; max-width: 100%;}}
重置我的边距和添补会粉饰右侧显示中的内容。
现在我要把我的内容放在网格中并调度我的布局。
.recipe-meta { grid-column: 1 / 2; padding: 0 2rem;}img { grid-column: 2 / 4; grid-row: 1 / 3; width: 100%; height: 100%; object-fit: cover; / necessary to keep the image within the grid lines /}.recipe-details__ingredients { grid-row: 2; padding: 0 2rem;}.recipe-details__preparation { grid-column: 2 / 4; grid-row: 3; padding: 0 2rem 0 3rem;}
我已经对内容运用了添补,除了我决定要超过全体视口的图像。对付图像下方的内容,由于从物理铰链下方开始的网格线的性子,我想添加额外的添补,因此它看起来左侧的添补与其他带有添补的项目相同。如果我不添加额外的,它会落得太靠近铰链。由于我已经有一个 grid-gap1rem并且我想将 padding 更加,以是我将添加3rem而不是4rem为我们供应双屏设备上的终极布局:
我可以重新添加尺寸更得当的添补来显示内容,因此它不会在带有物理铰链的设备上被遮挡。
只需对我们的 CSS 进行一些小的调度并利用个中一项新的媒体功能,我们就有了一个适应双屏设备的布局。要查看体验,请前往此处的 Edge 演示站点或基于 Chromium 的浏览器,然后打开浏览器开拓职员工具以查看 Surface Duo 仿真。如果您在 Chrome 中打开该站点,请确保在 下启用了实验性网络平台功能标志chrome://flags,以便演示精确显示。
单屏相应式设计细节为了确保我们考虑到小型单屏设备,我为手机布局选择的代码利用了 flexbox 并将所有内容放在一个列中:
@media (max-width: 48rem) { body { font: 1.3em/1.8 base, 'Playfair Display', serif; } .recipe-details { display: flex; flex-direction: column; }}
API 浏览器可用性和无设备测试
默认情形下,这些双屏 API 在 Microsoft Edge 和 Android 上的 Edge 中可用,从版本 97 开始。这些操持很快就会涌如今其他 Chromium 浏览器中,但详细韶光尚未确定。要在 Chrome 中启用这些 API,请转到chrome://flags并启用实验性网络平台功能。
虽然这些是相对较新的设备,但许多现在已经进入第二代和第三代,因此公司正在投资它们。如果您无法利用物理设备,最好的测试方法是利用浏览器开拓工具。我已经在仿真工具和 Surface Duo 上测试了我的网站,Duo 的仿真工具彷佛是相同的。我的设计在设备上的外不雅观与在 DevTools 中的外不雅观相同。它使构建和设计双屏设备就像开拓桌面和单屏移动设备一样随意马虎。
如果您利用的是不支持这些 API 的桌面或设备,则可以为 Visual Viewport Segments 属性供应一个 polyfill。CSS 媒体查询没有 API。目前,市场上的双屏设备都是基于安卓的,这些API操持在安卓上可用的基于Chromium的浏览器中。
如果可折叠设备上的浏览器不支持这些功能,您可以利用 polyfill 或确保您的网站在小单屏上仍能很好地呈现,由于用户可以灵巧选择如何在双屏上显示网站屏幕设备。他们可以跨两个显示器超过一个网站,或者他们可以选择让它跨一个显示器,如果他们选择后者,它将像在平板电脑或手机上一样显示。纵然您的网站没有双屏实现,用户仍旧可以选择单显示视图。双屏 API 供应了一种方法来逐步增强拥有设备的用户的体验。
结束双屏设备只是相应式设计的下一个发展方向。如果您有 PWA 或网站,可用的 API 可以无缝集成到您现有的代码库中。还有其他方法可以为双屏设备构建运用程序,您可以在Surface Duo 文档https://docs.microsoft.com/en-us/dual-screen/中查看这些方法。这是在网络上进行布局的激动民气的时候,双屏供应了得到更多创意的机会。
为帮助到一部分同学不走弯路,真正达到一线互联网大厂前端项目研发哀求,首次实力宠粉,打造了《30天寻衅学习操持》,内容如下:
HTML/HTML5,CSS/CSS3,JavaScript,真实企业项目开拓,云做事器支配上线,从入门到精通
PC端项目开拓(1个)移动WebApp开拓(2个)多端相应式开拓(1个)共4大完全的项目开拓 !
一行一行代码带领实践开拓,实际企业开拓怎么做我们便是怎么做。从学习一开始就进入事情状态,省得摧残浪费蹂躏韶光。
从学习一开始就同步利用 Git 进行项目代码的版本的管理,Markdown 记录学习条记,包括真实大厂项目的开拓标准和设计规范,命名规范,项目代码规范,SEO优化规范
从蓝湖UI设计稿 到 PC端,移动端,多端相应式开拓项目开拓
真机调试,云做事支配上线;Linux环境下 的 Nginx 支配,Nginx 性能优化;Gzip 压缩,HTTPS 加密协议,域名做事器备案,解析;企业项目域名跳转的终极办理方案,多网站、多系统支配;利用 利用 Git 在线项目支配;这些内容在《30天寻衅学习操持》中每一个细节都有讲到,包含***+图文教程+项目资料素材等。只为实力宠粉,真正一次节制企业项目开拓必备技能,不走弯路 !
过程中【不涉及】任何用度亲睦处,非诚勿扰 。
如果你没有添加助理老师微信,可以添加下方微信,解释要参加30天寻衅学习操持,来自今日头条!
老师会约请你进入学习,并给你发放干系资料。
30 天寻衅学习操持 Web 前端从入门到实战 | arry老师的博客-艾编程