CSS是关于盒子的造型。事实上,整个网络都是由盒子组成的,从浏览器的视口到页面上的元素。但是,每隔一段时间就会出现一个新的功能,让我们重新思考我们的设计方法。
例如,圆形显示器使我们可以玩弄圆形的剪辑区域。移动屏幕的凹槽和虚拟键盘提供了挑战,以最好的方式组织内容,保持它们的清晰。而双屏或可折叠的设备让我们重新思考如何在许多不同的设备姿势中最好地利用可用空间。

圆形显示器的草图,常见的矩形移动显示器,以及可折叠显示器的设备。
网络平台最近的这些演变使产品设计既更具挑战性,也更有趣。它们是我们突破矩形盒子的好机会。
我想谈一谈与上述类似的新功能:渐进式网络应用程序(PWA)的窗口控制覆盖。
渐进式网络应用程序正在模糊应用程序和网站之间的界限。它们结合了两个世界的优点。一方面,它们像网站一样稳定、可链接、可搜索和可响应。另一方面,它们提供额外的强大功能,可以离线工作,并像本地应用程序一样读取文件。
作为一个设计表面,PWA真的很有趣,因为它们挑战我们去思考混合网络和设备原生的用户界面可以是什么。特别是在桌面设备上,我们有超过40年的历史告诉我们应用程序应该是什么样子的,要打破这种思维模式可能很困难。
但最终,桌面上的PWA被限制在它们出现的窗口中:一个顶部有标题栏的矩形。
下面是一个典型的桌面PWA应用的样子。

