Microsoft-ui-xaml: Cascading styles in xaml

Created on 31 Aug 2020  路  11Comments  路  Source: microsoft/microsoft-ui-xaml

I hope introducing cascading styles in xaml like one on css

area-DesignDiscussion area-Styling team-Framework

Most helpful comment

I'm hoping this will be considered with all the styling rework ongoing within Microsoft. I believe they also plan to generate all styles for web/uwp, etc. from common design elements and definitions (I can't find the repo a the moment). Something like this would then be quite useful to combine css/xaml ideas.

As I understand it, there will be a Figma plugin, which will allow you to set both global and specific properties on components you use to design your apps. It will then allow you to export:

  • XAML Resource Dictionaries for WinUI (possibly also React Native for Windows;
  • CSS/TypeScript for Fast and FluentUI React web;
  • iOS and macOS resources for FluentUI components and React Native for macOS;
  • Android assets and resources for FluentUI components;

So designers can design once, export the code and assets, and the developers get to import those into their app projects.

Not sure how this will work for Xbox app designs, I hope those will come along with WinUI 3.X for Xbox, featuring open source control templates and app layouts.


Fluent Design overview

Design Tokens is the approach being adopted, which essentially separates the colour values used in a design system, from the actual uses of those values.

So you would define a group of _Global_ colours, fonts, thicknesses, strokes, gradients, margins, etc

Those values would be grouped typically by State. So Background.Rest or Background.Pressed.

Then you create an _Alias_ which would be something like Control.Border, Flyout.Background or Text.Fill - which would consume those grouped values.

All of these create a Style Dictionary for the design language.

From what I can see from Microsoft's work so far FluentUI Token Pipeline

_Fluent Design would have values in JSON format_

{   
"Global": {
    "Color": {
        "Grey": {
            "0": { "value": "hsl(0, 0%, 0%)" },

            "100": { "value": "hsl(0, 0%, 100%)" }
        }
    },
    "Stroke": {
        "Width": {
            "0": { "value": 0 },
            "100": { "value": 1 }
        }
    },
    "Corner": {
        "Radius": {
            "None": { "value": 0 },
            "Small": { "value": 2 },
            "Medium": { "value": 4 }
        }
    },      
    "Font": {
        "Family": {
            "Default": { "value": "\"Segoe UI\", Roboto, \"SF Pro Text\", \"Helvetica Neue\", Helvetica, Arial, sans-serif" }
        },
        "Weight": {
            "Regular": { "value": 400 },
            "Semibold": { "value": 600 }
        },
        "Size": {
            "100": { "value": 10 },
            "200": { "value": 12 },
            "300": { "value": 14 },
        },
        "LineHeight": {
            "100": { "value": 14 },
            "200": { "value": 16 },
        }
    }
},

_A Group of values_

"BrandBackground": {
    "Fill": {
        "Color": {
            "Rest": { "aliasOf": "Global.Color.Brand.42" },
            "Hover": { "aliasOf": "Global.Color.Brand.40" },
            "Pressed": { "aliasOf": "Global.Color.Brand.24" },
            "Disabled": { "aliasOf": "Global.Color.Grey.94" }
        }
    }
},

_And those Values applied to a "style"_

"ButtonPrimary": {
    "Content": {
        "Font": { "aliasOf": "Set.Control.Font" },
        "Fill": { "Color": { "aliasOf": "Set.NeutralForegroundInvertedAccessible.Fill.Color", "Selected": { "aliasOf": "Set.NeutralForegroundInvertedAccessibleSelected.Fill.Color" } } }
    },
    "Icon": {
        "Fill": { "Color": { "aliasOf": "Set.NeutralForegroundInvertedAccessible.Fill.Color", "Selected": { "aliasOf": "Set.NeutralForegroundInvertedAccessibleSelected.Fill.Color" } } }
    },
    "Base": {
        "Fill": { "Color": { "aliasOf": "Set.BrandBackground.Fill.Color", "Selected": { "aliasOf": "Set.BrandBackgroundSelected.Fill.Color" } } },
        "Stroke": {
            "Color": { "aliasOf": "Set.Borderless.Stroke.Color", "Selected": { "aliasOf": "Set.Borderless.Stroke.Color" } },
            "Width": { "aliasOf": "Set.Borderless.Stroke.Width", "Selected": { "aliasOf": "Set.Borderless.Stroke.Width" } }
        },
        "Corner": { "aliasOf": "Set.Control.Corner" },
        "Layout": { "Padding": { "value": [7, 15, 7, 15] } },
        "Shadow": {}
    }
},

Images of the Build 2020 demo for this workflow...

figma plugin screen 1
figma plugin screen 2
_Figma Plugin_

example output Swift
_Swift UI Output_

example output Xaml
_Xaml ResourceDictionary Output_

_( Names of values, and the values themselves are all WIP, But the start of it is coming to WinUI )_
microsoft-ui-xamldevCommonStylesCommon_themeresources.xaml - Branch: Feature/token-experiment

All 11 comments

https://github.com/microsoft/microsoft-ui-xaml might be a better home for this request

WPF is also a bit more functional in this area.

@kikisaints fyi

I'm certainly down with taking the best learnings from CSS and applying to XAML in a thoughtful way. But it's certainly an area of strong emotions. See this issue where I just used the name of CSS in the title and the response was very divided.

This is obviously a topic that requires a lot of design work. @kikisaints I know we've had lots of discussion about taking inspiration from CSS in a couple spots. Are there some proposals we can link to?

As a first step it could be useful to have ResourceDictionaries and a new CSS format interchangable.

I'm hoping this will be considered with all the styling rework ongoing within Microsoft. I believe they also plan to generate all styles for web/uwp, etc. from common design elements and definitions (I can't find the repo a the moment). Something like this would then be quite useful to combine css/xaml ideas.

I'm hoping this will be considered with all the styling rework ongoing within Microsoft. I believe they also plan to generate all styles for web/uwp, etc. from common design elements and definitions (I can't find the repo a the moment). Something like this would then be quite useful to combine css/xaml ideas.

