A presentation at Codemotion Amsterdam in in Amsterdam, Netherlands by Danny Banks
Building Consistent Cross-Platform Interfaces
https://bit.ly/codemotion-2019-cross-platform https://bit.ly/codemotion-2019-cross-platform-pdf @dbanksdesign
Consistent experiences help users build trust with the organization. Each interaction is part of the overall user experience with a company. If the user experience isn’t consistent across channels, users will question the organization’s credibility. - Jakob Nielsen Cross Channel Consistency
Consistent ≠ Exact
Be a good platform citizen
Design Tokens
Design tokens are the visual design atoms of the design system — speci cally, they are named entities that store visual design attributes - Lightning Design System
Design tokens are variables that codify every aspect of a design in a platform-independent format that is readable by both humans and machines. - Elliot Dickison, Amazon
Cr Tp Ic Color Typography Iconography Mn Dm Ev Motion Dimension Elevation
primary brand color scss $color-brand-primary-base: #0fb7b0; iOS/Objective-C UIColor *brandPrimaryBase = [UIColor colorWithRed:0.06f green:0.72f blue:0.69f alpha:1.00f]; Android Resource XML <color name=”color_brand_primary_base”>#ff0fb7b0</color>
Kingdom Phylum Class Order Family
time color size border background font button alert overlay danger success warning
color.core.teal.100 #0fb7b0 color.brand.primary.base color.core.teal.100 color.background.button color.brand.primary.base color.font.link color.brand.primary.base
color.core.orange.100 #fa953c color.brand.primary.base color.core.orange.100 color.background.button color.brand.primary.base color.font.link color.brand.primary.base
color.background.button color.brand.primary.base color.core.teal.100 #0fb7b0 color.core.purple.100 #6a5096 color.brand.primary.base color.core.teal.100 color.brand.secondary.base color.core.purple.100 color.font.link color.brand.secondary.base
Design Options Design Decisions
Core color palette Text color palette Specific uses grey 140 #191926 base grey-120 input grey 120 #252535 secondary grey-80 heading-1 text-secondary grey 100 #2e2e46 tertiary grey-60 nav-item text-secondary grey 80 #48485e grey 60 #81818e grey 40 #c2c2cc grey 20 #dadae6 grey 10 #f2f2f7 disabled-input text-base text-tertiary
Consistent Resilient Flexible
JSON { “color”: { “core”: { “grey”: { “20”: “#f3f1f1”, “40”: “#888888”, “60”: “#4d4d4d”, “80”: “#323232”, “100”: “#262626” } } } } YAML color: core: grey: 20: “#f3f1f1” 40: “#888888” 60: “#4d4d4d” 80: “#323232” 100: “#262626”
{ … } Transform Format CSS { … } Transform Format Objective C
Custom Build Script Eight Shapes YAML + custom build script FirefoxUX Design Tokens Nested JSON objects + custom build script
Theo JSON, JSON5, or YAML based token les CLI as well as node module based Transforms and formats with customization Has a great community
Theo # aliases.yml aliases: primary_color: value: “#0070d2” # buttons.yml props: button_background: value: “{!primary_color}” imports: - ./aliases.yml global: type: color category: buttons const theo = require(‘theo’); theo .convert({ transform: { type: ‘web’, file: ‘buttons.yml’ }, format: { type: ‘scss’ } }) .then(scss => { // $button-background: rgb(0, 112, 210); });
Style Dictionary amzn.github.io/style-dictionary
con g.json 1. { 2. “source”: [“properties/**/*.json”], 3. “platforms”: { 4. “web”: { 5. “transforms”: [“attribute/cti”,”name/cti/kebab”,”color/hex”], 6. “buildPath”: “dist/web/”, 7. “files”: [{ 8. “destination”: “_variables.scss”, 9. “format”: “scss/variables” 10. }] 11. }, 12. “android”: { 13. “transformGroup”: “android”, 14. “buildPath”: “dist/android/”, 15. “files”: [{ 16. “destination”: “style_dictionary_colors.xml”, 17. “format”: “android/colors” 18. }], 19. “actions”: [“copyImages”] 20. } 21. } 22. }
Design Token File 1. { 2. “size”: { 3. “font”: { 4. “small” : { “value”: 0.75 }, 5. “medium”: { “value”: 1 }, 6. “large” : { “value”: 1.25 }, 7. “xl” : { “value”: 1.75 }, 8. “xxl” : { “value”: 2.5 }, 9. “base” : { 10. “value”: “{size.font.medium.value}”, 11. “comment”: “All about that base” 12. }, 13. “heading”: { 14. “1”: { “value”: “{size.font.xxl.value}” }, 15. “2”: { “value”: “{size.font.xl.value}” } 16. } 17. } 18. } 19. }
Building the Style Dictionary 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. const StyleDictionary = require(‘style-dictionary’); // If you want to add custom transforms or formats StyleDictionary.registerTransform({ // … }); // Same as running style-dictionary build —config config.json StyleDictionary.extend(‘config.json’).buildAllPlatforms() // You can also pass in an object rather than a JSON file StyleDictionary.extend({ // … }).buildAllPlatforms()
Design Token File 1. { 2. “size”: { 3. “font”: { 4. “small” : { “value”: 0.75 }, 5. “medium”: { “value”: 1 }, 6. “large” : { “value”: 1.25 }, 7. “xl” : { “value”: 1.75 }, 8. “xxl” : { “value”: 2.5 }, 9. “base” : { 10. “value”: “{size.font.medium.value}”, 11. “comment”: “All about that base” 12. }, 13. “heading”: { 14. “1”: { “value”: “{size.font.xxl.value}” }, 15. “2”: { “value”: “{size.font.xl.value}” } 16. } 17. } 18. } 19. }
Output Web: SCSS 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. // variables.scss $size-font-small: 0.75rem; $size-font-base: 1rem; $size-font-large: 1.25rem; $size-font-xl: 1.75rem; $size-font-xxl: 2.5rem; $size-font-base: 1rem // All about that base $size-font-heading-1: 2.5rem; $size-font-heading-2: 1.75rem;
Output iOS: Static Constants 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. // StyleDictionarySize.m float float float float float float float float const const const const const const const const SizeFontSmall = 12.0f; SizeFontMedium = 16.0f; SizeFontLarge = 20.0f; SizeFontXl = 28.0f; SizeFontXxl = 40.0f; SizeFontBase = 16.0f; // All about that base SizeFontHeading1 = 40.0f; SizeFontHeading2 = 28.0f;
Output Android: Resource XML 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
<!— dimens.xml —> <dimen <dimen <dimen <dimen <dimen <dimen <dimen <dimenname=”size_font_small”>12.00sp</dimen> name=”size_font_base”>16.00sp</dimen> name=”size_font_large”>20.00sp</dimen> name=”size_font_xl”>28.00sp</dimen> name=”size_font_xxl”>40.00sp</dimen> name=”size_font_base”>16.00sp</dimen> <!— All about that base —> name=”size_font_heading_1”>40.00sp</dimen> name=”size_font_heading_2”>28.00sp</dimen>
{ … } Transform Format CSS { … } Transform Format Objective C
$${prop.name}: ${prop.value}
)) ) }); StyleDictionary.registerFormat({ name: ‘scss/variables’, formatter: Handlebars.compile( fs.readFileSync(‘./myTemplate.hbs’) ) });Demo Time! light base dark light base dark #40c7c2 #8f6ccc #0fb7b0 #06a39c #6a5096 #553c80 Button Button Heading 1 Heading 2 Heading 3
Resources Awesome Design Tokens Design Systems Handbook How to manage your Design Tokens with Style Dictionary design.systems #tool-style-dictionary #tool-theo #topic-design-tokens
Thank You!
Style Dictionary My Info amzn.github.io/style-dictionary dbanksdesign.com github.com/amzn/style-dictionary @dbanksdesign style-dictionary@amazon.com @dbanksdesign Slides https://bit.ly/codemotion-2019-cross-platform https://bit.ly/codemotion-2019-cross-platform-pdf
When building interfaces, it can be challenging to keep styles consistent across multiple platforms, devices, teams, and codebases. Design tokens are a single source of truth that provide a way to share design and style information anywhere. In this talk you will learn about how to use design tokens to synchronize your styles across any platform, device, framework, or tool.
The following resources were mentioned during the presentation or are useful additional information.