两个矩形用户界面的草图分别代表了macOS和Windows操作系统上的桌面渐进式网络应用程序的现状。
当然,作为PWA的作者,你可以选择标题栏的颜色(使用Web Application Manifest 主题_颜色属性),但仅此而已。
如果我们能跳出这个框框,收回应用的整个窗口的地产,会怎么样?这样做会给我们一个机会,让我们的应用程序更漂亮,感觉更融入操作系统。
这正是 "窗口控制覆盖 "所提供的。这个新的PWA功能使我们有可能利用应用程序的全部表面区域,包括标题栏通常出现的地方。
关于标题栏和窗口控制
让我们先来解释一下什么是标题栏和窗口控件。
标题栏是显示在应用程序窗口顶部的区域,它通常包含应用程序的名称。窗口控制是使最小化、最大化或关闭应用程序窗口成为可能的功能或按钮,也显示在顶部。
一个矩形应用程序用户界面的草图,突出了标题栏区域和窗口控制按钮。
窗口控制叠加消除了标题栏和窗口控制区域的物理约束。它释放了应用程序窗口的全部高度,使标题栏和窗口控制按钮能够叠加在应用程序的网页内容之上。
一个使用窗口控制叠加的矩形应用程序用户界面的草图。标题栏和窗口控制不再处于与应用程序内容分离的区域。
如果你是在台式电脑上阅读这篇文章,请快速浏览一下其他的应用程序。他们很可能已经在做与此类似的事情。事实上,你用来阅读这篇文章的网络浏览器就使用顶部区域来显示标签。
浏览器用户界面顶部区域的截图显示了一组标签,它们与应用程序窗口控件共享相同的水平空间。
Spotify将专辑封面一直显示到应用窗口的顶部边缘。
Spotify的桌面应用程序中的专辑截图。专辑图样横跨主内容区的整个宽度,一直到窗口的顶部和右侧边缘,以及左侧的主导航区的右侧边缘。应用程序和专辑导航控件直接叠加在专辑封面之上。
Microsoft Word使用可用的标题栏空间来显示自动保存和搜索功能,以及更多。
Microsoft Word的工具栏界面的截图。文档文件信息、搜索和其他功能出现在窗口的顶部,与应用程序的窗口控件共享相同的水平空间。
这个功能的全部意义在于允许你用你自己的内容来利用这个空间,同时提供一种方法来说明窗口控制按钮。它使你能够在一系列平台上提供这种修改后的体验,同时不会对不支持窗口控制覆盖的浏览器或设备上的体验产生不利影响。毕竟,PWA是关于渐进式增强的,所以这个功能是一个增强你的应用程序的机会,以便在它可用时使用这个额外空间。
让我们来使用这个功能
在本文的其余部分,我们将在一个演示应用程序上工作,以了解更多关于使用该功能的信息。
这个演示应用程序被称为1DIV。它是一个简单的CSS游乐场,用户可以使用CSS和单一的HTML元素创建设计。
该应用程序有两个页面。第一个页面列出了你已经创建的现有CSS设计。
1DIV应用程序的截图,显示了用户创建的CSS设计的缩略图网格。
第二页使你能够创建和编辑CSS设计。
1DIV应用程序编辑页面的截图。窗口的上半部分显示已渲染的CSS设计,窗口下半部分的文本编辑器显示用于创建该设计的CSS。
由于我已经添加了一个简单的网络清单和服务工作者,我们可以在桌面上将该应用作为PWA安装。下面是它在macOS上的样子。
1DIV应用程序的缩略图和CSS编辑器在macOS上的截图。这个版本的应用程序窗口在顶部有一个单独的控制栏,用于显示应用程序名称和窗口控制按钮。
而在Windows上。
Windows操作系统上的1DIV应用程序缩略图视图和CSS编辑器视图截图。这个版本的应用程序的窗口在顶部也有一个单独的控制条,用于应用程序名称和窗口控制按钮。
我们的应用程序看起来不错,但第一页中的白色标题栏是浪费了空间。在第二页中,如果设计区一直延伸到应用程序窗口的顶部,那就真的很好了。
让我们使用窗口控制叠加功能来改善这一点。
启用窗口控制叠加功能
该功能目前仍是试验性的。要尝试它,你需要在一个支持的浏览器中启用它。
截至目前,它已经在Chromium中实现,作为微软和谷歌的合作项目。因此,我们可以在Chrome或Edge中使用它,方法是进入内部的about://flags页面,并启用Desktop PWA Window Controls Overlay标志。
使用窗口控制叠加
要使用该功能,我们需要在我们的网络应用程序的清单文件中添加以下display_override成员。
{
"name": "1DIV",
"description": "1DIV is a mini CSS playground",
"lang": "en-US",
"start_url": "/",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display_override": [
"window-controls-overlay"
],
"icons": [
...
]
}
表面上看,该功能使用起来非常简单。这个清单的改变是我们使标题栏消失并将窗口控件变成叠加的唯一需要。
然而,为了给所有用户提供良好的体验,无论他们使用什么设备或浏览器,并在设计中充分利用标题栏区域,我们需要一点CSS和JavaScript代码。
下面是该应用程序现在的样子。
在macOS上使用Window Controls Overlay的1DIV应用程序缩略图的屏幕截图。独立的顶栏区域已经消失了,但窗口控件现在挡住了应用程序的一些界面
标题栏不见了,这正是我们想要的,但我们的标志、搜索栏和新按钮被窗口控件部分遮挡,因为现在我们的布局从窗口顶部开始。
这在Windows上是类似的,不同的是关闭、最大化和最小化按钮出现在右侧,与PWA控制按钮组合在一起。
在Windows操作系统上使用Window Controls Overlay的1DIV应用程序缩略图显示的屏幕截图。独立的顶栏区域不见了,但窗口控件现在挡住了应用程序的一些内容。
使用CSS来清除窗口控件
伴随着这个功能,新的CSS环境变量也被引入。
titlebar-area-x**titlebar-area-y****titlebar-area-width**titlebar-area-height
你使用这些变量和CSS env()函数来定位你的内容,同时确保它不会与窗口控件重叠。在我们的例子中,我们将使用其中的两个变量来定位我们的标题,其中包含标志、搜索栏和新按钮。
header {
position: absolute;
left: env(titlebar-area-x, 0);
width: env(titlebar-area-width, 100%);
height: var(--toolbar-height);
}
这个 **titlebar-area-x** 变量给了我们从视口左边到标题栏出现的位置的距离,而 **titlebar-area-width**是它的宽度。(记住,这并不等同于整个视口的宽度,只是标题栏的部分,如前所述,它不包括窗口控件)。
通过这样做,我们确保我们的内容保持完全可见。我们还定义了回退值(函数中的第二个参数 **env()**函数中的第二个参数),以便在变量没有被定义时(例如在不支持的浏览器上,或者当Windows控制叠加功能被禁用时)。
macOS上的1DIV应用程序缩略图视图的截图,其中有窗口控制覆盖和我们的CSS更新。窗口控件所阻挡的应用程序内容已经被重新定位。
1DIV应用程序在Windows操作系统上的缩略图截图,带有Window Controls Overlay和我们更新的CSS。窗口控件所遮挡的应用程序内容已经被重新定位。
现在我们的标题适应了周围的环境,而且感觉不到窗口控制按钮是事后添加的。这个应用程序看起来更像一个本地应用程序。
改变窗口控制按钮的背景颜色,使其与周围环境融为一体
现在让我们仔细看看我们的第二个页面:CSS操场编辑器。

