通过这篇文章,我将向大家介绍下关于设计的一些基本知识,让广大开发者在平时的开发中,可以更好的和设计、产品合作(撕逼)。
1.Color System
1.1 Material Color Theme
颜色是最有特色的主题属性,可以在主题上反映一个品牌和它的风格。我们可以将12种Material theme颜色分为三类。
- Primary and Secondary colors:这些颜色和它们的变体色被用来代表品牌。虽然secondary color(又称accent color)是可选的,但它有助于提高品牌的差异化。Variant颜色是Primary和Secondary color的深浅色调。我在挑选这些颜色时利用了公司的Logo。
- Surface、background、error colors:Surface color适用于卡片、Menu和Sheet的表面色。background color是应用在屏幕背景上,在UI组件的后面的颜色。error color是应用在组件上以突出错误的颜色。通常情况下,这些颜色与品牌没有关联。因此,如果我们想的话,我们可以将相同的Surface、background、error color应用于所有公司的特定主题上。
- onXXX colors:这些是UI组件上的文本和Icon颜色。
https://material.io/design/color/the-color-system.html#tools-for-picking-colors这个工具是可以帮助生成primary和secondary的调色板。
在这些颜色被声明后,它们会根据默认的material规范应用于UI组件。这意味着我们不需要为buttons, cards, bottom sheets, app bars等明确指定颜色。例如,cards的颜色将是surface颜色,floating action button将是secondary颜色,而Button将是primary颜色。然而,Material指南允许我们定制UI组件的颜色,以增加应用程序中的品牌辨识度,并使设计师同事们感到高兴。例如,我们可以选择卡片的颜色作为primary color,以更加强调品牌。
1.2 Semantic Colors
当我们构建应用程序时,有时我们可能需要比primary和secondary color更多的颜色。一个例子是用图表实现数据的可视化。在演示应用程序中,我们有一个饼状图,其中我们需要在每个部分使用不同的颜色。另一个例子是用颜色作为不同状态的视觉指标,如警报级别、金额变化或性能变化(减少/增加)。
在许多情况下,将颜色与场景联系起来是用交通灯的颜色(红、黄、绿)来参考的。
- 危险、表现下降、保持在目标以下是与红色相关联的。
- 警告,和接近目标是与黄色相关的。
- 安全、积极变化、达到目标与绿色相关。
有时我们需要比交通灯颜色更多的颜色。在不同的背景下挑选颜色通常是开发者失败的地方,或者说是感到压力很大的地方。在这种情况下,我们可以从色轮上的色彩调和中得到一点帮助。色轮是一个表示颜色之间关系的圆。
它的目标是找到能很好搭配的颜色。根据色轮上的位置,颜色有不同的色彩协调性。例如,假设我需要为4个类别分配颜色。如果这些类别在语义上是独立的,我就会选择方形调和的颜色;如果这些类别可以配对,我就会选择四方形调和的颜色。
在另一个例子中,我们假设我需要为6个类别挑选6种颜色。如果这些类别在语义上可以分为两组,我就会首先为第一组挑选3种具有类似调和性的颜色。然后,我将为第二组找到每种颜色的互补色。
色彩理论是一个巨大的话题,而且它并不简单。为背景找到合适的颜色需要进行实验。然而,在为一个主题挑选语义色彩时,了解色彩理论的基础知识仍然很有用。
1.3 primarySwatch and primaryColor
在Material Design中,有两个概念特别容易混淆,借助Flutter中的ThemeData,正好在这里讲解下它们的异同。
在设计文档中,primarySwatch是指从一系列类似的颜色中选择的颜色样本。例如下面的色板,这一系列的颜色就是primarySwatch。
所以说,primarySwatch并不是一个颜色,它是MaterialColor,这意味着它是一个Material Design程序将使用的不同颜色的色板。
而primaryColor只是其中一种色调。确切地说,primaryColor通常等于primarySwatch[500]。
通常情况下,定义一个primarySwatch,而不是只定义primaryColor会更好。因为一些Material组件可能会在阴影、边界等方面使用不同的primaryColor色调。
Material设计指南中给我们提供了这样一个工具,来方便开发者设置这些颜色。
https://material.io/resources/color
2. Brightness
2.1 Munsell Color System
在讨论亮度之前,让我们先谈谈Munsell色彩系统(HCV色彩体系)。下面是一张图片,它以3个维度表示颜色:色相Hue、明度Value和色度Chroma。当在中心周围移动时,色相会发生变化。我们可以很容易地用色相来描述颜色,如橙色、蓝色、红色、绿色、粉色、紫色等。明度Value是关于颜色的明度或暗度。它从下往上增加。在中心,底部是黑色,顶部是白色。当从中心向外移动时,色度会发生变化。色度是关于颜色的纯度、强度或饱和度。
「2.2 Light vs Dark Brightness」
我们的主题中的亮度属性有两个选项:dark和light。由于屏幕上的大部分颜色都是background和surface的颜色,在深色主题中,与浅色主题相比,background和surface的颜色会有一个较低的值(亮度)。
根据Material指南,在暗色主题中,随着elevation的增加,表面的颜色会变得更浅。例如,在暗色主题中,背景色应该比card和sheet的颜色有更低的值。此外,与浅色主题相比,深色主题中的primary和secondary color应该具有较低的色度(饱和度较低)。
2.3 Color Contrast
色彩对比是关于三维色彩系统中的位置差异。我们需要在我们的用户界面中应用色彩对比,不仅是因为它看起来不错,而且主要是因为色彩的可及性。我们应该确保前景(文本、图标)和背景之间的颜色对比是适当的。
根据WCAG (Web Content Accessibility Guide) 2.0,对比度是对两种颜色之间可感知的「亮度」或亮度差异的一种衡量。白色背景上的白色文字或图标的对比度为1:1。白色背景上的黑色文字有21:1的对比度。
Material设计指南确保在背景和前景(文本或图标)之间应用WCAG建议的最小对比度,即4.5:1。因此,应该相应地选择onXXX颜色(onPrimary, onSecondary, onSurface, onBackground, onError)。
2.4 Material Palette Generator
考虑到三维模型,当我们从浅色主题切换到深色主题时:
- background和surface的颜色应该从上往下移动
- primary和secondary color应该向内的中心移动。
- onXXX的颜色应该从下往上移动。
为深色和浅色主题建立一个颜色系统,这听起来可能太复杂了。多亏了Material Palette Generator工具,这并不复杂。一旦我们决定了primary和secondary color,我们就可以把颜色代码作为输入给生成器。该工具通过一个考虑到色相、色度和数值的算法,生成一个可用的、美观的调色板。它还提供了一个关于从可及点上的颜色的提示。一旦你点击了一个卡片,考虑到对比度,color P字母可以是黑色或白色。
Chris Banes的博文对根据亮度来挑选正确的色调给出了很好的解释。对于主色调,Material设计浅色主题通常使用500色调,对于深色主题建议使用较浅的饱和度色调(200-50范围)。浅色主题的主变色可以浅一些或深一些(500±200),而对于深色主题,建议使用500。
深色和浅色主题的secondary (accent) color色调可以选择与primary color类似的颜色,只是深色主题的次要变体颜色建议在200-50范围内,而不是500。
3. Typography
3.1 Text Styles
Material设计有13种不同的文本样式,用于在屏幕上格式化和绘制文本。6个headlines,2个subtitles,2个body texts,1个caption,1个overline,和1个button。每个UI组件都默认使用其中一种样式。
- Headlines是大型文本,范围从1到6。标题6是最小的标题,用于应用栏和对话框的标题。Headline5用于对话框中的大文本。其余的标题可以用来突出简短和重要的文本和数字。
- Subtitles比Headlines要小。它们用于列表中的内容。例如,Subtitle1用于标题文本,Subtitle2用于副标题文本或用于强调通常属于Subtitle1的列表的文本。
- Body texts用于长文本。Flutter中默认的材料文本样式是BodyText2。BodyText1可用于强调通常为BodyText2的文本。
- Caption和Overline是最小的样式,用于注释,如图像标题,图表图例。
- Button文本样式与动作相关,用于按钮、标签、对话框和卡片。
3.2 Fonts
每种字体都有自己的特点,这是一个强有力的工具,可以给人以关于公司身份的信息,如传统、有趣、干净、年轻、温暖、现代、优雅、成熟等等。通常情况下,公司有自己的品牌字体,但我们不需要在应用程序中使用他们的字体。
为了应用一个字体系统,首先,我从Google Fonts中挑选了三种字体。Rubik, Righteous, 和Source Code Pro。谷歌字体是开源的,可以免费使用,并且直接支持Flutter。其次,我利用字体比例生成工具来确定Material指南中定义的13种文字风格类别。该工具生成的代码适用于Flutter、Web和Android平台。
https://material.io/design/typography/the-type-system.html#type-scale
Material设计不允许手写和脚本文本样式(表现力强的字体)被用作body和caption文本,因为随着字体大小变小,阅读这些字体会变得困难。这些样式应该用于headlines和subtitles,尽管该指南仍然建议在使用它们做subtitles时要谨慎。字体比例生成工具也不允许为body和captions选择有表现力的字体。在演示应用程序中,我仍然在body和captions中使用了富有表现力的Rightheous字体,以达到演示目的,尽管不推荐这样做。
4. Shape
形状被用来表达品牌和强调用户界面的不同部分。在没有策略的情况下,将形状积极地应用到每一个组件上,会分散注意力,减少关注度,并产生歧义。例如,在条形图上应用形状可能会导致对所表示的数值的模糊不清。在演示的应用程序中,我几乎把所有的UI组件都应用了形状,以达到演示的目的,这绝对是不推荐的。
截至目前,Material Design有两种形状样式:圆角和切角。在应用形状时,我们需要考虑4个不同类别的UI组件。
- 小型组件:button, chips, fab, snack bar, tooltip, collapsed state of expanding bottom sheet
- 中型组件:card, dialog, menu
- 大型组件:data table, navigation drawer, model, and standard bottom sheet
- 最后是一些我们不应该应用形状的组件:如顶部和底部的appbar,checkboxes, dividers, radio buttons
我们可以为一个形状的右上角、右下角、左上角、左下角分别赋予不同的值。在Material指南中,有一个很好的表格,说明了圆角或切角的最小/最大值,以及每个部件的形状可以应用到哪些角。例如,一个chip可以有一个最大10px的圆角半径值,但不能有一个切角。一个按钮可以有一个最大20px的圆角半径值,和最大6px的切角值。
我根据以下观察结果,将形状应用于演示应用程序中的UI组件。ATA标志有清晰的圆角。Biohack的标志有一个几何形状的尖锐切口。Codeland的标志更像是长方形,边角处有一个非常小的圆角值。
5. Icons
Material设计图标是极简的,现代的,并在Apache许可版本下,使其可以免费使用和重新混合使用。它们可以以光栅或矢量图像的形式下载。比起光栅图像,我更喜欢矢量图像,因为它们是可伸缩的,而且尺寸更小。
Material图标也可以在Web和Flutter项目中作为图标字体使用。图标字体是用字体中的字形绘制的,但不是字母,而是图标和形状。在Android项目中,我们将SVG文件中的材质设计图标作为XML文件添加到资源文件夹中。然而,在Flutter项目中,我们不需要明确地将它们添加到项目中,因为所有的图标都可以作为字体的字形一次性添加。Flutter通过从字体集中移除未使用的符号来优化Material design图标库,这就减少了应用程序的大小、加载时间和内存使用。
截至目前,材料图标有五种不同的主题:填充、锐利、圆形、轮廓和双色。Flutter支持填充、圆形、勾勒和锐利的风格。考虑到品牌形状,ATA将使用圆形图标,Biohack将使用尖锐图标,Codeland将使用填充图标。
Conclusion
在这篇文章中,我解释了主题属性和相应的Material设计指南。我开发了多年的应用程序,却不知道其中的一些细节。我在公司工作时,设计师同事负责这些细节并为我提供设计。当我开始从事自己的项目时,我不得不自己建立一个设计系统。这篇博文中的细节对我帮助很大。
部分翻译自:
https://ulusoyca.medium.com/switching-between-client-specific-themes-for-b2b-flutter-apps-part-i-design-c9c501700c0e
https://material.io/design/color/the-color-system.html