窗的类型有非常多种,所以在使用时很容易被滥用,这样不仅会对用户带来困扰,也会让我们的设计中出现细枝末节的问题。本篇文章分析和总结了不同弹窗的使用场景及工作中的实际应用,知道这些后,以后再也不会“滥用”弹窗啦!
我们口中常说的弹窗其实是个广义的范围,包括了对话框,动作菜单,浮出层,toast,snackbar等,这么多类型的弹窗在使用中很容易混乱或者说滥用,反而得不偿失,给用户带来更多困扰。故本篇文章主要分析和总结不同弹窗的使用场景及工作中的实际应用。
官方的设计样式会提到,但是细节不展开,有需要的可以参阅MD官方文档和苹果HIG官方文档,文档里介绍的都很细致。
除了官方文档,本文还参阅了很多前辈的总结分析,参考链接已置于文末。(配图主要来自体验过程中的app截图,安卓部分截图主要来自MD规范)
在App使用中,弹窗出现的频率越来越高,运营活动,系统通知,信息反馈,任务引导等。滥用的弹窗会渐渐导致用户认知疲劳和视觉失调,甚至会出现“习惯性取消”等行为。
弹窗最主要的功能就是服务于当前主任务之外的支线任务,包括信息传递,操作反馈等。
对话框,警告框,toast……都属于弹窗,但是使用场景都不一样。
在合适的业务场景选择合适的弹窗组件,能够保证最基础的用户体验。因为像强干扰类弹窗的使用,对用户而言,更是一种强加的任务,很容易导致用户丧失耐心而流失。
弹窗可以按照是否强制打断用户操作来分成两种,模态弹窗和非模态弹窗(也可以叫做阻断式弹窗和非阻断式弹窗)。
模态弹窗:模态提供了一个专注聚焦的环境,用户只有完成或者关闭当前任务,才能进行其他任务。
特点:打断用户当前的操作流程,属于强势的干扰行为,故运用弹窗需要慎重考虑。
常用组件:dialog(对话框)/alert(警告框)、popover(浮出层)、action sheet(动作菜单)、activity views(活动视图)、modal bottom sheet(模态底部菜单)。
非模态弹窗:常用于轻量级的操作反馈和信息传递,不需要获取屏幕焦点,用户可以同时操作屏幕中的其他内容。
特点:属于轻量级的反馈,不会对用户流程产生干扰,但同时又给了用户反馈和信息。
常用组件:Toast(吐司),snackbar,Hud(透明指示层)。
dialog和alert分别是MD和ios的官方弹出框,是最常见的弹窗,两者功能一样,在使用上以及样式上略有区别(下文分析统一称为弹出框)。
弹出框通常用来传达和app及设备相关的重要信息,并且要求用户操作或反馈,且其出现在屏幕中央,对内容遮挡严重,会中断用户正常操作。用户只有完成或者关闭当前任务,才能进行其他任务。
其官方样式如下:
4.1.1 使用场景
通知用户app或设备相关的问题:
通过强干扰通知用户设备相关问题如备份,低电量等问题;这些潜在问题可能会对用户造成一定负面的影响。
再比如app的版本更新,消息通知,首饰引导等都关系到用户的利益,所以也会用强干扰的方式让用户明确知道并选择。
辅助用户完成任务,如系统权限:
用户在进行任务的过程中,受到阻拦,必须通过其他辅助操作帮助他完成任务。
如完成一些任务必须要开启相应的系统权限:上传照片要开启相册权限;拍小视频要麦克风权限;出行外卖等产品要开启定位权限;新建相册必须要为相册命名;下载app要登录itunes账号。
用户主动中断任务,破坏性操作等:
用户中断当前任务,对之前的操作有一定的影响,或者一些无法挽回的破坏性操作,故需强干扰的弹窗通知,避免用户因为失误有了不可挽回的损失。如退出账号;删除订单,活动消息等;放弃编辑。
操作反馈:
当操作后的反馈比较重要,会影响用户接下来的操作或会影响当下的任务,那就需要用强干扰让用户明确知道,要完成此操作需要什么,或者接下来会发生什么。
例如西瓜视频的结算通过强干扰通知到用户想要结算应该怎么做。
运营活动:
现在用弹出框来传递运营活动已经成为一个约定俗成的用法了,虽然ios规范中建议尽量少用弹出框,但公司还是要盈利的,所以基本上所有app都会以这种强干扰的形式来通知用户“这里有优惠活动”等运营活动。
这种场景下,弹出框会根据产品以及业务的运营需求及产品的调性做丰富的运营设计,来吸引用户参加运营活动,需要注意的一点,需要用户参加的buttom一定要加强,突出。
功能引导:
功能引导和运营活动一样,是产品出于业务角度考虑,用强干扰的方式吸引用户使用某功能,达到一定的业务目标,如用户活跃度。
例如完成订单后(外卖或商品)引导用户评价,并给予一定奖励。如将流量引流到新业务,从而达到新业务推广目的。
浮出层是ios的组件,是用户点击屏幕上的某个控件或区域出现在屏幕上方的临时视图,它最典型的是包含一个指向它出现位置的箭头,且浮出层一般在入口下方,整个浮出层应该位于整个屏幕的中上方。
浮出层最开始主要用于大屏幕的ipad,但由于手机屏幕越来越大,目前也被较多地运用到手机界面中。
4.2.1 使用场景
多个常用操作的快捷入口:
多个常用操作通过popover折叠起来,视觉上更清爽简洁,同时使用起来也方便,缺点是用户不能直观看到,需要一定的学习才能掌握,所以适合于有学习能力用户群的产品
呈现页面中一些折叠的信息:
属于浮出层的衍生应用,和上个场景一样,节约屏幕空间,显露出一部分,并将剩余信息折叠起来,不影响用户理解功能,又解决了屏幕空间,若用户有需求,即可展开探索更多的信息,同样也会用箭头等指向出处
对于新用户的功能引导或者新功能的引导:
此类场景也属于浮出层的衍生应用,主要通过带指向箭头的浮层引导用户学习某个功能,一般需要学习的功能是高亮的,且箭头指向它。
actionsheet是ios系统中特定的警告框,用来响应动作或控件,或者呈现和当前内容相关的两个及更多的选项。一般在屏幕底部。官方不建议在动作菜单中应用滚动条,所以动作菜单中的选项不能过多。
4.3.1 使用场景
当前对象的多个操作或者完成任务的多个选择:
对当前对象的的多个操作,如qq中对图片长按,出现多个对该图片可进行的操作,帮助完成任务。除了文字列表外,还可以用图标+宫格式的展示方式,例如分享功能的多个选项。
执行潜在的破坏性操作前的二次确认:
当执行潜在的破坏性操作前需再做提醒,避免产生不可挽回的失误。需注意的是破坏性操作的按钮需重点突出,一般用红色,起到警示,危险的提醒作用
和alert的区别:
alert主要适用于两个选项,而actionsheet可以有多个功能选项,且展示形式更多样。前文讲过,alert也有破坏性操作提醒的场景使用。
两者相比,alert出现在屏幕中央,actionsheet出现在屏幕底部。视觉角度上alert相较于actionsheet更有阻断感,对用户而言干扰性更大。
另一方面底部的actionsheet从手势操作的角度上来看,操作更方便,更容易对此作出选择或关闭。所以alert更加适用于严重后果的破坏性操作提醒。
活动视图是ios组件,是针对当前页面提供的一系列任务和服务,例如复制,收藏,查找等。系统提供了许多内置活动,包括打印,信息和AirPlay。
这些任务始终首先出现在活动视图中,无法重新排序。无需创建执行这些内置任务的自定义活动。活动视图还显示来自其他应用的共享和操作扩展。
Bottom sheet是MD的组件,MD中底部菜单有两种,一种是Standard bottom sheet(标准底部菜单),另一种是Modal bottom sheet(模态底部菜单)。
MD的模态底部菜单和iOS的action sheet类似,它阻止用户与屏幕其他地方交互,通过聚焦的底部菜单提供了更多的选项和功能。它可以是内联菜单和简单对话框的替代方案,为内容,图标和动作提供了额外的空间。
规范建议,模态底部淡淡的初始垂直位置的上限为屏幕高度的50%。内容超过屏幕高度50%的模态菜单可以在整个屏幕上拉动,在内部滚动以访问其余项目。同样他的展现方式有列表式,也可有宫格式
snackbar是android专有控件,是出现在屏幕底部的提供有关app相关的简短信息提醒,它属于轻量级的信息提醒,一般出现几秒后就会自动消失,不会中断用户操作。
snackbar往往由一条文案+一个引导性按钮(可选,按钮可以引导用户进一步操作)组成,带有一定的交互性。因为它自动会消失,所以它一定没有取消或者不要等否定性按钮。
4.6.1 使用场景
传达轻量级的信息和操作反馈,可以引导用户操作:
传达轻量级的信息或反馈,并且可以引导用户进行下一步行为,但并不强制用户操作。比如chrome添加书签时,可以进一步对新加的书签进行编辑;删除书签时防止用户后悔,提供一个撤销按钮。
Toast是android专有的控件,原先的MD规范中,toast是和snackbar放在一起讲的,翻阅了最新的MD规范,snackbar里找不到关于toast的相关介绍(有小伙伴找到的望提醒一下)。
Toast应该包含在snackbar里了,当snackbar没有按钮其实就是toast了,不过这边还是把Toast单独拿出来分析
4.7.1 使用场景
传达轻量级的信息和操作反馈,且不需要用户操作:
适用于通知用户不重要的信息和操作反馈,且不会对用户当前的任务有影响,因为不能交互,且几秒后消失,所以用户很可能忽略,所以该类信息相对而言没那么重要。
虽然toast是android专有样式,但现在很多ios版本的系统中都使用了改良版的“toast”,因为轻反馈,不打断用户操作,同时又能通知信息和操作反馈,对用户而言及其友好,但是不易传达过多的文字,因为用户很有可能会忽略。
ios文档中的feedback中有建议:反馈可以帮助人们了解应用正在做什么,发现他们下一步可以做什么,并了解行动的结果。所以实际应用中,既要不打扰用户,又要能引起用户注意,还要和产品设计相协调。
比如结合了文字和icon的样式,再比如用较为突出的背景色,位置的话在中央,顶部,底部,都会出现,会根据具体的业务来选择合适的位置。一般出现的位置会和操作内容在一起,这样用户才能清晰有效地得到即时反馈。
下方例举的toast案例因为选用了比内容更为突出的背景色,相比较上方案例的toast更易被用户发现和察觉,达到通知用户的目的。
Hud透明指示层,ios专用控件,典型的就是音量调节的弹窗样式。部分改良的toast,在样式上有借鉴学习Hud。
Dialog/Alert:
当信息或操作非常重要,并且必须要由用户做决定或者操作才能继续,一般用alert,更适用于用户判断选择。
Modal bottom sheet/Action sheet:
稍弱于dialog/alert,更着重于提供更多的功能和选项时使用。
Activity view:
是针对当前页面提供的一系列额外的任务和服务。
Popover:
使用更侧重于指向性,更适用于信息或功能折叠。
Toast:
不太重要的信息提醒和操作反馈,更适用于不需用户响应或反馈的场景。
snackbar:
不太重要的信息提醒和操作反馈,可以交互,但并不强制,更适用于可以引导用户进行下一步或者一些撤销上一步的场景。
Hud:
音量调节。
了解了每个弹窗组件的用法,下次就可以根据实际业务设计合适的弹窗了,不过官方规范或者文章的建议也都只是参考,实际工作中还是要灵活变通,设计的目标是帮助用户更好更快的解决问题。
以上就是我对弹窗相关知识的总结,总结的过程中也对官方规范弹窗部分的内容再次熟悉了好几遍,因为看的英文,所以理解上可能稍微有些不足,有不对的地方,还希望大家批评指正。(推荐大家多看看官方设计规范,就像一本非常实用的设计工具书,对于实际工作还是非常有帮助的)
再次感谢前辈的经验分享!
这个控件叫什么系列之toast的曾经,现在,与未来 https://www.uisdc.com/ui-element-toast
如何设计App中的提示控件(toast) https://zhuanlan.zhihu.com/p/22405748
iOS和Android规范解析——底部浮层(上)https://www.jianshu.com/p/8bdfbc0a9339
iOS和Android规范解析——提示框(Toast)对比 https://www.jianshu.com/p/e1beeacbea32
不要滥用对话框!细说 iOS Alert View 与 Action Sheet https://zhuanlan.zhihu.com/p/20189186
App设计中,6组常见组件的区别和用法 http://www.woshipm.com/pd/873075.html
APP提示框架详解:Toast提示、Snackers和Alert http://www.woshipm.com/pmd/296674.html
本文由 @麦子_Maizi 原创发布于人人都是产品经理。未经许可,禁止转载
题图来自Unsplash,基于CC0协议
立WordPress登录表单一般有两种实现方式,一种是建立登录页面+表单,一种是直接使用弹出窗口+表单。今天我介绍下非插件方式制作一个WordPress弹窗的登录表单,这种方法的好处就是在当前页面登录,无需跳转页面。
登录表单比较核心的函数是wp_login_form(),就利用其来实现。在functions.php中加入:
<?php
/**
* Customizing the Login Form.
* https://codex.wordpress.org/Customizing_the_Login_Form
*/
if ( ! is_user_logged_in() ) {?>
<!-- Login modal START -->
<div class="modal fade" id="modalLoginForm" tabindex="-1" aria-labelledby="modalLoginFormLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLoginFormLabel">登录</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?php
// Display WordPress login form:
$args=array(
'form_id'=> 'loginForm',
'label_username'=> __( '用户名或电子邮箱地址' ),
'label_password'=> __( '密码' ),
'label_remember'=> __( '记住我' ),
'label_log_in'=> __( '登录' ),
'remember'=> true
);
wp_login_form( $args );?>
<p class="px-3 mb-1"><a href="javascript:;">注册</a> | <a href="<?php echo esc_url( wp_lostpassword_url( $currentUri ) ); ?>"><?php esc_html_e( '忘记密码?', 'jet-x' ); ?></a></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<!-- Login modal END -->
<?php }?>
使用的是Bootstrap 5 的Modal弹窗样式,需要确定你的主题是否引入了Bootstrap。
制作一个按钮点击时弹出窗口:
<button type="button" id="loginUrl" class="btn btn-outline-dark" data-bs-toggle="modal" data-bs-target="#modalLoginForm">登录</button>
测试中,有时候会遇到弹窗的问题,有的是浏览器弹窗(alert)、有的是自定义弹窗;这节我们主要来讨论一下关于浏览器弹窗和简单的自定义弹窗。
switch_to_alert(): 定位到alert弹窗,返回一个弹窗的对象
dismiss(): 对弹窗对象的取消操作(相当于点击弹窗上的取消按钮)
accept():对弹窗对象的确定操作(相当于点击弹窗上的确定按钮)
text:对弹窗对象,获取弹窗内的文本
send_keys(key):对弹窗对象内的输入框输入数据(如果弹窗的格式有输入框的话可以使用)
authenticate(name, pass):对于身份认证弹窗,输入用户名和密码并自动提交(一般可能会用于本地搭建的一些系统)如图:
class Alert(object):
"""
Allows to work with alerts.
Use this class to interact with alert prompts. It contains methods for dismissing,
accepting, inputting, and getting text from alert prompts.
Accepting / Dismissing alert prompts::
Alert(driver).accept()
Alert(driver).dismiss()
Inputting a value into an alert prompt:
name_prompt=Alert(driver)
name_prompt.send_keys("Willian Shakesphere")
name_prompt.accept()
Reading a the text of a prompt for verification:
alert_text=Alert(driver).text
self.assertEqual("Do you wish to quit?", alert_text)
"""
def __init__(self, driver):
"""
Creates a new Alert.
:Args:
- driver: The WebDriver instance which performs user actions.
"""
self.driver=driver
@property
def text(self):
"""
Gets the text of the Alert.
"""
return self.driver.execute(Command.GET_ALERT_TEXT)["value"]
def dismiss(self):
"""
Dismisses the alert available.
"""
self.driver.execute(Command.DISMISS_ALERT)
def accept(self):
"""
Accepts the alert available.
Usage::
Alert(driver).accept() # Confirm a alert dialog.
"""
self.driver.execute(Command.ACCEPT_ALERT)
def send_keys(self, keysToSend):
"""
Send Keys to the Alert.
:Args:
- keysToSend: The text to be sent to Alert.
"""
if self.driver.w3c:
self.driver.execute(Command.SET_ALERT_VALUE, {'value': keys_to_typing(keysToSend)})
else:
self.driver.execute(Command.SET_ALERT_VALUE, {'text': keysToSend})
def authenticate(self, username, password):
"""
Send the username / password to an Authenticated dialog (like with Basic HTTP Auth).
Implicitly 'clicks ok'
Usage::
driver.switch_to.alert.authenticate('cheese', 'secretGouda')
:Args:
-username: string to be set in the username section of the dialog
-password: string to be set in the password section of the dialog
"""
self.driver.execute(
Command.SET_ALERT_CREDENTIALS,
{'username': username, 'password': password})
self.accept()
代码展示:
*请认真填写需求信息,我们会在24小时内与您取得联系。