1DIV应用程序CSS编辑器视图的截图,在macOS和Windows中分别带有窗口控制覆盖。窗口控件叠加区域的背景颜色为纯白色,这与编辑器中显示的CSS设计示例的热粉色形成鲜明对比。
不是很好。我们的CSS演示区确实一直到顶部,这正是我们想要的,但窗口控件在上面以白色矩形出现的方式相当刺眼。
我们可以通过改变应用程序的主题颜色来解决这个问题。有几种方法来定义它。
- PWA可以在网络应用程序清单文件中使用 "清单 "成员定义主题颜色。 theme_colormanifest成员定义主题色。这种颜色然后被操作系统以不同方式使用。在桌面平台上,它被用来为标题栏和窗口控件提供背景色。
- 网站也可使用主题颜色元标签。它被浏览器用来定制网页周围用户界面的颜色。对于PWA,这种颜色可以覆盖清单中的**
theme_color**.
在我们的案例中,我们可以将manifest **theme_color**为白色,以便为我们的应用程序提供正确的默认颜色。操作系统将在安装应用程序时读取该颜色值,并使用它来使窗口控件的背景颜色为白色。这种颜色对我们带有演示列表的主页面非常有效。
该 **theme-color**元标签可以在运行时使用JavaScript进行更改。因此,我们可以这样做,在打开一个演示时用正确的演示背景颜色覆盖白色。
这里是我们要使用的函数。
function themeWindow(bgColor) {
document.querySelector("meta[name=theme-color]").setAttribute('content', bgColor);
}
有了这个,我们可以想象,使用颜色和CSS过渡可以产生从列表页到演示页的平滑变化,并使窗口控制按钮与应用程序的其他界面融为一体。
Windows操作系统上的1DIV应用程序CSS编辑器视图的截图,窗口控制叠加和更新的CSS演示了窗口控制按钮如何与应用程序界面的其他部分融合。
拖动窗口
现在,完全摆脱标题栏确实有一个重要的可访问性后果:移动应用程序的窗口变得更加困难。
标题栏为用户提供了一个相当大的点击和拖动区域,但通过使用窗口控制覆盖功能,这个区域就被限制在控制按钮的位置,用户必须非常精确地瞄准这些按钮来移动窗口。
幸运的是,这可以通过CSS的 **app-region**属性。目前,这个属性只在基于Chromium的浏览器中支持,并且需要 **-webkit-**供应商的前缀。
为了使应用程序的任何元素成为窗口的拖动目标,我们可以使用以下方法。
-webkit-app-region: drag;
也可以明确地让一个元素成为不可拖动的。
-webkit-app-region: no-drag;
这些选项对我们来说是很有用的。我们可以让整个标题成为拖动目标,但让其中的搜索栏和新按钮不可拖动,这样它们仍然可以正常使用。
然而,由于编辑器页面不显示页眉,用户在编辑代码时就无法拖动窗口。因此,让我们使用一个不同的方法。我们将在页眉之前创建另一个元素,也是绝对定位的,专门用于拖动窗口。
<div class="drag"></div>
<header>...</header>
.drag {
position: absolute;
top: 0;
width: 100%;
height: env(titlebar-area-height, 0);
-webkit-app-region: drag;
}
通过上面的代码,我们让可拖动区域跨越整个视口宽度,并使用 **titlebar-area-height**变量使其与标题栏的高度相当。这样一来,我们的可拖动区域就与窗口控制按钮对齐了,如下图所示。
而且,现在,要确保我们的搜索栏和按钮仍然可用。
header .search,
header .new {
-webkit-app-region: no-drag;
}
通过上述代码,用户可以点击并拖动标题栏原来所在的位置。这是一个用户期望能够用来在桌面上移动窗口的区域,而我们没有打破这种期望,这很好。
用鼠标在Windows桌面上拖动1DIV应用程序的动画视图。
适应窗口大小的调整
对于一个应用程序来说,知道窗口控制覆盖层是否可见以及它的大小何时改变可能是有用的。在我们的例子中,如果用户把窗口弄得很窄,就没有足够的空间来容纳搜索栏、标志和按钮,所以我们要把它们往下推一些。
窗口控制叠加功能附带了一个JavaScript API,我们可以用它来做这件事。 navigator.windowControlsOverlay.
该API提供了三个有趣的东西。
navigator.windowControlsOverlay.visible让我们知道覆盖层是否可见。navigator.windowControlsOverlay.getBoundingClientRect()让我们知道标题栏区域的位置和大小。navigator.windowControlsOverlay.ongeometrychange让我们知道尺寸或可见度何时改变。
让我们用它来注意标题栏区域的大小,如果标题栏太窄,就把标题往下移。
if (navigator.windowControlsOverlay) {
navigator.windowControlsOverlay.addEventListener('geometrychange', () => {
const { width } = navigator.windowControlsOverlay.getBoundingClientRect();
document.body.classList.toggle('narrow', width < 250);
});
}
在上面的例子中,我们把 narrow类在 body如果标题栏区域窄于250px,我们就把类设置在应用程序的。我们可以用媒体查询做类似的事情,但使用 windowControlsOverlayAPI对于我们的用例有两个优势。
- 只有当这个功能被支持和使用时,它才会被启动;否则我们不想调整设计。
- 我们获得了跨操作系统的标题栏区域的大小,这很好,因为窗口控件的大小在Mac和Windows上是不同的。使用媒体查询就不可能让我们确切地知道还有多少空间。
.narrow header {
top: env(titlebar-area-height, 0);
left: 0;
width: 100%;
}
使用上述CSS代码,我们可以在窗口太窄的情况下,将我们的标题向下移动,以远离窗口控制按钮,并相应地将缩略图向下移动。
1DIV应用程序在Windows上的截图,显示了为更窄的视口而调整的应用程序的内容。
30个像素的令人兴奋的设计机会
使用窗口控制叠加功能,我们能够把我们简单的演示应用程序,变成在桌面设备上感觉更加集成的东西。它跳出了通常的窗口限制,并为用户提供了自定义的体验。
在现实中,这个功能只给了我们大约30个像素的额外空间,并带来了如何处理窗口控制的挑战。然而,这个额外的空间和这些挑战可以被转化为令人兴奋的设计机会。
更多不同形状和形式的设备不断被发明出来,而网络也在不断发展以适应它们。新的功能被添加到网络平台上,使我们这些网络作者能够越来越深入地与这些设备相结合。从手表或可折叠设备到桌面电脑,我们需要为网络发展我们的设计方法。现在,为网络而建让我们能够跳出矩形框框的思维。
因此,让我们拥抱这一点。让我们使用我们已经掌握的标准技术,并尝试新的想法,为所有的设备提供量身定做的体验,所有这些都来自于一个代码库