你们都知道 Hakim El Hattab 吧?他在 他的博客 上创建了一些非常酷炫的渐进式演示。他的 CodePen 个人资料 也充满了惊人的作品。
他最近的作品之一是 Avgrund。这是一种用于对话框的设计模式,其中主页面逐渐淡出,模态框从上方(或下方)飞入。主页面变小并变得模糊,使其看起来更远,类似于摄影中的 景深。模态框位于顶部,使其看起来更靠近您,并清晰地要求您关注。这是好事,因为 模态框 的目的就是要求用户在进行其他操作之前提供一些输入。

当你看到并使用它时,感觉非常神奇。有点想右键单击看看它是否是 Flash。但它不是,就像网络上许多东西一样,当你开始深入挖掘时,神奇之处仅仅是简单效果的巧妙组合。
让我们按顺序看看它们。注意: 这并不完全是 Avgrund 的工作原理,这只是我反向工程的结果。
步骤 1) 分离页面标记和模态标记
整个页面上的所有内容都应包含在一个包装器 div 中。模态位于该包装器之外。
<body>
<div id="page-wrap">
<!-- all page content -->
</div>
<div id="modal">
<!-- modal box content -->
</div>
</body>
标记如何到达那里取决于您。如果我在实际使用它,我可能会在需要时通过我专门为处理对话框创建的 JavaScript 代码动态注入它。
步骤 2) 基于状态的 CSS
无需使用过于复杂的 JavaScript。如果我们考虑“基于状态”,我们只需要在 body 元素上添加一个类名,然后就可以根据需要使用该类调整所有视觉设计。这是一个更大的概念,在很多方面都很有用,值得进一步讨论(例如如何/在哪里/为什么要触发状态),但在这里让我们只使用一些 jQuery 来保持简单。
// Something happens
$("button").on("click", function() {
// State changes
$("body").toggleClass("dialogIsOpen");
});
步骤 3) 模态的默认状态
模态将是一个固定位置的框,位于屏幕的正中间。默认情况下,它将隐藏(不透明度为零)且不可点击(pointer-events)。让我们先忽略浏览器对它的支持。如果这对你来说很重要,你可以用很多其他方法隐藏它,比如将其定位到屏幕外。
#modal {
background: white;
position: fixed;
width: 50%;
top: 50%;
left: 50%;
margin: -25% 0 0 -25%;
/* Embiggen */
transform: scale(1.5); /* prefix me */
/* Hidden */
opacity: 0;
pointer-events: none;
}
步骤 4) 活动模态状态(神奇之处!)
现在我们拥有了使页面在模态打开时“后退”所需的一切。让我们在状态处于活动状态时定位 #page-wrap 并执行魔法。
神奇之处在于: 通过变换缩放 #page-wrap 使其变小,并过滤 #page-wrap 使其模糊且色彩减少。
.dialogIsOpen #page-wrap {
/* Blur and de-color */
-webkit-filter: blur(5px) grayscale(50%);
/* Recede */
-webkit-transform: scale(0.9);
}
仅限 WebKit?嗯……过滤器目前仅在 WebKit 中可用。您可以选择是否加载供应商前缀。如果我要在网站上实际使用它,我会花一些时间确保此效果有备用方案,这应该不难。也许只是强调一下 box-shadow 就行了。
然后: 使对话框从上方出现,强制执行景深效果。不透明度使其出现;变换缩放使其从上方出现。
.dialogIsOpen #modal {
/* Regular size and visible */
transform: scale(1); /* prefix me */
opacity: 1;
/* Clickable */
pointer-events: auto;
}
步骤 5) 过渡
为了使其感觉自然和神奇,在两个参与者身上都添加一些过渡。
#page-wrap, #modal {
transition: all 0.4s ease; /* prefix me */
}
当然,Sass/Compass 使所有这些都变得更容易,因为它对所有这些东西都有 @mixins。例如:
@include transition(all 0.4s ease);
@include filter(blur(5px) grayscale(50%));
@include transform(scale(0.9));
公平警告,这些东西相当占用内存/处理能力。有时,像触发 3D 变换这样的少量技巧可以帮助 WebKit,但存在 文本外观难看 的风险。
body {
/* Use at your own discretion */
-webkit-transform: translateZ(0);
}
总结
如果您无法访问支持的浏览器或其他任何内容,请观看视频
我将本文中反向工程的演示 发布在 CodePen 上,但您确实应该去看看 Hakim 的演示,它也 发布在 CodePen 上。
太酷了!
我真的很喜欢 Hakim El Hattab 的作品——在 CodePen 上发现了它。我使用他的另一个项目 Meny 重做了我的个人网站。
模糊和灰度可以使用简单的 svg 滤镜(适用于 Firefox)和专有滤镜(适用于 IE,甚至 IE6,并且记录在案,使用旧语法可以获得 IE4!!)跨浏览器使用。
IE 缺少过渡,但是!一点 jQuery 应该可以解决问题。
性能问题有点可惜,希望能用上!!
很棒的技巧,感谢分享!
太棒了!
代码似乎没有清除!你能展示一下你在视频中使用的所有代码吗?
这在 netbook/平板电脑上的性能如何?在我的 1.6 GHz 酷睿 2 Duo 笔记本电脑上,动画有明显的延迟/卡顿。
我在一台新的 i7 笔记本电脑上试了一下,动画在这台电脑上和 Nexus4 Android(4 核)上都比较卡顿。
非常酷!想法正在涌现。可能会在我的艺术家网站上以某种方式使用它!
这是一个非常酷的交互。我喜欢它如何吸引你,你情不自禁地会关注模态。对于“您必须登录才能执行此操作”之类的消息来说可能很不错。
Hakim 万岁!我在某个 WebGL 博客上点击了一个链接,他正在那里提供指导,然后我进入了他的博客。整个星期天都在阅读。Hakim 是沉浸式前端体验之王。
喜欢这种效果。在我的老旧电脑上有点卡顿(双核处理器万岁)
可能会在未来的项目中尝试一下。
很棒的作品,非常感谢分享!
效果非常棒。如果系统性能能够像屏幕分辨率一样(比如 CPU 核心数)随 User Agent 一起传递,那么就可以根据系统性能轻松地降低或增强这种效果。
不过,我注意到,虽然该效果在我的 iOS6 iPhone 4 上运行时偶尔会出现一些小问题(可以通过移除模糊滤镜来解决),但我的 iPhone 5 渲染该效果时却没有任何问题,几乎达到了原生级别的流畅度。
糟糕,是我的失误。我太习惯于在 Google Analytics 中查看屏幕分辨率信息了,以至于忘记了它实际上并不是 User Agent 的一部分,而是 GA 的 JavaScript 跟踪/统计代码的一部分。
Hakim 拥有一个令人惊叹的实验作品集,其中包括本博文中展示的实验,以及其他一些实验,例如 Fokus 或 Meny(我最喜欢的之一)。
极好的灵感来源。
在切换 body 类时要小心。测试
有趣的 jsperf 测试。但我不明白为什么 IE 对 body 类没有任何结果 whatsoever。那里发生了什么?
IE 确实有 body 类的结果,但数值是:100/秒 vs. 数百万/秒(其他浏览器)。
我喜欢 Hakim 的作品!感谢分享
您好,Coyier 先生
我正在从您的文章中学习新的技巧。
您的文章很棒!
非常感谢。
模态界面,即使是美观的界面,也应该避免使用。
哇,不错 - 谢谢!
非常棒的作品。
是否可以一个按钮触发 3 个模态覆盖层?
谢谢!
Andrea
仅在**Chrome**上有效 :(
我正在尝试创建一个带有图像的员工目录,用户可以点击这些图像并生成一个模态
对话框,该对话框是交互式的(例如,点击的图片对应的员工的联系信息)。
这似乎为我提供了一个实现方法的提示,但我不想冒险构建不应该构建的东西,或者重建那些使用现有的 WordPress 插件即可轻松完成的事情。任何反馈都将不胜感激。