As I understand it, there will be a Figma plugin, which will allow you to set both global and specific properties on components you use to design your apps. It will then allow you to export:

  • XAML Resource Dictionaries for WinUI (possibly also React Native for Windows;
  • CSS/TypeScript for Fast and FluentUI React web;
  • iOS and macOS resources for FluentUI components and React Native for macOS;
  • Android assets and resources for FluentUI components;

So designers can design once, export the code and assets, and the developers get to import those into their app projects.

Not sure how this will work for Xbox app designs, I hope those will come along with WinUI 3.X for Xbox, featuring open source control templates and app layouts.


Fluent Design overview

Design Tokens is the approach being adopted, which essentially separates the colour values used in a design system, from the actual uses of those values.

So you would define a group of _Global_ colours, fonts, thicknesses, strokes, gradients, margins, etc

Those values would be grouped typically by State. So Background.Rest or Background.Pressed.

Then you create an _Alias_ which would be something like Control.Border, Flyout.Background or Text.Fill - which would consume those grouped values.

All of these create a Style Dictionary for the design language.

From what I can see from Microsoft's work so far FluentUI Token Pipeline

_Fluent Design would have values in JSON format_

{   
"Global": {
    "Color": {
        "Grey": {
            "0": { "value": "hsl(0, 0%, 0%)" },

            "100": { "value": "hsl(0, 0%, 100%)" }
        }
    },
    "Stroke": {
        "Width": {
            "0": { "value": 0 },
            "100": { "value": 1 }
        }
    },
    "Corner": {
        "Radius": {
            "None": { "value": 0 },
            "Small": { "value": 2 },
            "Medium": { "value": 4 }
        }
    },      
    "Font": {
        "Family": {
            "Default": { "value": "\"Segoe UI\", Roboto, \"SF Pro Text\", \"Helvetica Neue\", Helvetica, Arial, sans-serif" }
        },
        "Weight": {
            "Regular": { "value": 400 },
            "Semibold": { "value": 600 }
        },
        "Size": {
            "100": { "value": 10 },
            "200": { "value": 12 },
            "300": { "value": 14 },
        },
        "LineHeight": {
            "100": { "value": 14 },
            "200": { "value": 16 },
        }
    }
},

_A Group of values_

"BrandBackground": {
    "Fill": {
        "Color": {
            "Rest": { "aliasOf": "Global.Color.Brand.42" },
            "Hover": { "aliasOf": "Global.Color.Brand.40" },
            "Pressed": { "aliasOf": "Global.Color.Brand.24" },
            "Disabled": { "aliasOf": "Global.Color.Grey.94" }
        }
    }
},

_And those Values applied to a "style"_

"ButtonPrimary": {
    "Content": {
        "Font": { "aliasOf": "Set.Control.Font" },
        "Fill": { "Color": { "aliasOf": "Set.NeutralForegroundInvertedAccessible.Fill.Color", "Selected": { "aliasOf": "Set.NeutralForegroundInvertedAccessibleSelected.Fill.Color" } } }
    },
    "Icon": {
        "Fill": { "Color": { "aliasOf": "Set.NeutralForegroundInvertedAccessible.Fill.Color", "Selected": { "aliasOf": "Set.NeutralForegroundInvertedAccessibleSelected.Fill.Color" } } }
    },
    "Base": {
        "Fill": { "Color": { "aliasOf": "Set.BrandBackground.Fill.Color", "Selected": { "aliasOf": "Set.BrandBackgroundSelected.Fill.Color" } } },
        "Stroke": {
            "Color": { "aliasOf": "Set.Borderless.Stroke.Color", "Selected": { "aliasOf": "Set.Borderless.Stroke.Color" } },
            "Width": { "aliasOf": "Set.Borderless.Stroke.Width", "Selected": { "aliasOf": "Set.Borderless.Stroke.Width" } }
        },
        "Corner": { "aliasOf": "Set.Control.Corner" },
        "Layout": { "Padding": { "value": [7, 15, 7, 15] } },
        "Shadow": {}
    }
},

Images of the Build 2020 demo for this workflow...

figma plugin screen 1
figma plugin screen 2
_Figma Plugin_

example output Swift
_Swift UI Output_

example output Xaml
_Xaml ResourceDictionary Output_

_( Names of values, and the values themselves are all WIP, But the start of it is coming to WinUI )_
microsoft-ui-xamldevCommonStylesCommon_themeresources.xaml - Branch: Feature/token-experiment

Really awesome summary @mdtauk, Thanks! Thats exactly the info I was looking for.

I'm excited about this all coming together. I hope they dont hit any technical roadblocks. High-level meta concepts are really a fundamental component of cross platform development in the future.

I also envision a future where control logic can be defined, for example, mathematically like Modelica. Then even source code could be generated in whatever language needed and we can stop re-writing the same controls every time a new language or framework comes around :)

Really awesome summary @mdtauk, Thanks! Thats exactly the info I was looking for.

Fast, FluentUI, and WinUI all appear to be doing work to prepare for using the Figma Plugin and Design Tokens.

Xbox is still unknown as none of their work is in the open, and all UWP resources for Xbox date back from 2016.

I'm excited about this all coming together. I hope they dont hit any technical roadblocks. High-level meta concepts are really a fundamental component of cross platform development in the future.

I think this is why we are seeing new Control designs being proposed now, so they can share values with these Design Tokens alongside FluentUI Web (which may get a design refresh to match, or if not, will match better with the updated WinUI designs)

From what I see in the tokens branch XAML - the new naming conventions are logical and clear, however something like ControlAAFillColorDefault - I can't figure out what the AA stands for, but @chigy informed me its not a final name, so hopefully once the Design Token work is done - hopefully that will change.

image

I have been collating these values into a figma page, to visualise them better for myself


It also seems the plugin will possibly replace the Fluent Theme Editor, and allow exporting a custom theme to use in your app, whilst by default, will use the default Design Tokens?

image

The Button is one of the XAML controls updated to use the new Design Tokens in the feature branch, so I am illustrating how they reference the Lightweight styles, and they reference the Global Design Tokens

Illustrating the xaml style referencing

Using the plugin, I think you will be able to override the Global Tokens, probably in App.xaml - those will propagate down to controls and views in the app.

Then the next level down, you can override the Lightweight Styles to allow only certain control types to deviate from the default Fluent Design / WinUI provided values. App level or page level or view/panel level.

Then there are the properties on the Button control, which you would normally be able to override, but it is not encouraged. If you wish to alter the PointerOver, Pressed, or Disabled states, you would need to re-template the control.

Was this page helpful?
0 / 5 - 0 ratings