Ignition Community Live with Ray Sensenbach
Theming in Perspective37 min video / 31 minute read
Theming in Perspective allows users to customize the look and feel of their Perspective projects at a broad level. In this webinar, we’ll take a deep dive into this powerful new feature covering everything from the basics of theming through to developing a custom theme using your company’ s brand colors. This session is for anyone who wants to follow a hands-on example of themes in action.
Ray: Good morning, everybody. This is Ray Sensenbach, we're gonna be leading the session this morning, we're in Ignition Community Live, appreciate you joining us. So today's session is titled Theming in Perspective.” And I'm your host, Ray Sensenbach, I'm a design lead at Inductive Automation. I've been at the company for around four years now, I've been a UX designer for over 10 years. And I currently work with the design group at IA. We are within the software engineering department. So today's topic, Perspective theming. So theming in Perspective is a powerful new feature, which will allow you to customize the look and feel of your Perspective applications at a really broad level. So throughout the webinar, we're gonna take a deep dive into the subject and we're gonna cover everything starting from the basics of theming and our thought process behind the feature, why we did it, into some of the more complex topics like custom themes and design strategies you can use to add in custom fonts and even use color variables throughout your project. And really, our goal today is to give anybody who's interested in the feature a hands-on deep dive with simple examples of all of the components that make up the feature.
Ray: And we hope that you can get inspired and explore the feature in more depth yourself, because it's really powerful and there's quite a lot you can do with it. And I know myself and others on the team are really excited to see what our users, yourselves, go ahead and build out with things like custom themes.
Ray: So to jump right into part one, we're gonna give you a background on the feature itself and a lot of the team's work that went into developing the themes. So Perspective themes were introduced in version 8.0.13. And what they do is they allow users to customize the look and feel of components at a really broad level. So themes provide the default styles of components. And with our default themes, you're able to choose from six right out of the gate. And this includes three light-skinned UI themes, as well as three complimentary dark-skinned UI themes. And as I mentioned, advanced users that are really familiar with CSS and web technologies are able to take the feature even further by offering their own custom themes. Now, why did we add themes? So this is something that we've been really excited about for a long time. And we've been slowly building towards, we've been slowly putting the pieces in place that now allow us to completely round out the feature.
Ray: And just what I mentioned was a pretty massive front-end development undertaking. So as you work on development teams yourselves, you might understand that we needed some good benefits backing up the reasoning behind the feature. And we had those, and those included the ability that themes provide, which is unified and customized visual design across all of the components and applications. They also give us the ability to consistently render our components across different browsers and different sessions. And what they do is they empower you to make really sweeping style changes with very minimal effort. I'm gonna go through that a little bit later on. We also enabled users to create custom themes themselves. And you can... If you don't wanna go quite the advanced custom route, you can just go ahead and choose your preferred theme from our default six that I mentioned in the session properties themselves.
Ray: So whether you're advanced or more just mainstream, using the features as they come, you can get a lot of benefit out of this. So the goals that we wanna go over now... So basically, now that we had that justification defined and got the green light to go ahead with the theming feature, we developed these goals that go through each, and how we accomplish each of them. But basically what those goals were, we wanted to provide built-in web accessibility. And we also wanted to support dark themes out of the gate, and we wanted to develop more intentional data-visualization color palettes, as well as providing just a really seamless upgrade experience for our end users and your users, actual operators. So to accomplish each of these goals, we first spent a good chunk of time really digging into a lot of color theory and doing a lot of design research to develop a design system of color palettes that we could use for these things. And I'm not gonna dive in too much detail today on all of the color theory. But I do wanna go through each of these different palette types and describe how they're used so that if you're developing a custom theme yourself, it's really helpful to understand where and how each of these palettes is applied to the actual components in Perspective.
Ray: So the palette types include the neutrals, which are the 10 through 100 grays that you see there, outside the calls to action, functional palettes, and our data-visualization palettes. And then finally, we have a pseudo palette which are the containers. I'm gonna go into more detail on each of these but just to give you a quick naming overview. That pseudo palette is the containers which give us a Z-index of different containers for our interface elements. And here's a closer look at those pallets, just zoomed in here. And I briefly explain what each of them is used for and how the themes apply those colors.
Ray: So first are neutrals. You can see here we have a range of light to dark, with 10 color shades each. Then there's three different neutral palettes, and they form the basis of those six default themes. So here we have just the lights, the core lights, and then the light cool and the light warm. And then at the complement of that, which you can't see in the image, is the dark, dark cool and dark warm. I'll go into more details on that in a minute. But the tinting, so the reason we did this is to provide just subtly different palettes for a different look and feel of your applications. So the warm pallets, think of adding just a slight tinge of brown or reds; and the cool palettes, they add just a slight tint also of a cool color like a blue or purple. And the 10 shades that we developed here, they give us a really flexible palette to work with as we move forward and design new components in the future. So we don't have to inject any new values or break our color system in future. And the neutrals are used to form the majority of our component UI.
Ray: Next, we have our call-to-action palette. So these are the blues you see in the lower left-hand corner here. And calls to action, we felt that because it's used to indicate interactive elements on the screen, things that users will click on or can click on and work with, essentially, in an application. So we tend to use and rely on blues a lot, internally, for this type of functionality. And that's because just in the context of web applications, it's so baked into every user's understanding of how the web works, how applications work. And we don't have to reach each user's... What indicates that something's functional or interactive or a call-to-action. So we use these blues and you can see we defined universally what our hover colors will be, what our active or selective states will be, as well as some subtle highlights and disabled state.
Ray: Next, we have our functional palette, we use these pretty sparingly to indicate to the user things that are important for them or that they might need to notice. It's similar to alarming, but a different functionality, so you don't overlap those colors. And we have the basics included here that you might want to include, such as information, success, errors and warnings. Finally, we have that pseudo palette that I mentioned, which are the containers. So you can see that these are just leveraging the grades, 1 through 10, 20, 30 and 50, to define three different levels of containers. So they move from back to front in an application. So from the root, just maybe the background of your default view or your repeal, moving forward to containers and nested containers, and then they'll have that consistent border palette defined. And so finally, we also have these data-visualization palettes, which I don't think I've previewed just yet. And we're primarily gonna be using these in our training components. So we went ahead and developed diverging, qualitative, and sequential data-visualization palettes. And each of them have specific use cases, depending on the type of data that we're gonna be representing, or maybe even the chart type that we're using them within. I'm gonna go into a little bit more detail on that later, but just a quick preview of what those pallets look like visually.
Ray: Okay, and now that we have an understanding of the color palettes behind our themes, I wanna revisit our goals for theming and go through how we achieved each of these goals with those palettes. So first is accessibility. We need accessibility right from the forefront, a cornerstone of our coloring systems and theming itself. And we basically wanted to ensure that the colors and the typography that are baked into each component work hand in hand, meaning that text is legible against our background colors, against our containers and headers. It's readable, legible, as well as compliant with a lot of WCAG guidelines. So essentially, we did all the hard work for you, and basically, we wanted to make it really dead simple for our users, our application designers, to use Ignition and create accessible applications for your end user's or operators. And this here just gives a preview of one of the palette's accessibility tests, which was white and black text colors against the different tints within a palette.
Ray: You can see that white through 30 is visible against these tones; 40 through black, okay, are not accessible, so we're gonna avoid using those in any case on the components. Also within accessibility is just color contrast. Again, I don't wanna go too far into the weeds here, but it'll suffice to say it was a good deal of work and we pressure-tested all of our palettes against these types of WCAG compliant guidelines. And here, we're showing the primary palette with a call-to-action palette, 10 through 100. And we're testing, again, the color contrast of foreground and background elements, ensuring that they're legible. And what we did is we only use those that pass double and/or triple, and both. So anything that did not pass or is in this pass with large text only, we went ahead and avoided those in all of our component designs.
Ray: In this some people do go ahead and use AAA theme passes, but really, with our industry and our really high data density, a lot of times our text values are quite small. So we do avoid those when possible, because we're not necessarily designing expression marketing web pages, it's more data-dense applications, tables and grids, things like that, as you all are very familiar.
Ray: So the next goal was dark themes. A little bit more of a fun goal here, we often get this request, obviously internally, for various pieces of the platform, the design included. And this being a newer product, Perspective, we had that opportunity to build it in from the get-go. So we decided to offer it here within Perspective themes, where honestly, the undertaking is a little bit less overwhelming than might be in other products. But now that we have the baseline built for this, it opens up the possibilities internally. The benefits of dark themes are more than just users requesting them and it being a cool thing. What they do is they facilitate screen use within our physical environments, all while conserving battery power on our devices.
Ray: It also improves visual ergonomics by reducing eye strain while staring at screens all day, which a lot of us do, myself included. I definitely have dark mode on at all times on my work machine and that definitely helps with eye strain personally. So I've seen this benefit first-hand. So with this goal of dark themes being offered, established really early, we went ahead and designed these 10 through 100 neutral palettes with that in mind. And what we did was we designed them to be inverted from the center out into the dark themes. On the top, you see what a light palette would be, on the bottom, a dark palette, which... We're just inverting the color values, so 50 becomes 60, and you can see that cross happening here, 40 becomes 70, yeah, 40 becomes 70, 30 becomes 80 as so on. You see that cross happening.
Ray: So at this point, all of our monotonous and nerdy color pallet work early on paid off really huge, because with a simple swap of values we're able to instantly generate our three matching dark themes, which are also contrast-compliant right outta the gate, because that same contrast applies between the lights and the darks. So you can see here an example of what those container types look like side by side, just the inversion of that palette. And here, another example of just a smorgasbord of components on a view, showing what different inverted colors look like between. I believe this is just the light on the left and the dark on the right. So one of our longer-term goals is these data visualization color pallets being applied throughout our products. So with this feature implementation, we laid that groundwork forth in the implementation. So they're gonna be useful for these different types of data visualization, including diverging, which is good for action and performance or rates of change.
Ray: Also qualitative, which is great for distinguishing between different categories which don't have correlation. Additionally, we have, finally, the sequential palette which shows relationships between print-trending data. There are those pallets again visually, and here's the mock of how they might be applied to the components themselves. It's just a nice visual-consistent paradigm, and we're still working towards applying this completely to our large charting components. But it's definitely gonna be baked into our new ones as they roll out, and slowly integrated into existing charting components in a way that, again, has a seamless upgrade experience for folks. And we're also trying to apply, at a large level within the company and throughout other products, potentially like the Gateway itself and various other products that are a part of the Ignition platform.
Ray: And last but not least, we wanted the upgrade experience to be really seamless for our customers and our end users. So the light theme continues to be our default, as it was previously, and we essentially designed it to carry on the pre-8013 UI, with just little improvements, including those contrast studies that we did with the accessibility guidelines.
Ray: And we also baked in a new default font family, which is known as Sans, before it was Roboto. Both Google fonts, free and open source. But notice Sans, if you notice, offers much more language support and it's gonna really help to aid our future localization efforts.
Ray: So, now that we all understand the themes themselves, maybe a little bit more than we wanted to, we're gonna dive into using the themes within our respective applications. Theme selection at its most basic form lives within an application session props. So for a lot of users, this might be the only way they interact with the theme, and that's fine. If you want to switch from a light to a light cool or light warm or a dark, you can do that really quickly and simply right here in session props. You can see by default, again, we have just light set, and like any property in Ignition, changing this prop takes effect immediately in our WYSIWYG design environment. So that means if you choose a dark theme here, and you go back to a view, your design canvas is going to honor that and you'll now be designing within a dark mode with dark-themed components. As you drag new components off with a component palette, they will be themed dark by default.
Ray: So let's see that action. So here's a quick screen recording of me doing just that. So, I'm gonna have a view open with that array of charts on it that you saw earlier. You see that here, our basic charts. And then we go in and switch to the respective page configuration screen down here. And this is where our session props live. Going up to the theme prop and changing that to dark. And then I pop back to my charts view, and you can see instantly my actual live components in the designer are honoring that dark theme. And now I'm designing in dark mode. And that just illustrates how quick and easy it is to completely change the look and feel of your application. And so, as I mentioned, this is just a session property, so like any other property in Ignition, it's open to manipulation via binding, scripting, event actions, etcetera. There's really a number of ways to set the theme, because we all know you can get really creative and roundabout with doing things, and even they can do scripts. So, I'm gonna go through a few of the basic examples of how you might want to manipulate this property, and some quick ways to do that.
Ray: Oh, and a quick shout-out to our great teams within IA, who produce the amazing work which makes up our user manual and documentation. So, you can really find a lot of this exact information at docs.ia.com, inductiveautomation.com. And they have a lot of great step-by-step examples and they go through really the basics that I'm gonna gloss over now, and also some really more advanced ideas in there. So that's a great resource for any new feature such as theming. Right, so the most straightforward way is a simple bidirectional binding between a component property and that session theme property. So this is commonly done with a drop-down component or maybe a toggle-switch component, so I'll show you that now. So with a drop-down component, as I mentioned, it's as simple as creating a bidirectional binding. So we're gonna see in this video, which is just a few seconds long, how that can happen really quickly in your designer.
Ray: So here, I'm going to grab that drop-down component, and then I'm going to create a binding on the value property. Pause a bit, for a second. So in my edit binding dialogue, I click on "Property," and then I'm gonna configure my property binding, I'm gonna use this helper to dive into the Perspective session props and the theme property itself. Being okay, we'll populate the input fields here. And then definitely remember to click this bidirectional check box, this allows the drop-down to write to the session property and vice versa. So now that my binding is configured it, I'll hit "Okay."
Ray: And now because this is just an inner script default drop-down, I'm gonna populate it with some options. So you can see I added two options, the first being light, the second being dark. And now as I go into preview mode in the designer and just choose between those options, you can see it's happening right away. And as I mentioned, it is a WYSIWYG environment, obviously, like a lot of our engineers know. So you can see that happening instantly in the preview mode there. I just wanted to show it again, it's fast. Right, now we're dark, everything's dark. Now we're light, all components are light. So if you can see there, it was just a few seconds, a few clicks, and it's all wired up, that works in the session as well. So this is an example of this same paradigm working within the session. Also wanted to give this redundant example, just because this is a resource which is available on Ignition Exchange. So if you're interested in grabbing resources from the Exchange itself, and picking apart, maybe that's how you learn, not so visual, but maybe you have to do it yourself, right? Grab one of these Ignition Exchange resources, and that supports theming, and you can see it happening live in your actual project and on your machine, which could be helpful.
Ray: So you can see there, I opened a dialogue and it's light, and I swapped the theme to dark, same dialogue, I open again, it's styled dark. And that works for different tinted themes as well, so you can see there, I moved to the light-warm tinted theme there. So it's really easy to use. I had a final example, just to show a different component in action, and actually the toggle component being used. And here in the top right, you can see this dark mode option being toggled on and off. So it usually turns on dark mode, all UI changes to dark mode and off. So that's just a little bit more of a potentially user-friendly way to offer on and off, and a little bit more of a mobile design style interaction in that example.
Ray: Another way to change our theme in a project is by using a component, events and actions. So what we did is we added this action or events called theme. And I'll show you how that happens in a couple more videos here, but it's very, very simple. So this is the way I preview that, is just via a button. So in this example, I have that same charting view here, and I've got a big, old dark-mode button. And when this is clicked, I want the entire UI to switch to dark mode. So I right-click the button and go down to configure events, select the event that I want to affect and add that theme action that I mentioned. Now at this point, the configuration is very simple, it's very similar to the drop-down component, actually. So let me just choose which theme out of those that are available on this current instance we want to swap to when this action is performed. In this case, I'll switch to a dark theme. Okay. And then I think again, you actually, you end the preview with that happening. Click the button, boom, we're in dark mode. So there's various, various ways you can do this, these are just a few pretty simple ones. And you can accomplish that through scripting and various other ways. It's quite simple.
Ray: Alright, moving into our final section this morning, wanted to talk through the basics behind creating a custom theme, as well as a few powerful features within themes which you might not be aware of just yet. But first, I gotta hit you with a big custom-themes disclaimer. So this is an advanced feature, and by "advanced feature," I mean that it's unsupported to some extent by our support department. So because of the very nature of custom themes, you're writing your own CSS, you're writing your own code, just like scripts which are affecting the product. So we're unable to assist with any specific questions about your custom theme and structure of your CSS, but please feel free to ask any questions that you have in our user forums. And I just wanted to note again, start with readme if you're going to be tackling this feature. So the readme file is located in the themes folder, which this older structure steps you down to. And once you get that readme doc, it's gonna give you an introductory guide to custom theming, similar to what I'm gonna tell you today, but in a lot more detail, and it was written by our really talented front-end development staff who know this thing forwards and backwards, so they can essentially convey it to you in your own language. So any of your technical details are gonna be in that readme file.
Ray: Alright, so for custom themes, we're going to go through three parts, first of which is understanding the styles cascade within Perspective. Then we're gonna talk through using a custom font. And finally, we're gonna talk through using custom color variables as well as the default custom... Excuse me, the default color variables which shift with our default themes. So let's get into the styles cascade. So it's really critical to understand the relationship between themes, style classes, and inline styles for theming. And again, another shout-out, so this is not just me doing this stuff, we have a whole great team behind it. This is a screenshot of our user forum, and we've got some amazing employees in there, like Cody, who are answering all of your questions and giving really detailed, great answers, just like you see here, which I'm actually gonna leverage now. So all not officially supported, as I'd mentioned, you can really get some great Q&A going in our user forums. And here, please go ahead and detail how themes work in line with style classes and inline styles. So check out forum.inductiveautomation.com for content like this.
Ray: So to summarize his post there, a custom theme essentially can handle a majority of your default styling. So you're still gonna rely on style classes and inline style properties to manage things like dynamic states or one-off variations, but keep in mind that your theme provides the base. It sets the default styles for every single component. So as you drag components from the palette, this gives them their default look and feel. And it also gives you color variables, which can be used throughout your project in style classes and inline styling, and which I'll talk about more in a minute. And just remember that inline styles are the most specific way to define CSS, so they take precedence always, so they might override things that are defined in your style classes or your themes above that.
Ray: Usually they're used the most rarely, and usually for things that are not repeated across other components or for unique positioning or styling... That's not gonna be reused. So just another way to show that same information here, you can see how each tier overwrites the one above it. And just to give a verbal example of that, and so in my theme, I might set my default button color to be blue. Then I have a style class created within my designer for use cases of when I want my button to be a different color, so maybe it's a warning, and I want that button to be red in that case. So I might create a style class for my red warning buttons, which override my blue default buttons. And then finally, I might have some inline styles within all my various instances of those red, warning buttons, which are used to perhaps position the button within a dialogue or the specific use case where my app, where it actually lives and in the end application. So you can see how each one waterfalls down, so it overrides those above it.
Ray: So now we understand the cascade of styles within Perspective, I wanna talk through adding a custom font, so this requires a custom theme to achieve globally. But by default, I mentioned that our default font of themes is Noto Sans, and so in this use case, I'm gonna walk through replacing that with another font file, and that's going to require creating our custom theme. So the first step is to get our font files. You're gonna make sure you have web-safe font files, which usually are WOFF's or TTF's. Now, there's various font files which are supported by the web, and you wanna make sure that you either use open-source fonts or those that you have the rights to. Quite a lot of fonts are fairly expensive, for good reason, they're very, very well designed, but you wanna make sure you either purchase the license to use these fonts in web applications, or just go ahead and use open-source ones.
Ray: In this case, I'm just showing a Google Fonts example. This is a really good resource for web-safe fonts that are open source, and really well designed in a lot of the cases. So for our example, I'm gonna grab this Teko font just because I thought it visually would be very different from Noto Sans, so in our examples, you can really easily see the difference between default and then when we're using this, more techie Teko font. So we are now going to make our overrides. So the first file to override is our fonts.css file. So we're going to essentially tell our application where to find these files locally on our drive, so we place these font files that I downloaded, and follow the path here into this folder. And now I'm going to tell it, in these font face declarations, where these can be found. So if I had a before and after, you would see that before this would show dash dash font dash Noto Sans, whereas now I have replaced all the references to Noto Sans on the default with this Teko font stack.
Ray: The next file to override is our globals.css file, and because in my "custom theme" here, I am only changing the font. I'm gonna go ahead and start with an import of the globals.css file from the other theme, the light theme in this case. And this is because I don't wanna completely override everything, I want to first... As we understand how the cascade works, I want to first import all of the defaults that light defines, and then I'm going to go ahead and write my overrides just inline, just below it. In this case, this line is telling us what all of the HTML elements are and giving it the font family of our Teko font by default.
Ray: Next up is the third and final file that we make changes to in our custom theme, which is our index.css file. So index, this is the whole file, in this case, it's seven lines, basically what it does is it imports and compiles all of our disparate style sheets into one file, which eventually is used by our sessions in the web browser to display our full style sheet. So keeping these all separate makes it a lot more usable for ourselves and for you now as custom theme developers to grok what's going on where and to allow for a lot of easy manipulation. So that's how the index*.css file works, but in our case, our last two changes that we made were to this fonts and globals.css file, so we are going to change it from pointing to the light CSS file to our now local fonts.css and globals.css. So now we use those instead of the defaults from the light theme. And that's it.
Ray: So this is just a screenshot example of a session, a web session that is using Teko font. You can see in the right example, very clearly, that that's not Noto Sans, it's a little bit chunkier. It looks more like that Teko font that we defined. And you also can see on the left, which is a larger view of an application, this is actually a Maker Edition application that I've... Kicking around my own spare time, a little side project, hopefully once it's done it'll be on the Exchange, but for now, it's still definitely very much in development. Anyways, I just wanted to show on that left preview a little bit more how it applies across all components, so you can see I have just a label in that header text area, and then behind the scenes, that's a tabs component for biography and profile pic, below that another label, and then the file upload component, and you can see the custom fonts are applied there as well, and then a few buttons and labels down below. So it's applied everywhere universally, if we did it just as I showed you in this example.
Ray: And finally, I wanted to touch on using more color variables from themes throughout your Perspective apps. So this is a new way that you can define a set of colors, which you can then later reference throughout your project. And really, if you do anything for a custom theme, this might be a really powerful thing that you can do. We are working on some ways to make this more into the UI of the designer, but until then, this can be really powerful as custom themes. And essentially, what you do is you define, as I mentioned, a set of colors which are used later throughout your project.
Ray: So in this custom theme, I went ahead and added these two color variables. So you saw, like my "fitness application." So now I have my fit brand color and my fit supporting brand color, those are those really vibrant purples that you saw. And now I can use those throughout my project in the designer itself by referencing these named color variables. This is a, hopefully, clear screenshot of that in action. You can see I have a style class dialogue open here. And down through the bottom, right of that screenshot, you can see my background color. I've defined it as the variable fit-brand, just like we saw in our actual style sheet.
Ray: And in the very top, in that big purple example, you can see that purple value being applied and understood by the designer because it's defined in my theme file. So this is really helpful. It solves a lot of problems that we've seen with folks trying to manage their colors throughout applications. I can go ahead and provide other designers on my team with just a list of the approved color variables, perhaps, for them to apply to their screens when they're designing them out. And you can avoid a lot of these weird problems that we run into as application designers where a few years later, you have six different blues or three different error reds, and it just breaks apart and becomes disparate. By doing the work upfront in our themes and defining these custom colors, we can soften that problem and not run into it later.
Ray: And just to reiterate this feature, I showed you the two fit brand colors, they're in the top-right of that screenshot. But down below are the defaults that all of our themes include. So we have all those neutrals that we've talked about, the call to actions, the highlights, hovers. You can see a screenshot of this here, but I think there's around, gosh, maybe 30 or 40 or so defined in these themes files, which you can either manipulate yourself or just add to you as I've done here at the top. And we actually have a great documentation page that went up somewhat recently, which details what all of the defaults are per theme; and additionally, how you can, as I just showed, add your own and reference to those throughout the project. And so that's a lot. But just a quick look back at everything we talked about this morning before we jump into Q&A. We talked through the basics of theming, what it is, our goals behind it, some of the color theories, things like that.
Ray: And we went through how to use themes with simple component actions and bindings. And then we went ahead and created some basic custom themes with fonts and color variables, and went through the style cascade of themes, style classes and styles inline. So yeah, that's pretty much all I had this morning on the subject. I'd love to answer any questions you have now. So I've got one question so far, from Dan Bridgeman, asked pretty early on, and I anticipated this one, "Can a designer itself be run in dark mode?" The answer is no. Mentioned, we've gotten this question, feature requests quite a few times. It's definitely on our minds and we're thinking through ways to accomplish this, but it's not currently built and you cannot currently do that, no.
Ray: But yeah, just a quick thanks again from me for joining. Again, please visit our forums, visit the docs to get any type of information like this that you need. It's all laid out there and just... Yeah, thanks for coming. And I look forward to more of these Ignition Community Lives, they've been really great so far. So thank you.
Want to stay up-to-date with us?
Sign up for our weekly News Feed.