利用栅格系统,构建优秀的响应式设计
合理运用栅格系统可以帮助我们控制布局结构并实现一致和有组织的设计,这篇文章介绍了利用栅格系统构建响应式设计。
一、写在前面
今天,90%的媒体互动都是基于屏幕的,通过手机,平板电脑,笔记本电脑,电视和智能手表来与外界产生联系。 多屏设计已成为商业设计中不可或缺的一部分,响应式设计正迅速成为常态。 作为UI设计师,我们希望为我们的产品在不同尺寸下都能为用户提供良好的用户体验,栅格系统可以帮助我们做到这一点。
即使是我们只针对一个尺寸进行设计,我们也经常面临设计布局方面的问题。 合理运用栅格系统可以帮助我们控制布局结构并实现一致和有组织的设计。 栅格系统就像无形的胶水一样凝聚一个设计,即使元素看上去是彼此分离,但通过网格将它们连接在一起,实现良好的层次结构,位置关系和一致性。
设计师和开发者之间的协作过程中,栅格系统在前端开发中是被应用的很广泛一套体系,许多优秀的设计都使用了栅格系统,使用栅格系统可以加速开发并保证视觉还原。 栅格系统虽然是传统设计方法中的一部分,但它仍旧能帮助我们去设计这个多终端的世界。
看到这里,你可能非常想知道格栅系统在页面中是如何运作的,那么今天我们一起来学习并且实践我们的格栅系统。
“The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice.”
“网格系统可以帮助我们设计,但却不能保证我们的设计。它有多种可能的用途,并且每个设计师都可以寻找适合其个人风格的解决方案。但是必须学习如何使用网格。这是一门需要实践的艺术。”
——《平面设计中的网格系统》作者Josef Müller-Brockmann
二、什么是栅格系统?
网格系统可以让你依靠秩序与逻辑去完成设计。
早在20世纪初,德国、荷兰、瑞士等国的平面设计师们 发现通过维持视觉秩序,从而使版面能更加清晰有效地传递信息,二战后这种理念在瑞士得到了良好的发展 ,直到20世纪40年代后期,第一次出现了使用网格进行辅助设计的印刷作品。
由瑞士设计师大师Josef Müller-Brockmann(约瑟夫·米勒-布罗克曼)所著的《平面设计中的网格系统》一书,自1961年出版以来畅销至今,对设计界有着深远的影响。史称Swiss Typography Movement (瑞士新浪潮平面设计运动),后来成为全球风靡的International Typographic Style (国际主义设计风格) 。
约瑟夫·米勒一布罗克曼(Josef Muller-brockmann, 1914-1996)
瑞士的一位平面设计师和教师。1958年任《新平面设计》(New Graphic Design)主编1966年被任命为 IBM 的欧洲设计顾问。布罗克曼因他的极简主义设计与简洁的排版、图形和色彩而闻名,他的设计对 21 世纪的众多平面设计师都产生了重大影响。
三、栅格系统的优势
1、减少决策成本提高设计理解力
栅格系统在页面排版布局、尺寸设定方面给了设计者直观的参考,它让页面设计变得有规律,从而减少了设计决策成本。
UI设计也是需要理性的、客观的、具有数学逻辑美感的。熟练运用网格系统能够让你的设计更有秩序和节奏感,页面信息的展现更加清晰,提高阅读效率,从而提供给用户舒适的使用体验。加快认知速度。这意味着用户在使用产品完成特定的任务时,例如发送消息,预订酒店房间或乘车。用户能够连贯的理解并找到找到下一条信息或下一步要采取的步骤。
2、响应化
因为人们使用不同类型的设备与产品进行互动,从智能手表的小屏幕到超宽屏电视,交互是流畅的,并且没有固定的尺寸。使用产品时,人们通常会在多个设备之间切换,以完成该产品的单个任务。 所以响应式设计不应该是一种奢侈品,而是一种必需品。 这意味着设计师不能再为单个设备的屏幕构建。多设备环境迫使设计人员根据动态网格系统进行思考,而不是固定宽度。使用网格可以跨不同屏幕尺寸的多个设备创建连贯的体验。
3、加速团队协作设计
当多位设计师共同设计产品时,一个统一标准就变得尤为重要。如果没有一个统一的框架去约束的话,我们的产品的页面和组件的标准可能各式各样,这样的话整个产品的页面都会比较混乱。 因此,网格系统有助于将界面设计工作分开,因为多位设计师可以在统一的布局下进行不同部分工作,并且无缝集成并保持连贯。
4、加速开发并保证视觉还原
大多数设计项目的实施,涉及到设计者和开发者之间的协作。 栅格化提高了页面布局的一致性跟复用性; 避免了设计师与开发者在细节上的反复沟通确认,从而提升了整个设计开发流程的效率、并能帮助开发者实现较为理想的设计还原。
四、栅格系统的基本构成
1. 列和槽(Columns and Gutters)
列(Column)是内容的容器,水槽(Gutter)用来调节相邻两个列的间距,把控页面留白;列和列间距加上页面边距(Margin)等于屏幕的水平宽度。
列和列间距的内容区域(Content width)由N个列和(N-1)个水槽组成。通常情况下,web 端采用 12 列,平板采用 8 列,手机采用 4 列。
当然,你可以根据项目特点来设计你的网格系统,列和水槽的宽度我们可以利用8点网格系统来定义,下面会讲到。
列的数量越多,页面就会被分割的越“碎”,在页面设计时就会越难把控,适用于业务信息量大、信息分组较多、单个盒子内信息体积较小的页面设计,列间距宽度数值对页面的影响,与外边距大体类似,即间距越大页面越轻松简单,反之亦然。
用户已经习惯通过鼠标滚轮或滚动条(scrollbar)来纵向浏览页面内容,因此竖直方向可以无限延伸,所以栅格系统在竖直方向的栅格可以不体现出来,我们在执行设计时只要在水平方向保持规律的变化就可以了。
2. 页面边距(Side Margins)
页面边距就是内容区域(Content field)以外的空间,比较推荐的设计就是页面边距可以随着屏幕尺寸的增大而增大。 页面边距在移动设备上通常是 12Px到 40Px 之间,在平板设备和桌面设备页面边距变化就相当多了。
在响应式设计中,你选择了一个页面边距之后,缩小页面宽度时页面还是会有你设置的最小页面边距,直到到达下一个响应点(breakpoint)。当你增大页面宽度时,页面就有更多的页面边距,直到页面宽度到达下一个响应点(breakpoint)。
3. 模块(Field Elements)
模块就是你的设计区块,可以是一段文字,一张图片,或是其他更加丰富的元素。背景元素并不能算作是设计模块,所以并不需要遵循栅格系统。模块的定义是很灵活的,它可以是个小的单位或是元素,也可以是一个元素丰富的区块。
以12栅格系统为例,一个12栅格系统可以根据业务需要被2等分、3等分、4等分、6等分、12等分,还可以被1:1:1、1:2:1、1:3:2、2:3:3、1:2、1:3、1:5、3:5等不对称分割,具体采用哪种比例的组合需要我们根据自己业务需求来定。
4. 8 点网格(8pt spatial system)
栅格系统大的层面可以帮助设计者更好的进行版式设计与内容布局,而小的方面可以辅助设计师规范页面内各种元素的对齐与间距的设定。从用户体验角度来讲,这两者同等重要,从执行层面来讲,我们一般先做版式设计与布局,然后再填充内容、调整细节。
由于列跟水槽的宽度是以网格作为基本单位来增加或者减小,所以栅格化的重要一步就是需要先定义好栅格的原子单位“网格”的大小。目前最普适易用的就是 8 点网格。我们也可以利用 8 点网格法来制定产品中的间距,建立 8 点为一个单位的网格,使用 8 的倍数来定义模块的间距与元素的尺寸。8 点网格有如下几点优势:
1)目前主流桌面设备的屏幕分辨率在竖直与水平方向基本都可以被8整除,使用8作为最小原子足够普适。可以确保不同布局之间的视觉一致性,同时可以灵活的适配多种尺寸的设计。以8为单位符合“偶数原则”。偶数原则可以在页面缩放中最大程度的避免类似于0.5、0.75、1.25等次像素的出现,从而使页面各类元素在大多数场景下都能有比较精致的细节表现
2)在网格系统中应该更加注重的是间距, 而间距要遵循网格系统(例如使用 4、8、16、24、32 等和 8 具有规律的数字)同时在产品中的各类元素也要遵循这类原则(例如图标大小、组件大小等)。所以布局的水平和垂直节奏和各个组件的节奏会相互重叠,整体的设计将更加完整。
3)开发工程师使用的前端开源组件库比如Metronic、Antdesign等也是基于8的原子单位来设计 ,因此如果设计师也使用以8为基本单位的栅格系统,开发与设计师相互对接就会更加方便,开发实现页面时也能更高品质的去还原我们的设计。
如果设计上没有立即可识别的间距系统时,这种设计可能会让用户感觉廉价、不一致,而且通常不值得信任。如果设计上遵循一个8pt网格系统时,节奏变得可预测和视觉上的愉悦。对于用户来说,这种体验是经过修饰和可预测的,这增加了用户对品牌的信任和喜爱。
无论有多少个设计师在协同合作, 现在都有一个一致的间距规范,决策成本将大大降低。 设计师可以轻松地从另一个设计师停止的地方开始设计,或者轻松地并行构建。我们定义下规范可以及时和开发同学沟通,因此可以为工程师节省时间。
5. 基线网格(Baseline Grid)
基线网格由密集的水平行组成,这些行提供文本的对齐和间距准则,类似于您在直纹纸上书写的方式。在下面的示例中,每8px行在红色和白色之间交替。
基线网格
提示:将所有行高设置为基本单位(8x或4px)的增量非常重要,这样您的文本才能与基线网格完美对齐。
字体行高
五、响应式设计
1. 什么是响应式?
设计师需要通过设计让内容在不同的平台上体验最大化,确保让用户在任何一个屏幕上看到内容的时候,会觉得这些内容就是为这个平台而设计的,而不是单纯的缩放而来。这种无缝的体验,才是跨屏幕设计的真正难点所在。
想要制定一套针对不同设备和屏幕的设计方案,你需要一整套的策略。用户体验同时包含了性能、交互、效率等多方面内容,也就是说,对于一个线上的响应式页面,我们不仅要关注视觉上看到的,也要关注我们操作、使用时的感受,这些综合因素最终影响着用户使用时的效率与体验。
2. 响应式设计的核心步骤
1)确保核心的用户体验
虽然用户体验是无处不在的,但是对于特定产品,最核心的体验是存在的。产品通常是用来解决用户所面临的特定问题的,它的这一特质让产品变得有意义。关键的内容和关键的功能的组合,通常构成了产品的核心用户体验。
如果你并没有想明白这个问题,不妨问问自己:用户需要完成哪些最常见/最重要的任务?找到问题的答案之后,你的产品就应当从各个方面、各个渠道,完整而全面地支撑这些功能,帮助用户完成这些任务。
举个例子,Uber 的核心用户体验是随时随地地叫车,无论设备的屏幕大小如何,你进行的设计全部都应该围绕着这个需求和功能来进行。叫车是Uber的核心功能,即使使用Apple Watch这种极小的屏幕尺寸都应该顺利地完成这个任务。
2)敲定你的产品所覆盖的设备类型
现在的移动端设备屏幕尺寸各不相同,单独为某一个设备设计内容无疑是不现实的。根据你的产品覆盖人群、受众分类、使用场景,综合考虑你的内容会优先呈现在哪些设备和平台上,然后有意识地筛选出常见的设备类型:手机,平板,桌面端,智能电视,智能手表……
不同的设备组合通常是基于不同的场景、需求和服务来构成的,用户会针对不同的屏幕进行不同模式的交互,甚至处理的内容也会有差异。
比如说,在手机上,用户更加倾向于使用轻量级的任务,并且进行一定量的沟通和交流。在平板上,用户行为更多集中在内容消费上,并且目前平板的使用量被认为在逐步降低。桌面端依然是用户完成较为专业、复杂任务的首选平台,足以应付复杂多样的内容。了解各种设备类型和使用场景是用来构建用户体验的关键。
3)针对不同内容来匹配用户体验
并非所有的内容都符合不同设备的使用场景,比如智能手表就不适合展示大量的文本内容。 你的产品所覆盖的设备组当中,每种设备的使用场景不同,应该匹配的用户体验也不一样。移动端用户和桌面端用户的需求就是不同的,场景差异也很大。
以Evernote 为例,它可以在多种不同类型的设备之间同步和切换,其桌面端版本就针对用户的内容需求进行了优化:Evernote 的桌面端应用程序针对阅读性的内容和多媒体进行了优化,而移动端的Evernote 则强化了拍摄记录、图片和音频记录的功能:其次,不同的设备屏幕具备不同的输入方式,设计师如果忽略输入方式上的独特性,也常常会出现许多问题,这里就不扩展开来了。
4)优先为最小的屏幕做设计
一直以来,设计师都习惯从最大的屏幕着手设计,最后考虑最小的屏幕上的显示效果,这意味着绝大多数的设计都是从桌面端开始设计的,通常桌面端的内容和功能更全面。当桌面端的整体设计完成之后,再推进到其他设备端的设计。
然而,在进行桌面端设计的时候,我们常常会遭遇“厨房水槽”困境:由于产品通常会牵涉到多个利益相关方,许多多余的功能会被加入进来。
而实践经验表明,移动端优先的设计往往能够更好的专注于核心功能,更适合作为产品设计的起点。当你优先设计最小屏幕所需要的界面的时候,这种局面会强制你从最关键最重要的地方开始设计。这也是之前设计圈和产品开发领域一直所强调的“移动端优先”的策略的由来。
在此之后,再进行平板、桌面和电视端的设计,就是一个自然的做加法的过程了。在绝大多数的案例当中,最小屏幕通常是手机屏幕。
5)测试你的设计
产品的测试环境并不一定都得是在现实世界中寻找,但是在尽可能让真实的用户来做可用性测试,并且在产品发布之前解决所有的用户体验上的问题。
3. 为何要利用栅格系统来进行响应式设计?
响应式可以响应的前提有两点: 页面布局具有规律性;元素宽高可用百分比代替固定数值 ,而这两点正是栅格系统本身就具有的典型特点,所以利用栅格系统进行响应式的设计是顺理成章的,也比较高效快捷,所以响应式与栅格化天生一对好搭档。
六、如何建立栅格系统
第1步:确定列的数量
第一阶段先不要限制自己的列数。首先,创建一个低保真或高保真的原型。设计一些基本元素和用户流程。在此之后,就开始设计最优的列数和大小。 如果在项目开始设计之后不得不改变我们的栅格系统,不要有负担,我们需要有一些试错的空间。
我们在设计页面时,用到的最多的布局方式就是等分布局,即页面内容区域被 N 等分,每一份的宽度则根据屏幕宽度自适应调整。那么就从这个角度出发,思考一下页面的网格应该设置为多少列,才能最大程度的满足各种等分布局的需要。与web类似,移动端最方便的网格之一是12列网格。这个网格将允许我们在一行中同时放置偶数和奇数个元素。
对于移动端来说,12列网格的缺点是一个列的宽度太小,你可能很少创建一个列宽度的元素。如果你选择2、4或8列网格,请记住在一行中放置奇数个元素可能会出现的问题。
Pro-Tip:
界面设计通常包含数百个不同的页面,因此,一个网格可能不适合所有的页面。如果需要,创建额外的栅格系统,但不要忘记设计的一致性。网格系统的一致性:相同的布局边距、列之间相等或成比例的水槽,以及更改列本身的宽度时其他模块也需要保持相同的比例。
第2步:定义水槽和边距
首先,让我们先翻阅目标屏幕的设计 Guideline,以找出通常页面边距(Side Margins)。目前,Android和iOs的最小推荐布局边距为16pt。web端则依照屏幕尺寸不同而不同。这意味着,如果你希望遵循系统指南,则页面边距不应小于16pt。(但可以更大的😉)
在选择12列网格时,列之间的水槽不应该太大, 因为由于列的宽度小和它们之间的大宽度的水槽,列将在视觉上产生分裂的感觉。同时我建议你选择与8pt间距系统成比例的水槽大小。 所以布局的水平和垂直节奏会相互重叠。水槽与页面边距成比例。那么网格更加一致,也将允许我们轻松地在其中放置特殊元素,如轮播(carousel)。
第3步:定义 8pt间距系统
了帮助不同设计能力的设计者们在界面布局上的一致性和韵律感,统一设计到开发的布局语言,减少还原损耗。在大量的实践中,我们提取了一组可以用于 UI 布局空间决策的数组,他们都保持了 8 倍数的原则、具备动态的韵律感。经过验证,可以在一定程度上帮助我们更快更好的实现布局空间上的设计决策。定义网格系统方法很多,如运用8点网格系统、斐波那契数列、某最小原子单位的增量、从底层系统参数化定义间距等,我们以最小原子单位的增量为例去定义网格系统。最小单元格的数值选择需要从两方面考虑:
- 一方面是该数值是否能被大多数手机屏幕的宽度整除,即广泛的适用性;
- 另一方面是在具体使用时是否具有一定的灵活性。
在适用性方面,4、6、8、10这四个数值都是基本可以满足的,在灵活性方面,4px表现最佳,但是页面就会被分割的非常细碎,在设计时比较难于把控。因此我们需要根据 APP 的实际情况选择合适的数值,4px或6px单元格比较适合页面内容信息较多,布局排版比较复杂的产品。 而8px单元格对一般的设计场景都可以很好的满足,比较适合大多数的 项目,因此是比较推荐使用的。
那么假设我们以8为基准的去延展系统间距,得到如下间距系统:
1、2、8、16、24、32、40、48、56、64、72、80、88、96、192等,这里都是8的倍数或能被 8 整除
但是目前间距数量太多,过于细碎也会导致画间距比较乱,所以我们继续优化梳理(以6为基准,前面个数是后面个数的2倍递增),得到以下间距系统:
1、2、8、16、24、32、48、64、80、96
第4步:sketch布局设置
利用 sketch 的布局设置功能,即可快速搭建出网格系统的参考布局,在平时做设计的过程中,可以经常使用 Ctrl+L 快捷键切换布局的显示,提高设计效率。
我们来解释一下这些设置分别是什么:
- Total Width: 就是内容区域(Container)的值
- Offset: 表示栅格的偏移量,我们只要设定完成以后按Center按钮即可,会自动居中;
- Number of Columns: 就是栅格数
- Gutter on outside: 是非常重要的设置,勾选以后才能跟前端的栅格算法匹配。
- Gutter Width: 就是栅格之间的间距
- Columns Width: 就是栅格的宽度
七、如何做到响应式?
在传统的栅格化系统设计中,列的宽度和水槽的宽度是保持不变的,只是列的「数量」发生变化。为什么要这么处理呢?
这是为了让设计更简单:
如果一组三张卡片分别放在桌面的四列上,那么在平板电脑上,会显示两张卡片,并把第三张卡片进行折行显示在第二行上。不需要做任何的调整,因为已经知道它位于第四列上了。
在手机上,答案也很简单,只需要一张卡片,其他的就会自动堆到下面的行中。
但是目前我有更多的响应策略,例如当视窗(Viewport)发生变化时,内容区域的元素如何去响应,具体到我们当前的栅格系统,就是Columns、Gutters、Margins以及由Columns跟Gutter组成的盒子(BOX)四者的值(主要是宽度)如何变化,以及在这种变化之下我们页面的布局如何调整。
1. 固定栅格或是断点系统(Fixed boxes or breakpoint system)
固定网格,列宽和水槽宽不会改变,只是改变列的数目,当窗口缩放时,排版布局不会发生任何改变,只有当达到一个临界值(开发那边设置好的固定的值),界面才会发生改变。在此之前界面排版都是不变的,就像一部分被切掉了。
如果开发那边写了一个固定栅格,当你从桌面缩小到平板电脑,就像是在桌面的浏览器宽度时,你不会看到任何变化,设计就像是被剪掉了一样。但当达到平板屏幕尺寸临界点时,设计布局马上就会改变,平板电脑上的显示效果就会好起来。如果继续减小这个值,同样的事情也会发生,在到达另一个临界值之前,设计看起来都是不变的。
下面是常见的断点系统(Breakpoint System):
如图,响应式是以视窗的最小宽度作为基本依据来制定每种宽度下Columns、Gutters、与Margins的响应策略,也就是说Viewport Min-width是做出响应的触发条件,视窗每达到一个最小宽度,就会触发该宽度下预设的页面布局方式,而每种布局都是在该宽度下的最佳布局,也是因此,响应式才会在各种复杂分辨率条件下都能给用户比较好的体验。
每个视窗宽度的最小值是触发响应的关键值,因此我们给这些用于触发的关键值起了个名字叫“Breakpoint”,每个Breakpoint触发一种响应策略。
2. 流动栅格(Fluid Grid)
流动栅格系统是编辑内容,仪表板,图像,视频,数据可视化等理想的响应策略。当窗口缩小时,内容将动态的发生变化,文本会进行换行,元素也会变窄。然而,这些元素在内容宽度缩小到下一个临界值之前,布局是不会变化的。在各种情况下,对用户来说,扩展内容的大小比扩展可见内容的数量更有用。
所以我想说的是,断点BreakPoint只是一个更改布局的参考点。这就是为什么列宽和水槽的数量不会改变的原因,因为我们想让设计师在考虑布局时能够更容易地创建一致性。内容宽度会随着窗口的缩放而发生改变,例如图片会缩小,文本会换行。水槽的宽度不一定是固定的,可以随着页面宽度变化。
在每个断点处,列计数是固定的,列宽度是最小网格8PT的倍数。行高是列大小的倍数,遵循推荐的纵横比。边距和填充是小单位的固定倍数。在断点之间,实际列宽是网格区域的百分比,而不是一个小的单位倍数。内容尺度流畅。
首先从所以屏幕大小中选择一个基本尺寸,然后按照推荐的纵横比以基本大小的倍数构建每个响应式尺寸。当每个块使用相同基础大小的倍数时,就会出现网格。遵循此方法可确保栅格系统一致性,甚至跨产品的一致性。
3. 混合栅格(Hybrid Boxes)
在实际项目中,使用流动网格和固定网格的组合也是常见的做法。网站通常是流动网格,因为它要去适应各种不同终端的大小。后台系统设计、工具型的界面设计就比较经常使用网格和流动网格组合的形式。
例如的后台管理系统(dashboard)侧边栏是固定网格,右侧内容是流动网格。混合栅格在每个维度上有不同的缩放规则,所以它们不使用统一的缩放比。当用户需要调整浏览器的大小以使内容在一个维度上伸缩而在另一个维度上不伸缩时,便使用混合网格。
八、面板对栅格系统的影响
How Panel behavior effect Grid system
1. 灵活面板(Flexible panels)
灵活的面板允许折叠和扩展状态。面板的展开状态为固定宽度,用户无法调节。当用户将鼠标悬停在折叠的面板上时,面板就会展开。当灵活的面板扩展时,它们要么压缩内容和网格,要么将内容推到浏览器边缘之外。
2. 固定面板(Fixed panels)
固定面板保持静态宽度,不能折叠,也存在于响应网格之外。
3. 悬浮面板(Floating panels)
此面板样式漂浮在主要内容区域之上,不影响响应网格。浮动面板将任何UI元素隐藏在其下方,用户必须将其移除。内联菜单、下拉菜单和工具提示也是浮动的。
九、总结 资源 扩展阅读
写这篇文章的目的是想提供一些关于如何在响应式设计中使用栅格系统,我知道对于我自己来说,我花了很多时间理解网格是如何工作的。我在YouYube上看了很多视频,也阅读了大量的文章,但每个人都在关注它为什么重要,却不去注重到底怎么在自己的项目中使用这些原则。
你要做的最好的事情就是从现在开始注意那些优秀设计是如何对齐元素的,你将会开始阅读这些设计系统。为了帮助理解,这里有一些设计系统概述了它们的网格使用:
Google’s Material Design System
https://material.io/design/layout/responsive-layout-grid.html#columns-gutters-margins
Intuit’s Design System
https://designsystem.quickbooks.com/foundations/responsive-column-grid/
IBM’s Carbon Design System
https://www.carbondesignsystem.com/guidelines/layout#2x-grid-fundamentals
在完全理解了网格的工作原理之后,你将成为了一名更好的设计师,因为你知道了你的设计将如何在临界值之间进行转换。你也可以落地你的设计,使它们能够达到像素级完美。这样的规范带来了更一致,更简洁的设计,当用户从一个界面到另一个界面流转时,这真的提升了产品的档次。我建议在你的设计中去应用这些网格,并和开发同学一起,以实践的方式将它们落地,这将会是一个非常不错的进步。
作者:Ivan 郑子越;公众号: CoDesign设计社区
原文链接:https://mp.weixin.qq.com/s/dK0Nz4ixi3bSIW9XdEcHkw
本文由 @Ivan 郑子越 授权发布于人人都是产品经理。未经许可,禁止转载。
题图来自 Unsplash,基于CC0协议。