Design Like a Pro: Building Mobile-Responsive HMIs in Ignition Perspective
Applying Mobile Design Principles with the New Module62 min video / 49 minute read View slides
Chief Strategy Officer
Senior Software Engineer
About this Webinar
Your HMI may work great on the plant floor but can you translate it into an equally effective mobile interface? In this second webinar on mobile-responsive design, we’ll show you how to apply the principles from the first webinar using the Ignition Perspective Module, the new visualization module for mobile-first industrial applications.
Join software engineering and design experts from Inductive Automation to learn how to use the features in Ignition Perspective to redesign common industrial applications into mobile applications that are simple, well-organized, and always in-step with the user’s needs.
Learn more about:
- Auditing your design
- Choosing layout strategies
- Reusing existing elements
- Answers to your questions about Ignition Perspective
- And much more
(The moderator, Don Pearson, briefly introduces Inductive Automation and Ignition software, and then introduces the presenters, Perry Arellano-Jones and Ray Sensenbach.)
Session 1 Recap
Ray: Yep, thanks. So, let's get started. The plan for today's webinar is just to get more into the nitty-gritty details about how we can apply a lot of these design ideas that we talked about in the previous session. We're going to be using Perspective heavily today to showcase some of these features. First off, we're going to recap that first session in case there's anybody new with us today, and just to bring those concepts to the front of our minds. Then, we're going to jump into Perspective itself a little bit and walk through how to really specifically accomplish a lot of what we're learning about. Really, our goal is just to sort of set you up to continue on with your own explorations in these new design paradigms.
Ray: To start with that quick review, in case there's anybody new, we're going to recap some of these design principles that are specific to designing and targeting these mobile and touch-friendly devices. Then, I want to go ahead and lay out some of these common responsive layout patterns and add on to that in how to directly create each of these layouts using Perspective.
Ray: Really quickly, what do we mean by mobile-responsive? Essentially, this just means optimizing your screen layouts specifically for user contexts. That's a little bit fuzzy intentionally, but with that, I'm talking about things like targeting device and screen sizes and modifying the types of interactions that users are having with our designs and applications because we're now in a touch world, and we don't have the other input types such as mouse and keyboard. I'm also going to be addressing some unknown factors like the network speed a user might be on and the quality of their connections. We really want to take advantage of these new mobile-specific features that we have now in the mobile world such as geolocation, cameras, things like that.
Ray: To quickly summarize some of the benefits and drawback of responsive, really on the pro side, we have this main feature of lower development costs over the lifetime of your applications. That's mainly due to this fact that we have a single data model to maintain with a responsive app versus creating several specific solutions for specific devices. This leads to the ability to support any device size. With responsive, like I mentioned, we're not targeting singular devices, but the idea is to target the entire spectrum of devices. That also gives us this nice consistency in look and feel in that our apps essentially have the same branding and interface across all devices.
Ray: With that, there's some drawbacks. The main drawback is that there's no one strategy fits all. There's no one best practice for responsive design. A lot of times, our solutions are really dependent on this mental shift, and they are unique to your specific content in your application. That has this learning curve as well because it is a mental shift. This is just something that, over time, we're going to practice, and we're going to develop this comfort zone and become more proficient with responsive design. We really think that the benefits of responsive far outweigh the drawbacks, so we're really investing heavily in it.
Ray: All right, so quickly, I'm going to go through these mobile design principles. We talked about them in much more detail in the first webinar, but, again, I'm just going to bring them to top of mind. The first mobile design principle that you want to consider in your mobile apps is touch and ergonomics. Really, really boiling this down to its simplest form, you essentially want to have larger input targets on mobile because they're touch friendly and we're using our fingers, as I mentioned, as opposed to mouse and keyboard, which is much more precise. You want to essentially leave some space in between your inputs as well so that you eliminate the errors that happen with touch input sometimes.
Ray: We also talked about, last time, testing your designs on real mobile devices as opposed to emulators. You want to, again, really just focus on what your user's context actually is, ideally testing on the devices that they're actually using if possible. We also talked a bit about this idea of depth on mobile. You want to progressively provide more and more contextual information to your user as it's needed. A good example of this is a mapping application, as you can see in this little animation. As we zoom further, further in, the information that's presented is more contextual. It's different, and it's more specific to the location.
Ray: Mobile-first is just this mental shift of designing for mobile first and then expanding content and functionality as we have more real estate on our screen. On mobile, the design is really focused and specific to what that user's action and top priorities would be. But as we have more and more screen space on, maybe, a tablet size or up to desktop sizes, we're adding in more functionality that might be more friendly to the user on desktop.
Ray: We also talked about this new paradigm of content in UI. Essentially, the idea here is, as we remove more traditional inputs like checkboxes, buttons, scroll bars, things like this, we're going to have our users interacting directly with the content itself. Think of scrolling. We don't have a scroll bar on the screen. We just press directly onto the content with our thumbs or fingers and move the content around on the screen. It's a much more natural interaction, and we just want to keep this type of design paradigm in mind because it's just sort of a new way of thinking about things.
Ray: Removing UI clutter, we sort of always touch on this in our design sessions. This is just simply getting rid of anything on the screen that isn't providing a ton of value to the user at any time. A good way to do that in mobile is to try to minimize the amount of fixed elements on your screen. So, if you tack on a fixed header or a fixed footer or both, you start to really eat up the screen space that's available.
Ray: Finally, we talked a bit about designing systems. This is a really common web paradigm. As designers and engineers on the web, folks create these design systems that are made up of reusable components. Usually, they start small and slowly build upon each other to create larger organisms and then full screens. It's a really exciting concept, and it leverages a lot of the best practices that we talk about. It has this great advantage of if you go back and need to make changes or edits, those changes can take place in one place, and then they cascade out throughout larger applications so that you're saving yourself a lot of time and effort in the development side.
Ray: That's it for the mobile design principles. As I mentioned, we went over these in a lot more detail with more examples in the first webinar. If you haven't seen that already, go ahead and check that out if you can. Hopefully, these new design principles become more and more second nature to you as you approach your new projects.
Ray: Shifting now into these responsive layout patterns, again, we talked about these in the last webinar, but today, I'm going to take these a step further and talk about how we can actually build out each one of these using Perspective. These are all common layout patterns that folks use in responsive design to achieve their layout goals, right? This first pattern is called Mostly Fluid, and, as you can see in this little graphic, it goes from mobile to desktop from left to right. The content is completely stacked on the left. Then, as the space increases, those columns shift up into 50% of the space. Then, we stop that growth at some point. There's a maximum width where those white margins just increase on the side here and here.
Ray: To achieve this, it's really straight forward. I actually just went ahead and used our column container and then firstly just arranged my A, B, and C components on the artboard. Column containers have built-in breakpoints, so I chose two breakpoints, small and medium, and I arranged the components differently on each of those. On my small breakpoint, A, B, and C are in one column, and then once I reach my medium breakpoint at 700 pixels, the layout changes. The number of columns that each of these components is spanning, B and C just swaps from 12 each to 6 each, so then they naturally flow up next to each other.
Ray: Once I have those components in place on the column container, I simply added a few styles to the root container to create the full effect that I'm going for. I selected that root column container and firstly, I defined this maximum width of 1,000 pixels. That means once my design reaches 1,000 pixels, that's as wide as it's going to grow and that's why this is Mostly Fluid. It doesn't completely go fluid to the infinite widths that somebody might have on a really large screen, so I define this maximum point.
Ray: Then, I went ahead and added this margin of zero auto, and that gives me a nice centering effect with the CSS. Top and bottom has zero margin, but my left and rights are just automatically calculated, which makes them centered in the browser. That's all it took. It's just a simple column container with a few styles, and you can see here in this resizing browser how my layout is changing to be from one column to that other layout that we discussed.
Ray: The next pattern is known as Off Canvas. This is really frequently used in mobile. Essentially, what we're doing here is moving a lot of our content from our designs off of this physical screen, but it's always one click away, and it's always able to be reached by the user when they need it. It's used a lot in combination with a lot of these other patterns that we're going to talk about.
Ray: To build this, I just went ahead and leveraged Perspective's docking system, docked views. It might be a little bit hard to see in this example, but this is the page configuration in Perspective, and I'm just simply setting up these docks that I'm going to show you in a minute here. I'm setting up sidebar dock on the left, and in the bottom, I have an alarm dock and just a content dock. This configuration that pops up here when I click to edit these, it gives you a lot of options to really make these each custom in the size, custom interaction in how they operate.
Ray: You can dock views to any side of an application. There should be a graphic here, but this essentially shows that you can dock your views along the top, left, right, and bottom of your application. Then you have your main content area in the center of the screen like you'd expect. You can even dock things into popups in front of your content.
Ray: This is just a quick and dirty example I put together of those docks in action. In the top menu, in the header, I'm using just an on-click event to trigger that sidebar coming in, and this is just my docked view, which has my main navigation. Along the bottom, you can see I've got other docked views, that might be alarms or just other content that my user needs. This is just a nice, easy pattern to move content out of the way so the user can focus on main content and then they can, obviously, bring it into view when it's needed.
Ray: Next it the Column Drop pattern. It's really similar to that first fluid pattern I showed, but it just doesn't have that maximum width. You can see in the desktop view we're using up all of the space on the screen. To accomplish this, I actually use a combination of tools. This is one of those examples where there are many ways to accomplish these layouts. In this case, I just simply use, again, a column container, in this case, a breakpoint container, and I'm leveraging, again, the docking system of Perspective.
Ray: You can see on my small, mobile screen, again, I have just that simple column layout, A, B, and C stacked. Then, at a certain breakpoint, I think it's around 800 pixels, my B container pops over to the left sidebar and takes up that physical space now that it's available. Then, I'm left with just A and C. I accomplish that by using a breakpoint container, which has my nested column container within in it. That dock triggers automatically at a certain breakpoint to pop into view. Those two things happen at the same time. Again, that's just one way to accomplish that. There's no correct way. You just need to explore what works best for your content, and because views are infinitely composable and mutable, there's, again, just a lot of ways you can do these things.
Ray: Tiny Tweaks is another layout pattern. It focuses a lot on content changing itself. You can see in this graphic, my layout actually isn't changing. That just means that I'm going to use style changes to support usability. That's used frequently to just change margins and paddings or text sizes and changing how content is being displayed on the screen.
Ray: I'm actually going to let Perry cover this a little bit later in the presentation, but this is just a little preview as far as what he's going to talk about in more detail later. This is a typography section of a design style guide that he's going to help you create.
Ray: Layout Shifter is a heavier, little bit more custom solution. It's used in completely different layouts or completely different components to represent the same content. This is one pattern that might require a little bit more work to configure, but, again, it leads to really custom solutions based on the content that you're trying to present. It's super useful in a lot of cases, and it's definitely worth the work a lot of the time.
Ray: I actually didn't build out an example of this. I just used our great Ignition demo online. You can check this out live at demo.ia.io or demo.inductiveautomation.com. This is just a live demo of, in this case, an alarm status table. You can see on mobile, we're using this card element and this list of data to represent our alarms. That works really well on mobile because it's legible. It's very horizontal. I'm sorry, it's very vertical in nature. Then, once we get up to a larger desktop view, we're using a full table component to represent that same information. So, tables are much more desktop-friendly, whereas just the raw data and the cards themselves are better suited for the mobile experience.
Ray: This is just one example on the demo site, so go ahead and check that out. You can grab your browser and drag it around. All the pages are responsive. They all use different patterns and different strategies to best represent the data. It's really interesting to take a look about how a lot of these layouts are accomplished on that website.
Ray: All right, so that's it for the layout strategies and design patterns recap that we talked about in the last session. We're going to move on to a little bit more of an applicable topic. We're going to start off with project planning and go through a lot of best practices with developing components and layouts with Ignition 8's powerful new features. I'm going to hand it off now to Perry to walk us through that planning and bring us through to the next section of the webinar. Perry.
Planning Your Project
Perry: Thanks, Ray. All right. So, project planning. One of the biggest challenges in any creative venture ... That's exactly what planning a project is, right? But the big challenge is really figuring out where do I start. Most of us, the answer's pretty simple. We're going to collect the requirements, also known as deliverables, for our project and, hopefully, that gives us enough information to move on. A lot of organizations have formalized requirement and bid processes, and those are great, but sometimes that great technical documentation that you get isn't totally in line with what the user actually experiences.
Perry: As a result, one of the things that we definitely encourage quite a bit is for you to spend time with your end user in their environment. This gives you a much better understanding of their workflow, of their environment, the devices they're using. Maybe they've got a lot of sunlight coming in through a window that makes certain colors really hard to see on a screen or something like that. That's the kind of information that you may not get in a technical, formalized requirement document. Definitely, do what you can to get into their space.
Perry: If you can't be physically present, then organize a teleconference or maybe get some pictures of their environment, even just a phone call can help shed a little bit of light and give you a more complete picture on what it is that the user's really going to benefit from. The side benefit of that for us is that this extra information can actually help you deliver a better product, which may reduce the amount of reworking you need to do or reduce the amount of problems that end up resulting in your application and having to come back and fix them later.
Perry: Another thing that we talked about quite a bit in webinars and in sessions at ICC in the past is using wireframes. Once you've got a fair understanding of the requirements for your project, it's time to start actually figuring out what you're going to build. This is really where we start coming into design. If you were at our ICC session last year, we spent a lot of time walking through some designs and recommending creating wireframes before you start building. So, what would that look like?
Perry: Wireframes don't need to be complex. You don't need fancy tools necessarily. A lot of times, just putting some ideas on paper with a pencil will help you organize your thoughts and figure out what possibilities are there and what's going to work best. For example, here's an initial sketch up that Ray actually did for the new Vision project launcher in Ignition 8.0. At its lowest fidelity, we're able to work through a lot of simple design decisions and just figure out our general layout. Then, you can take that and take it a step further and create a mock of your actual design. This is still technically what we call wireframe fidelity, but from here we know the structure that we want, and it's just a matter of adding the UI polish in order to bring it all the way to production quality.
Perry: This is something new, but once you've got a wireframe, it's time to actually start figuring out how you're going to build the project from a technical perspective. Here again, a little planning up front can save you a lot of time in the long run. So, what should your project look like? There's really no best way to structure a project, but one thing that we do suggest is in leveraging Ignition 8's project inheritance. If you're unaware, project inheritance is a new feature, and it allows us to basically combine projects by inheriting the resources of another project.
Perry: For instance, in our image here on the left, we've got project A where I've created some templates. Project A is inheritable, meaning any other project that I want to use those resources can inherit those resources. If we look, we've got project B that doesn't have any templates. Simply by setting B to inherit project A, now project B has all of those templates available to it. Beyond that, project B can not only just use those templates but if project B has a special need, it can actually override those templates with its own version.
Perry: Previously, you could accomplish this by exporting your resources or your projects, but if anybody has done that, it becomes pretty painful as your organization grows or your changes start happening more rapidly. This system, you basically make the changes once in one place, and all your projects simply inherit the improvement. It's a lot less overhead to manage. This also lets us do things like if I'm a big organization, I might want a UI design team that's focused just on component development that everybody else can use. It's pretty neat that I could create a team, and they'd work on one project all the time building out great components, and every other team in the organization can use that same component library, so the entire organization has the same look, feel, and consistency across their projects.
Perry: Finally, the last step, Ray already mentioned this, but we always recommend creating a design system instead of just creating a single-page or a single design. Remember, design systems are ... They're just a collection of visual guidelines. They can be large and complex, but they don't need to be, and they almost never start that way. Start simple and build it up when it makes sense.
Layout Tools & Strategies
Perry: All right, so starting our project, that's what we're going to be doing today. We're going to take our own advice and walk through some of these steps. We'll do it by essentially putting together our own design system in Perspective. We'll build some responsive screens along the way and give you some examples. For me, I already have a lot of user feedback because we hear what you guys want to see quite a bit. So, I can check that one off the list.
Perry: Wireframe design, I'm actually going to steal some of Ray's wireframes and design systems that we used in Perspective early on as our inspiration. So, I've got that checked off. Then, project inheritance. To start my actual project, what I'm going to do is create two separate projects. One is going to be a component project that's going to act as my component library. It will be an inheritable project. The other is going to be, what I'm going to call, my design project, which is where my design system is. So, project inheritance, check. A design system is what we're going to be building, so we're going to have to save that last checkbox.
Perry: With the design system, the question arises, what should you put into it? You don't need to be complex, and these are some pretty complex examples here. Don't try to do that, certainly not to start. To start off, just keep it simple. Start with some colors, maybe your company's brand colors and some action colors. Even then, if you want to get a little bit more advanced later, do that. Just like this example that we're working off, add some typefaces, some different styling for different elements of text. Then, from there, if you need to get more technical and get larger, you can certainly do so, but don't be intimidated and feel like you've got to start there.
Perry: Again, we're following our own advice, and we're going to just pick an element from here in order to start building it out. Specifically, I want to start with this row of base colors, so let's take a closer look at that. These are base colors. The term base may not be familiar to you if you're a new designer, but base colors are just something that we use in designs where we want to create a sense of depth or maybe differentiation between different elements. For instance, if we've got a header of a table that we think needs to look distinct from the rows beneath it, we might use colors from the scales to note that difference. Having a defined base gradient like this that's shared across components is a great way to achieve some cohesion in your designs.
Perry: If you look at the row of base colors here, you notice that each color swatch is the same shape, same size. They just have different values presented, right? Anytime we see something like this, we should ask ourselves, "Hey, is this an opportunity for breaking down this design into reusable parts?" I've got seven color swatches. There's a good chance I'm going to want to add more later, so I think it makes sense to invest a little time into abstracting this into a single, reusable component. So, let's start there.
Perry: All right. Oops. Here I am. I've opened up the designer, and I'm in my component library project. If I look at the project resource tree, I can see that I've got two new resources that Perspective provides, styles and views. Styles are a resource that we can leverage to apply design styling in a very performant way. If you're familiar with CSS, you've got any sort of web development background, styles are effectively CSS classes. We're going to talk about those a lot more.
Perry: Now, views are what hold our components, and they do so through their use of what we call containers. The primary tool of organizing your components on your screen is the container. That's basically how we achieve our layout designs and our responsive designs. A view gets exactly one root container, and that root container determines really how all the immediate children of the view are organized. Containers themselves are just special components. You can combine them. You can nest them. That's how Ray achieved some of those designs in those early design patterns that he was talking about.
Perry: What's really neat about views is that they too can be used just like components in other views, meaning that we can take a view, we can add some components to it that serve some root purpose, and then we can basically use that everywhere. We call views that are set up to do that template views. We'll talk about how we build that. Let's actually do that right now. We're going to start building a color swatch template view. I'm missing an image there.
Perry: All right, so getting started with our template view, we're going to right click in the designer in the views, and we're going to create a new view. Right away we're presented with this configuration panel here. If we focus just on the layout options for now, there's five of them. We're going to make use of some of them today to better understand how it impacts our design. With five options you have to ask, what should I choose? What makes sense? Like many things when it comes to design, there isn't a best choice for a blanket answer. It's really going to depend on the content and the context that you're working in.
Perry: They all serve different purposes. They have different benefits. Given that most of us are familiar with coordinate-style layouts, we'll start there. That makes sense for this component because we're not looking to have any responsiveness for our color swatch. I choose coordinate, create the view, and I've got an empty view in my workspace. All I have is an empty canvas here, so where do we start with? Well, looking at the element that we want to create, I basically have three things that I'm worried about. I've got the color up on top, and then I've got these two labels down below.
Perry: The color up on top, there's a lot of things that I can use for that. I'm just going to choose a label because I know that I can remove the text from a label, and I can color the background. Piece of cake. To actually make this, all I need to do is resize my view to a reasonable size. I grab one of our labels off of our pallet of components, get some initial sizing done, and then I can use the control if you're on Windows, or command on Mac, plus shift and then drag. That lets me basically duplicate any component and keep it in the same line whether it be horizontal or vertical.
Perry: I've created my three labels here, resized it. This is basically it for now, right? So, where do we go from here? How do we make this actually usable by other components in any meaningful way? How do we turn it into that template view? Well, the answer really lies in bindings and parameters. If you're new to the Ignition platform, the term binding is just a mechanism for associating data between two elements. Those elements might be component properties. They might be a tag or a tag value in a component. We'll see how that works here in just a moment. For now, we're going to set up our view's parameters.
Perry: Parameters are essentially the way that you get data in and out of one of these template views. To create my parameters, if I select the view in the project tree like we have here seen on the right, the Perspective property editor responds by showing you the properties available to the current selected thing. Views have parameters. To add a new parameter, I simply click that little blue plus, and you can type in whatever values you want.
Perry: In our case, our color swatch, we've really got three things. We've got a color and then we've got two labels, but the actual color itself in one of those labels are being driven by the same data. For my parameters, I just create two of them. One that holds the name of the color, the other that holds the code. I've given them some default values here, so when we drop it onto a screen, we can have something there that isn't just random text or nothing.
Perry: With our parameters now set, now we've got to do our binding. That's what basically we see happening here is I'm going to come in here and to create, for instance, the color swatch up top, I delete the text, and then I use a style property. There's two different ways that you can really style components, at least two primary ways. There's style classes, and then there's style properties. Style classes are that resource I mentioned at first that you can create just like you create a view. Style properties are properties that apply only to a specific component. That's what we're going to use here right now.
Perry: To add a style property, what we do is create a new key and value in the style section of our component props, and we just type in what we want. If you don't know exactly what you want, you can click a little icon that's to the right of the word style, and it will pick a little helper up. That will guide you through some of the things that are available to you. Once we've got our properties set, you can see this happening in the image. The next thing to do is set up the actual binding. To do that, all we do is click in the gutter just to the left of the property we're interested in binding. You see right here there's a little icon. Clicking that brings up the binding configuration panel, and once our binding configuration panel picks up, we're looking to bind properties.
Perry: We want our view parameter property to provide the value and to send it into the place where we're binding it to. In this case, it's the background color. We're going to choose the property binding from that little editor when it pops up, and then we can use the helper that we'll see again here in just a moment in order to find the path to the actual property we want to bind to. Here we are. We're finding the property we want to bind to, which is one of our parameters. Click color code, accept it, and with that, our values are now being driven by that parameter.
Perry: That was it to making our template view. It's really pretty easy. We basically use a container to figure out how the view's layout's going to work. We use parameters to send data to and from the views, and then we can use bindings to connect the data between the parameters and the actual component properties. Let's move on and figure out how we might use this template color swatch to build our first view in our designer project.
Perry: Again, that was in our component project, which is our inheritable project. Now, we're going to move over to the designer project. Just as a reminder for what we're looking for here, we're going to try and replicate this row of base colors. So, a similar process. Basically, what I did is I created a new view, and I size it approximately what I think it should be. Then, you'll notice that the component that actually gets pulled off of the palette here is not the color swatch component. What it is is the embedded view component. Embedded views are a way of basically calling another view and using it as a component.
Perry: All embedded views take a couple properties. One of them is a path, which is what just got configured there. That's a path to the view that you're interested in presenting. Because we inherited that template view, it shows up in our project resource tree just like a local resource so we can choose it. Then, the other thing that we configure with that is this params array. You can see there that once we get that embedded view on there, it shows right up with the default white that we had set previously.
Perry: To give the color the name we want, since we've got our bindings set up and our parameters set up, all we need to do is configure the parameters for this particular template. Here I'm just adding to this params property those two parameters. Because they're already bound, if I type in color name and add something in there, it ends up being applied to the label and also to the background color. After we've got one of these up, we can just make copies our of embedded view, update the parameters, and this is what our result is. Looks pretty good, right?
Perry: We can actually look at this in the designer and then also in the browser and see how they look. Here in the browser, it looks exactly as it did in the designer. Since we're here to learn about mobile responsive design, let's see what happens when we take this and we put the browser into responsive mode. To do that ... Ray already showed you that little slider, but here's how you would actually enable that. You just open up the development tools in your browser. In this case, we're using Chrome. In Chrome, there's this button up at the top left that I've highlighted in red. If you click that, it will take you to a slightly different view of your browser, and it provides these new little bars that you can grab onto in order to change the size.
Perry: What we see right here is, unfortunately, our coordinate container that we picked is letting us down. As our screen size shrinks, our content doesn't respond at all. Instead, we just get a scroll bar. We've talked a lot about this, but scrolling, especially horizontal scrolling, is just not a good experience on mobile. So, let's take another look at a container that we could have used that might actually behave a little better as our screen size shrinks. This is where we're really starting to think about responsive and not just simple coordinate organization.
Perry: This time we're going to choose a different container. That's going to be the flex container. When you add a component to the flex container, it uses something called CSS Flexbox. Flexbox, if you're not familiar with it, don't worry. We're going to have some links for some reading at the end that you can check out. I'll say that Flexbox itself is really pretty simple. It lets you put items into rows or columns. You can choose one or the other, and it just treats each item as a box. Then you can configure how each of those boxes actually reacts to the environment.
Perry: You can align them to the left. You can align them to the right. You can justify them in different ways. You can tell these boxes to spread apart or stick together. In addition, you can also tell the items whether they should grow or shrink or maybe wrap if the space available to them changes. These animations here are just a couple of the options available to you. Flex containers are really a good way to get a mobile-first design, at least to get started.
Perry: This image here, basically, we're seeing the same layout. It looks identical to the coordinate. The main difference is if we look at the coordinate version, we've got up here ... You see a little X, Y where the container is. It might be hard to read on your screen. It's a little hard to read for me, but in your designer typically you can differentiate that from this one, which has got these little boxes. So, that's hint number one that our container type's different. The other thing that I notice is that over here on the right, our properties are different from a coordinate container. A coordinate container doesn't have a direction. It doesn't wrap. It doesn't justify. Those are two things that you can really quickly, at a glance, determine what kind of container is on the current view that you're working with.
Perry: How does this one work on mobile? This is actually a much better experience. As your screen real estate gets smaller, it just starts to wrap around. The great thing about this is that the amount of work that it took to create this given the same starting point is actually less than it takes for the coordinate layouts. I don't need to worry about moving our components on the view and placing them where I want. I just put them there, and then the flex container will align them based on a couple settings that I set.
Perry: The main thing, I guess, to take away from this is really just how important container types are. Choosing a more responsive container doesn't necessarily result in more work up front, but there's a high likelihood that if you choose the wrong one, you're going to end up with some work because people are going to want a better experience on mobile. So, take some time. Play with all the different containers. Get a little bit of a feel for how they work, and then choose the best one depending and your specific goals.
Building Reusable Elements
Perry: Let's go to the next step here. We're going to dive a little bit deeper in our design system, and we're going to apply that Tiny Tweaks pattern that Ray talked about. Well, just as a reminder, Tiny Tweaks is basically stylistic changes to the same content. By content, I just mean the text on the screen, the images, stuff like that, in, of course, the same layout. We're not changing the structure of the page at all. We're just changing the way that certain stylistic parts appear. Like Ray mentioned, we're talking about text size and maybe your font changing or the padding around elements changing, borders, highlights, that sort of thing. Tiny Tweaks are something that's actually pretty easy to do and can be very powerful in the right setting.
Perry: What we're going to do is we're going to try and replicate some different text types. It's pretty common in any application to have something like we see here where we've got headers that are differentiated. Different sections of our page might have our standard paragraph text and more specialized text types like labels. Here I've got this one called Equipment Label. Taking a little bit of a closer look, this is what we're going to try to replicate. Essentially, we've got two different columns of text. As I'm mentioned earlier, style classes are a great way to achieve stylistic differentiation and reusable styling in your project. On the left, we've basically got an example of what the text looks like, and on the right, we've got the name of the style class that we created in order to create that appearance.
Perry: Let's see how we can leverage style classes to accomplish our Tiny Tweaks. As I did last time, kind of the same thing. I asked myself, "Hey, can I make something reusable to save myself future work?" There's a good chance that we're going to add more text in the future, and it sure is nice having that component where all I have to is provide it the parameters, and it changes to be what I want. The answer's a clear yes. In our case, we'll basically deal with each text item is just two labels in a row. Rather than worry about creating them and aligning them for each row, I'm just going to make a single component just like I did with the swatches. Then I can use that anytime I need it.
Perry: I'm going to skip past the nuts and bolts of creating my component because the process is basically the same. There's just a couple implementation differences that are worth pointing out. The first one is that you'll notice here, like I mentioned before, our container has an icon next to it. This is not the X, Y in here, so I'm actually using a flex container. A coordinate container could work here, but I chose flex because we're looking to probably change the style of this, which means that I might want the size of my component to actually respond to the environment or to the content. If I were to choose a coordinate container, there's a chance that I could end up with scroll bars if, for instance, my header text is too big.
Perry: The second difference is a little bit different in that I'm just going to use a different model for how I create my parameters. In the previous one that we did, which is here on the right, we created two different parameters because we had two different values we're trying to send in. In this example, instead of creating two different parameters, I just created one. Using this deeper nesting in parameters like this versus using independent parameters like this is really a judgment call. A single object parameter can make for a little bit cleaner configuration in some cases. It's also a very natural fit if you've got UDTs for instance, which are user-defined data types. If you've got a very clear match for your template view, creating this object-style parameter can accept the whole UDT value. It just really depends on what you're trying to accomplish.
Perry: The downside to this deeper nesting is really that it can become a little bit more monotonous to try and find those sub values in scripting or when building data objects in the property editor. Then it may also not be quite as clear to your users that are trying to configure these things, but it gets a little bit of experience for both to figure out what works for you.
Perry: One other thing that I want to point out is that I'm going to use a transform here. A transform is something in Perspective that occurs in bindings. When you bind something typically and historically you would just basically get that raw value and no real direct way to change it before it arrives at the destination, meaning the property we're actually trying to apply that to. Transforms are really neat in that they will basically intercept a value that's coming in via our view parameter. It lets you modify that value before it arrives at its destination.
Perry: Common uses could be something like mapping an integer to a color code for instance, or another thing could be running maybe some text through a localization script or something like that. There's a lot of uses for them, and what's really neat about them is that they can actually be chained. I point this out in the context of responsive design because one of the biggest limiting things that we find with designs in the time it takes to implement new designs is really in trying to get that data to your component in a way that's usable by the component.
Perry: Here with transforms, if you're familiar with Vision, you used to maybe use a client tag, and you would take your binding and write at this client tag. Then you would have some change script or something like that that changed the values on that client tag. Then you had another tag or another property somewhere that was actually listening to that one. It was a little bit challenging at times. This is a much more direct model, and it's performant, and it's super clean and easy to understand.
Perry: For us, my transform is really pretty simple. One of the parameters that we created in our text settings object was an array called classes. Classes in a regular component are something that we use in order to add our style classes to our component. I don't want to present text that's an array. I just want basically a single string that I can add as my style class name in the event that I have multiple classes applied to my component. All I'm doing here is I'm basically taking that array, and I'm just joining all of the elements of my classes array into a single string. This is what that looks like as it's configured.
Perry: That was basically putting together our little example text component, right? We've got the example text on the left with this default value, and then we're going to have the name, or names if we've got multiple, because we're using that array that's transformed into a single string or have one or more style names on the right.
Perry: Now, back in my designer project, I'm going to create a new embedded view in order to use this. Instead of using an embedded view that is static, I'm going to choose a flex repeater component to hold my embedded view. Flex repeaters are really pretty neat because they allow us to be flexible in what we present. It lets you basically pick the path of the component, or view, excuse me, that you want to represent, and then the number of times that that shows up is totally dynamic. It's dynamic based on how many entries you have in this instances array.
Perry: That's what we're demonstrating here. As you can see dynamically, as I add a new element to our instances array ... I'm not even adding any values. I'm just adding a new empty object. For each one I add, it creates a new instance of my view. The way that this works is that if those values in that array happen to be parameters or happen to be named the same as your parameters, the view essentially is provided those values as its parameters, and that's how we basically get out dynamic values. This is a pretty simple case, but hopefully, it's easy to imagine how you can use this in more complex environments and with much more complex components.
Perry: We've got now this flex repeater in our dynamic repeating view, but currently, it's just showing our default values. Let's start getting them styled and start getting them populated with some actual values we care about. We're going to create some style classes, and we're going to add them to our instance configurations. Style classes are those style resources that we talked about right up above here above views. All style classes have names. I'm going to choose for basically all my text style classes some consistency because I want them to be recognizable and easy to identify.
Perry: I'm starting all of them with the word text and then underscore and then the type of text that they are. Then, at the end, I'm just appending maybe dark or light. Dark being my text is dark, so it's the kind of thing that I'd want to use on a light background, and maybe I might want a light version if my text is light. That would be the kind of thing that I would use on a dark background. After creating the name of my style, I get this little style helper that pops up. Now, all I need to do is basically add the styles that I want to apply to my class.
Perry: In this case, I'm starting with my header. I just want it to be a little bit bigger. So, I set the font size, click okay, and I've got my font, or, excuse me, my style created. In doing that there, what I've basically have done, even though it’s over here on the left, is I've created my base style. A base style is something that basically applies that style to my component regardless of the situation, assuming that I have no further style rules applied. A style rule is basically a way to get some additional dynamic functionality out of your style.
Perry: That is actually how we're going to start accomplishing our Tiny Tweaks. If I click that style rule with the little plus button next to style rules, I'm presented with two options, element state or media query. Element states represent something in CSS known as a pseudo selector. They're a way of styling an element in pure CSS so that it can respond to environmental things such as mouse hovers or maybe the component being focused. They're a lot of fun to use, but right now, we're more interested in responsive design, so we're going to look at media queries.
Perry: Media queries are similar except their focus is more on configuring styling behavior based on things such as screen size or aspect ratio or orientation on the page. If I choose media query, I can see I've got a new style rule that's created over here, and I've got this new option up at the top. There are a number of different things that I can pick from there, but the one that we're interested in right now is min-width. The way that that works is that essentially when my min-width is surpassed, the whatever styles that I've created for that particular rule will be applied.
Perry: You can see here that we're still working on our h1 text style, and we've chosen a min-width of 480 pixels, which is typically a decent starting point for something like a mobile phone. Then, we're just applying a little bit more margin to our component when we get to mobile. If I save this and I apply it to the component by adding it to our style classes array and then I open that in the browser, you can see right here we have a whole bunch of reactivity to our size growing.
Perry: That's exactly what we're looking to accomplish. When it gets wider than 480 pixels, we get a lot more padding, and that's going to make it a lot easier for somebody on a desktop screen to view because on mobile, the phone's close to you. You don't need quite so much space between elements because it's right there. It's very sharp typically, and beyond that, you don't have a whole lot of real estate. The desktop, a little bit different environment. The screens tend to be further away. They tend to be lower resolution. Having a little bit more space between elements can really improve readability. So, that was really what we're trying to accomplish here.
Perry: Unfortunately, it actually looks like we're starting to run out of time. I think what we're going to do is save some time for Q&A, but Ray and I are going to put together essentially the projects that we built these examples with, and we'll make sure that they're tagged on the webinar slides at the end as something that you can download and take and run with yourself in order to get more experience with how these views work. If you do that, definitely post something in our forums. Get in touch with us. Show us what you've built because we love seeing what you guys put together.
Perry: Just to wrap up real quick, we've covered a lot today. Specifically, with the Tiny Tweaks stuff, we learned a little bit about style classes and how we can use them to provide responsiveness via media rules. They're very performant. They're something that can be shared. You create that style class once. You can use it in any number of components. You can use multiple style classes. A component can have not just one, but you can create basically your font color style and maybe your font size style and then combine them both to get a color and sized label. You can mix and match all you want.
Perry: I'm going to try and save some time for Q&A, so thanks for everybody for being here today. There's going to be some resources here to check out, and I'm going to actually turn it back over to Don.
(The speakers start answering viewers’ questions for the remainder of the webinar. Selected questions and answers related to Ignition 8 and Ignition Perspective are transcribed below; for the full Q&A section, please listen to the webinar recording at the top of the page.)
Q&A: Migration from Ignition 7.9 for Non-HTML Programmers
Don: We've filled the whole hour with content, but we're going to take a couple of minutes for questions. I'm going to ask one that I know people are interested in because you've covered so much ground today. When you take a look at Ignition 7.9, is migration from Ignition 7.9 a steep learning curve for non-HTML programmers? Any thoughts on that?
Perry: That's a great question. The simple answer is never simple, but you can make a lot of ground without having to learn a whole lot new. If you use the helper tools and the helper UIs in there, you can really basically, I think, get up to speed with the equivalent features in Vision pretty fast. In that regard, there's not a very steep learning curve. When it comes to the little bit more advanced functionality like we're talking about like responsive pages or responsive design, at that point, I think it definitely pays to have some familiarity with CSS. It doesn't need to be a super deep familiarity, but there's going to be some learning involved.
Don: Okay, cool. Well, at least that's a start answer to it. So, it depends.
Q&A: Maturity of Perspective Compared to Vision
Don: That's okay. Okay, cool. I think this is a general question, and you guys can ... We're going to try and get to a couple of questions. We'll probably overrun by five minutes. Then we'll let everyone go for today. But Carl and Colby’s February blog post stated that Vision is currently more mature, stable, and comprehensive than Perspective. How long will until Vision and Perspective are equal peers in terms of functionality and stability? I know that's probably a it depends question also, but any thoughts on that either Perry or Ray?
Perry: Well, yeah. Yeah. We get asked this a lot. I guess it's a few things to keep in mind. First, obviously Vision's been being developed for about 12 years, so it's pretty difficult for us to try and shoot for feature parity with Vision on day one. When it comes to components, components are something that are going to just ... They're going to constantly be worked on, added to, polished, and worked throughout the lifespan of Perspective. That's going to be an ongoing thing, and we've got a whole bunch of plans for new components and improvements on the existing components.
Perry: When it comes to stability, Vision and Perspective are very different technologies. Of course, our goal is for them to be equally stable, and I think that we're at the point now to where it's certainly stable for most use cases. Like any new product, people are going to find edge cases and bugs that we haven't hit before, but I think we're in a pretty good place there.
Q&A: Project Inheritance
Don: Okay, cool. Here's another question. Does project inheritance work across Perspective and Vision or are the resources unique to each module?
Perry: Well, yes. Project inheritance does work across modules. If you've got an inheritance project that you built both Vision templates and Perspective resources in, then yeah, they'll be available to everything. You're not going to be able to use Vision resources in Perspectives in any sense, but you'll be able to inherit those resources in any project.