View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Videos

Open Menu Close Menu
  • Collections
  • Topics
  • All Videos
  • About

More Videos

Streaming is available in most browsers,
and in the WWDC app.

  • Overview
  • Transcript
  • Introducing Dark Mode

    Hear from the Apple design team about the principles and concepts that anchor Dark Mode. Learn the basics of enhancing your app with this new appearance, and add an experience that people are sure to love.

    Resources

    • HIG for macOS
      • HD Video
      • SD Video
    • Presentation Slides (PDF)

    Related Videos

    WWDC 2019

    • Implementing Dark Mode on iOS

    WWDC 2018

    • Advanced Dark Mode
    • Advanced Debugging with Xcode and LLDB
    • What's New in Cocoa for macOS
  • Download

    Hi everyone. Welcome to the Introduction to Dark Mode session. My name is Raymond Sepulveda, and I'm a macOS designer on the Human Interface Design team. For the first half of today's session, I'm going to be going over some of the design principles that went into the design of Dark Mode, as well as some of the design considerations that you should take into account when updating your own applications to take advantage of Dark Mode. Then, for the second half of the session, my engineering colleagues Rachel Goldeen and Taylor Kelly from the Cocoa Frameworks team are going to be going over how to adopt and support Dark Mode using an example application that they built together. The three of us are super excited to share all of these details with all of you, so let's jump right in. As we announced in yesterday's keynote, macOS 10.14 is going to be getting a new interface appearance, and we call it Dark Mode.

    The new design is very attractive and engaging, while at the same time being very calm and understated. These are great qualities for an interface, and they make it great for creative professionals who are dealing with heavily detailed images and colorful assets such as images and video assets.

    But, in actuality, it's actually great for just about any type of user who is looking to concentrate or focus on any given task at hand. So, whether you're trying to concentrate on writing the next great novel or you're trying to read one without disturbing your bedside partner, Dark Mode is really great for either type of situation.

    The interface shares a lot of family resemblances between the light appearance and the dark appearance, and that is because we wanted to encourage users to switch between both appearances easily and find the one that really best suits their needs. And so it was very important that things like control metrics, window layout, and the distribution of translucent materials be the same as much as possible between both appearances. As such it's also equally important that all of your applications take full advantage of both appearances so that they update correctly between both appearances no matter what the system is running under. You really don't want to be that one light appearance that's stuck in dark appearance. All in all, we're super happy with how the design turned out, and we are really anxious to see what you guys are going to turn your apps into as soon as you get hands on the developer beta and start adopting the Dark Mode.

    Aside from Dark Mode, another new interface feature that we added into macOS 10.14 are accent colors. Previous releases of macOS offered two accent colors, blue and graphite, but for macOS 10.14, we've expanded the color palette to include eight fun colors to really help you personalize your Mac. So, if you're like me and you love the color red, you're going to immediately switch over to the color red . If orange or yellow are more of your preference, you're going to switch over to those, and we make those available as well. I should note that the accent colors are not just a sub-feature of Dark Mode, but they're also available in Light Mode. So if you prefer Light Mode but want green accent color, you can do that as well.

    So, now that we've covered a little bit of the basics of what Dark Mode is and what accent colors are also, let's dive a little bit deeper into some of the design principles that went into Dark Mode. At Apple, when we begin a new design project, we like to establish a set of design principles to help guide us throughout the entire design process. And, with Dark Mode, there were three in particular that we referred to quite often throughout the entire process. The first one is the most straightforward, so let's just jump right into that one, and that is that dark interfaces are cool, period, right? They are almost effortlessly cool in a way that light interfaces sometimes kind of struggle to be. But why is that, really? Part of it is because we all have these notions of what a dark interface is and what a dark interface looks like. And a lot of that is fed into us by what we've seen in pop cultures in things such as sci-fi movies and action movies. So much so that if I were to go around the audience and ask everyone to give me one-word association of what a dark interface is to them, I'd get responses such as cool, of course; slick; professional; futuristic; and even beautiful.

    So going into the design for Dark Mode, we really wanted to acknowledge all of these aesthetic associations that we all have with dark interfaces, while at the same time embracing a lot of the real benefits that a dark design offers you, such as a higher contrast for typography. We realize that Dark Mode is really, really cool, and that a lot of you are going to want to adopt Dark Mode on your apps permanently. But, in actuality, only a small subset of apps really should be dark all the time, and those are things that are media-centric or content-creation apps. Those are the ones that are best suited to staying dark all the time, so if your app doesn't fall into one of those categories, it's better to let your app follow what the system appearance is, rather than to make it dark permanently. The second principle was that dark interfaces are not just inverted. And, really, what's at the core here is that when you look at a dark interface, it can sometimes be easy to think of just taking the light interface and inverting it to end up with your final result. But, in actuality, that can be very creatively limiting, and so it's better to take a look at your elements and your application on a case-by-case basis and try to determine what is the visual cue that they're trying to communicate and then figure out whether an opposite visual cue is necessary.

    So, if you take something, for example, like, a standard Light push button in the light appearance, the buttons look like this in their active state. And, then, when you click on them, the buttons darken. And this is generally true of almost all of the controls in the light appearance in that their click state is a darker version of what their active state was.

    In Dark Mode, however, the general active state looks like this, and when you click on them, they brighten, and that, again, is generally true of all of the controls. They will all generally brighten up. Another example are group boxes. In light appearance, the group boxes have a dark fill behind them and are shaded such along the edges to give them a recessed quality such that they look like they're carved into the window background that they're inside of.

    In Dark Mode, however, the group boxes are treated almost as if they are self-illuminated. But, at the end of the day, the general purpose of the group box is the same between the two modes in that what they're really trying to communicate to the user is that the contents contained therein are all related somehow.

    Why I said that it was important to go on a case-by-case basis and try and determine what the visual cue that your elements are trying to communicate-- It's important, is because, in some cases, the visual cue that's being communicated is already effective enough in the Light Mode and should be left as is in Dark Mode. An example of this are the window shadows.

    As we all know, macOS is a layered window environment, and the window shadows really help to communicate the sense of depth, the Z-depth of the windows. So, if we were to have inverted the window shadows, for example, and started using a white shadow, for example, the entire UI would have become flat. You would have lost that sense of depth. Another thing to note is that the window shadows in macOS are constructed of two layers. We've got the diffused shadow and the rim shadow. So, if we look at this little portion of the screen and look at how the shadows were constructed and treated in Dark Mode, the first thing to note is that, in taking into consideration that users are going to be able to go back and forth between light and dark appearance quite often and that some apps are going to stay dark all the time, it was important for us to keep the diffused shadow exactly the same. So, we used the exact same shadow blur parameters for the shadows in Dark Mode.

    Next, we took a look at the rim shadows and saw what changes we needed to do for those, and the changes that we did for Dark Mode where we adjusted the opacity to make them a little bit higher so that the contrast edge was more defined and that we made them a little bit crisper. To further the focus and the edge detail on the windows, we added an inner rim stroke to the windows to really help define the windows and pop them off. The end result is that the visual cue still looks very similar to the light appearance, but the end result has been finely tuned for dark appearance so that it works much better.

    The second principle was that Dark Mode is content focused, and this was the one that we referred back to the most often throughout the entire process, actually.

    When you look at a light interface screen, it can sometimes be a little difficult to tell what the content is, where to focus your attention to, especially when there are lots of windows on the screen.

    And part of the reason for that is because a lot of the content that we all create is just bright in general. However, in a dark UI, the content stands out because of the background being pretty dark. All of the window chrome in the background generally just melts away, and the content becomes the primary focus of your attention.

    Generally, we found that there were three methods for how to treat your content regions inside of your windows to optimize the content focus.

    The first method was to just generally go completely dark. An app like Finder is a great example of where this is possible because of the way that the content is displayed. Finder's content are displayed as colorful file icons and so the dark background really helps the icons stand out as much as possible. The second method was to leave the content as is. Pages is a great example of what you see is what you get app, where the contents should be rendered and presented exactly as the user authored and created it.

    Dark Mode is a great UI for what you see is what you get apps, because the content really becomes the primary focus, and the UI really becomes the secondary focus and almost melts away.

    The third method was to make the content region appearance a user option. Mail is a good example of an app where the appearance of the content might be ambiguous as to whether the user would prefer it to be light or dark, and so the best thing to do is to make an application setting so that the user can determine whether they want it to be light or dark on their own, while their application's chrome area still respects the overall system appearance. One thing that all three of these windows had in common was that the chrome remained dark and became secondary to the content area. And Dark Mode kind of achieves this using a feature that we call desktop tinting, which causes the window's background colors to camouflage themselves with the desktop picture. We found that completely desaturated gray colors have a tendency to have a color temperature that was sometimes in conflict with what your desktop picture was, and this effect was magnified when you have a translucent sidebar area, for example, against a solid opaque area of your window, and so desktop tinting helps mitigate that. Once applied, the desktop tinting gives the whole window a harmonious color scheme, which helps it to blend in with the surrounding areas and really reduces that color temperature disparity.

    So, how do we do the desktop tinting effect? The first thing that we do is, actually, we take a sample of the desktop portion that is behind the window, and then we derive a average color for that area, and then we blend that average color with a gray, which then becomes the window background color.

    This background color is dynamic, so as the user moves the window around the screen, the color will update itself so that the window always stays in sync with the wallpaper portion that was behind it. So, if we look at the effect in action across a couple of different wallpapers, you can see that the window is adjusting itself on the right side to match the desktop picture that is behind it.

    Not only does the window background color adjust itself to take advantage of the desktop color, but the controls also get a little bit of that going through them also due to the control's opacity.

    For users that work in color-sensitive applications or have very color-sensitive content or just generally would prefer not to have the desktop tinting apply to their UI, we offer the Graphite Mode so that they can disable the color tinting altogether. If we take a look at the color swatches for the window background colors, along the top there, we can see the window background color in the Light Mode, which is the standard light gray that we're all accustomed to. And, in the middle there, we've got the under page background color, which is a mid-tone gray, and then we've got the content background, which is the white background color that we're all familiar with behind all of our content areas.

    In the middle row, you can see how the desktop tinting affects these colors, and, then, along the bottom, you can see the effects of the graphite accent color disabling the desktop tinting effect.

    So, now that we've gone over some of the design principles, let's go into a little bit of the design considerations that you should take into account when updating your apps. First, let's talk about colors.

    For macOS 10.14, we added a lot of colors. We also removed a lot of colors, updated some, and, as you can see behind me, these are some of our system colors. Along the bottom, we've got the dark variance of the colors, and, as you can see, the dark versions are generally a little bit brighter and more saturated.

    Rachel and Taylor are going to a little bit deeper into the color usage during their portion of today's session, but, for now, I just generally want to try and cover three colors in particular, which are the blues.

    Going from left to right, we've got controlAccentColor, systemBlueColor, and linkColor. Linkcolor, as the name implies, is meant to be applied to links, text links in particular. So, things that are hyperlinks, taking of the user to a website, or a link within your application that navigates the user to another area of your application-- those should be treated with linkColor.

    ControlAccentColor and systemBlueColor are really meant to be used on controls that have visible borders or button bezel backgrounds or for tinted glyphs.

    ControlAccentColor, as the name implies, is going to respond to whatever the system accent color is set to, in this case, red. So, if you have a custom control that is trying to mimic the appearance of a standard system control, or you just have a control that you would like to follow suit with whatever the system appearance is set to, you should use controlAccentColor. If you have a control where it's important that the control stays blue because of informational purposes or for branding purposes, then systemBlueColor is a better choice for you to use.

    Next, let's take a look at designing with vibrancy.

    When we talk about vibrancy, what we're generally referring to is the package of a translucent material working in conjunction with the content that is displayed above it. So, in this case, the vibrancy is the vibrant Finder sidebar.

    Generally, we have non-colored artwork that is meant to be treated vibrantly. An example of that is the glyphs and the text in the Finder sidebar here. The end result of the vibrancy is is that the colors become higher saturation, and the contrast is increased for things like the text.

    Colored artwork, such as the finder tags in this example, should be treated as non-vibrant. Same thing with colored iconography. The vibrancy will destroy the original colors that you have in your image, and so you want to treat those as non-vibrant. So, taking a look at how you can construct vibrant content, it might seem almost obvious to just use opacities, in this case, opacities of white. But while it's true that some color contribution from the background is occurring through the materials here-- and that's happening because of the opacity-- the end result is actually not as highly saturated as we would desire. And, as you can see along the bottom with the Quaternary Label Color, the legibility is a little bit compromised.

    Instead, what you want to do is construct these using opaque grayscale colors. One thing to note here is that the text color for the RGB label colors here are full black. What's going to happen once the Blend Mode is applied is that the text that is black is going to become completely transparent. So, if you have areas of your content that need to be treated as a knockout, use full opaque black, and if you have areas that need to be gradiate towards an opacity, use a gray that is ramping itself towards a full black. This is true in Dark Mode, and the opposite is true in Light Mode, in light, vibrant areas, I should say, where white full, opaque white is full transparent and gradiating towards that is going to give you a transparency.

    So, once we apply the vibrancy, we can see that the gray colors become a lot more saturated, and the legibility of the Quaternary Color Label is a lot more improved. Putting them side by side, we can see just how much of a difference there is between the opacity construction, versus the grayscale construction. In some cases, over certain colors, the opacity construction will fly, but it's not exactly the best end result, aesthetically or legibility wise.

    Next, let's take a look at artistically inverting glyphs, and, by artistically inverting, what I'm referring to is the process of creatively looking at your glyphs and determining what areas need to be adjusted to take advantage of the Dark Mode, for example. So, here we've got a set of our standard glyphs that we have in the light appearance. One thing to note is that the light appearances glyphs generally use a lot of edge strokes with hollow centers. And the reason for that is that we take advantage of the white backgrounds that these are generally placed on top of in order to denote form and shape.

    But, if we were to take these exact same vector forms and place them over a dark background, all of that sense of form and volume is kind of lost, and so we had to artistically invert them to bring back some of that sense of form and volume.

    Looking at how some of these are constructed, we've got a couple of simple examples, like this finder tag. On the left side, it's denoting a white tag with a dark eyelet cutout. On the right side, however, in Dark Mode, that sense of it being a white sheet of paper is lost. So, once we invert it, we get back that white sheet of paper with an eyelet knockout hole.

    Looking at how this is constructed, generally, what you would do is expand the clipping paths, I should say, and then select your eyelet shape and then reverse the knockout on that. And then it's just a game of selecting any redundant vector paths and removing those. Taking a look at a slightly more complex shape, for example, the house. We've got a white house on the left side, and on the right side, the house isn't white anymore. So, inverting it returns us back to a white painted house.

    Generally, the construction for this is about the same as the other process, but one important aspect of this glyph, in particular, was that we have to add a new shape into the vector form. In this case, we're mimicking the roof line, creating a shadow underneath the roof that we're going to knock out. And this is important, because if we were to have left the construction of the house without that shadow line, the roof would have no definition, and it would be really hard to see that at small size.

    Moving on to a more complicated glyph, like this mail envelope, for example. On the left side, we can see a sense of volume and shape. We've got two layers, generally. We've got the back flap of the envelope, and we've got the front flap of the envelope with a letter contained in between. On the right side, a lot of that sense of volume is just missing because of the lack of fill colors.

    And so, once we invert that, we return back to having a sense of volume.

    Again, generally, the process of construction for this one is about the same as some of the other ones, but it's a little bit more detailed and time consuming just due to the number of paths that there are. But, generally, what you want to do is break it apart into two pieces, again, so that you have the front and the rear portion, and then you have your letter portion in between. One important detail that this glyph exemplifies is the dual opacities that we use in some of our glyphs. In this case, the letter is set to 80% opacity in order to make it secondary to the envelope, itself, being opened, which is what we're trying to communicate.

    And the opposite is true in Light Mode also, where we do use 80% opacities, in some cases, also.

    So, quickly wrapping up what we've covered so far.

    Dark interfaces are cool, so cool that you're probably going to want to make your app potentially dark all the time, but unless your app is a creative or media-centric app, you should reconsider that, and, instead make your app follow what the system appearance is set to, instead. Don't limit your app design to just inverting your existing light appearance, and, instead, take a look at what elements are in your app on a case-by-case basis, and try and determine what are the visual cues that are trying to be communicated by the controls, and then determine whether an opposite visual cue is necessary or not. Then take a look at what type of content your app produces or displays, and then use that as a guidance to determine what type of method to use for how to treat your content area-- whether to go fully dark, whether to make it stay as is, or whether to make it a user option via the app settings.

    Then, taking a look at colors, generally, you want to make sure that you're using the three colors that we went over, appropriately, if you have controls that are text controls, try using text link if it's applicable. If you have controls that you want to follow the system accent color appearance, set those to control accent color, and if you have a control that has to stay blue all the time, adopt system blue color. And then Taylor and Rachel are going to go into a lot more detail about color uses, so definitely pay attention to their section. When constructing your vibrancy areas, make sure that you're constructing them in a way that takes full advantage of the vibrant effect blending, so make sure that you're using grayscale colors that are opaque. And if you have areas that need to be knockouts or have opacities, ramp towards black in Dark Mode or ramp towards white in Light Mode.

    And then, lastly, make sure that the glyphs that you're using are artistically inverted in order to showcase the intent that the glyphs are trying to communicate to the user as effectively as possible.

    Finally, make sure to go to the Human Interface Guidelines to see more design guidance.

    And then as well as checking the design resources section, where, by the end of the month, we're going to be making available updated Photoshop, and sketch templates, and kits for you to use.

    And with that, I'd like to hand it off to Rachel to go over some details on how to adopt and support Dark Mode. Thanks Thank you, Raymond. Hello everybody. Let's take a moment just to thank Raymond and the rest of the design team for designing Dark Mode. Isn't it awesome? Now Taylor and I will take you through the engineering basics of adopting Dark Mode in macOS Mojave. A while back, Taylor and I were chatting, and we discovered that we were both huge fans of chameleons. And while we don't yet own our own pet chameleons, we thought we'd be prepared by writing an app called Chameleon Wrangler. We did this back in High Sierra, and so we thought, "Hey, let's update it for Mojave." The first thing we did was put our system in Dark Mode and launch our app from the dock. And it didn't really look too dark.

    In fact, it's exactly the same between light and dark.

    And you'll note throughout this portion of the talk that on the left, when we want to compare, we'll have the light on the left and the dark on the right, so you can compare them side by side. Can't actually run the system this way. It's just for show.

    So, what we needed to do was link against the 10.14 SDK and Xcode 10.

    We built and ran our app, and voila.

    It's a lot darker.

    Comparing with light, you can see a lot of things are different and darker, automatically, but there's still some things we'd like to fix up.

    So, we'll go into detail about some of the colors. There's a lot of colors.

    Let's take a look at this header area that's light green.

    We implemented this using a hardcoded color, where we specified our custom RGBA values.

    The problem with this approach is that it doesn't change between the different appearances. You're stuck with the same color no matter what the system preference setting is.

    Instead of doing it this way, we're going to take advantage of colors in asset catalogs.

    You've been able to do this since 10.13-- have colors in asset catalogs, but now you can specify colors for different appearances. So, we've added a dark version of our header color.

    Asset catalog colors have several advantages. You can give them meaningful names that describe where the color is used or how it is used, and those are often called semantic names. You can have multiple definitions of the color, as I showed you, with the light and dark versions and also for different color spaces-- sRGB versus P3. And it gives you a central location for defining all of your colors. That makes it easy to go in and tweak your colors without changing any code if needed. So, here's our color now in a asset catalog, and it's called headerColor, because it's the header color.

    And let's see how it looks now, using headerColor. Looks a lot better and dark with that dark green. But something becomes obvious, and that's the text. Chloe's name and age are hard to read now against the darker green.

    Things looked okay in light, but they don't look good in dark. Well, there, we were using black and dark gray, and those are static colors, also. Not exactly the same as hardcoded, because we're using available colors, but they don't change.

    So, instead of using asset catalogs this time, we're going to take advantage of dynamic system colors.

    NSColor has many dynamic colors available for you to use with definitions across the different appearances.

    And a special thing about NSColor is that the colors are resolved at draw time, which means that the actual RGBA values that are used depend on the circumstances at the time that the color is drawn. I'm going to go through some examples of dynamic system colors now.

    Starting with the label colors that Raymond talked about earlier, and I'm showing the dynamic colors on the top half and some corresponding static colors just using black in varying levels of opacity on the bottom half. And, as you can see, in the light appearance, everything looks fine. But over in dark, labelColor looks great still, but the black colors disappear against the dark background. Here's an example in the system in Mail of where labelColor and secondaryLabelColor are used.

    The more important text is given the labelColor, and the less important text is secondaryLabelColor. To find out which colors are dynamic, in the Interface Builder popup menu for colors, it'll show you the list, and they've done a really nice job of making those be the dynamic colors.

    So, now switching, once we know that, black color and dark gray to labelColor and secondaryLabelColor, this fixes our text, and it looks great in both light and dark.

    A little bit more about dynamic system colors.

    As Raymond showed you, there are a bunch of colorful system colors-- systemRed, systemYellow, systemGreen are just three examples. And they subtly change for the different appearances so that they look great in both places, as opposed to the static, plain red, yellow, green colors.

    Another special thing about using systemRed, etc., is that they will match other uses of systemRed throughout the OS as well as matching on iOS.

    So, it's great to stick to these kinds of colors when you have an informational content in your color. It needs to be red or yellow for a warning, for example.

    Raymond also talked about linkColor, systemBlue, and controlAccentColor, so I wanted to talk about that again.

    LinkColor and systemBlue are very similar but slightly different and use linkColor for actual links to webpages or for going someplace in your app, whereas systemBlue is used for standard actions in your application, or you might even use controlAccentColor if you want to match the system preference, in this case, purple.

    You may search through your application code and find all the places you're using color and fix it all up and then still end up with a situation like this, where, for some reason, even though your text switched color, there's something behind it that's still drawing wrong. And if you're stuck and can't figure out what to do, I suggest taking advantage of Xcode's View Debugger. I'm just going to cover this briefly here, and the advanced Dark Mode session will go into more detail about debugging tips and tricks.

    So, I can see that light view is actually my scroll view, and I had set in the interface builder to a custom gray color. That's why I couldn't find it searching through my code.

    So, I switched it to the default background color, and now everything looks great.

    And while we're here on this text view, I'd like to go through some of the colors in play here that are dynamic system colors that also may be useful to you. First, there's textColor, which is switching between black and white; textBackgroundColors switches from white to black; selectedTextColor goes from black to white; and then selectedTextBackgroundColor, which is blue. But you can see it's two different versions of blue, and this is special, because it follows the system preference for the highlight color. And you can see, when the highlight color changes, the selectedTextBackgroundColor changes with it. Now, I'd like to move along and talk about accessibility.

    In the Accessibility display preferences, there's the Increase contrast checkbox.

    If we turn on Increase contrast mode, you'll see that colors and artwork throughout the system change to make the UI easier to see for people to see with low vision.

    Well, now in asset catalogs, we can add colors specially for the high contrast appearances as well. So, here I've added to my header color a version for high contrast light and high contrast dark. And this is how Chameleon Wrangler now looks in the dark high contrast appearance. You'll notice that not only is my header color using that special color that I defined, the rest of the system colors are also specially defined for the high contrast appearances. And this is true for light high contrast, as well. Now I'd like to move along and talk about images.

    We'll take a look at the toolbar buttons here.

    This chameleon color picker button looks pretty good in light, but in dark, that dark outline disappears against the dark background of the button.

    So, we'd like to have a special version of it for the dark appearance, and, once again, we turn to our asset catalog friend and add a version for the dark appearance.

    And now it looks much better against the dark button with the light outline.

    That's great for full color images. How about these other two buttons? Well, they already look pretty good. We didn't have to do anything, so why? Why are these right? Well, that's because we had made these images template images. To tell you a little bit about template images, in case you don't already know about them, it's important to understand that the transparency of each pixel is maintained, but the color is ignored. You can make the starting image any color you like, that's ignored. It's only the transparency. They can be bitmaps or PDFs.

    And here's an example from the OS of the speaker volume image.

    The original image is black, and then it has this partially transparent section for the larger soundwaves.

    And if we put this image into an NSImageView, it's automatically given the Secondary Label Color, and you can see in light, it's a medium gray, and in dark, it's a lighter gray. And then the partially transparent areas have less contrast against the background.

    Another advantage of using template images is that they automatically pick up on the button state. When a button is disabled, the images are dimmer, and that's handled for you if you use template images.

    Okay. So, Chameleon Wrangler is now looking pretty good. We got our colors sorted out. We got some of our images sorted out, but there's more to the application than what you see here, so I'd like to invite Taylor to the stage to tell you about the rest of it.

    Thank you very much. Thank you Rachel.

    Now that Rachel's covered a lot of the fundamentals of having our colors and images react appropriately for Dark Mode, let's first take a look at applying some of those to some more detailed areas of our application. First up is Moodometer, where we can keep track of Chloe's mood shifts throughout the day.

    You can see here that the popover's background has automatically adjusted for the Dark Mode. However, the button content is way too dark, still, on top of the background.

    Taking a look at our Asa Catalog, we can see that we've prebuilt these images with the color defined in the asset themself. So, we can use the technique that Rachel showed us, where we add a dark variant for those images with a lighter color.

    However, it's kind of unfortunate that we're only varying the fill color of these images but keeping the same shape. So, there's probably a better way, and, in Mojave, there is, using this contentTintColor API.

    With this, you can create a template image and provide a custom tint color to be used instead of the default appearance sensitive one. That will be used as the base fill color for any of the places that the image appears. So, we can set the content tint color on an NSImageView to tint its image or on an NSButton to tint both its boot image and title.

    So, let's take a look at adopting this. The first step here is to convert these to simple template images and remember to set the render mode to be the template effect.

    Taking a look at Chameleon Wrangler now, we can see that these images are now getting the default templating effect, which looks great in Dark Mode, but the next step is going to be applying that color. So, we could just pull the color out of the asset, add a dark variant, and set the contentTintColor on these buttons to be that named color. And this button will automatically pick the right variant based on whether it's appearing in the light appearance or dark appearance. However, Rachel also showed us how there are a number of colorful system colors that already have these light and dark variants, which we could use instead. For instance, we could use systemRed, systemYellow, and systemGreen, which, if we return back to Chameleon Wrangler, we can see looks really great and has those buttons pop on top of that background.

    What's really cool about this combination is that not only do we get a very specific green color for both Light and Dark Mode, but with the content tint API, the system effects applied on top of that vary based on appearance as well.

    As Raymond discussed, in the light appearance, there's a darkening effect on top of that base tint color. Meanwhile, in the dark appearance, there's a brightening effect.

    All of these effects are further customized for the increased contrast setting without any changes from our application. So, it's really great that we didn't have to specify all 12 of these colors. And instead, we specified a single one and, thanks to dynamic system colors and dynamic system effects, we got all of this completely automatically.

    So, our Moodometer is looking great. Next, we can step over to another type of app where we keep track of very important information about Chloe, such as how stressed she's feeling or more importantly, what's her favorite type of berry? We can see here that this already looks great, because we are using stock Cocoa controls, which automatically adjust for Dark Mode.

    We can see how it reacts to the accent color feature that Raymond talked about by opening up system preferences, changing the color to a nice chameleon striped yellow, and returning back to Chameleon Wrangler.

    We can, again, see that the built-in controls automatically adjust to that yellow accent color, including the focus ring and highlight color.

    However, we can notice that our custom tab bar has remained blue, even though we've changed the accent color.

    Because this blue doesn't really have any significance for our application, we probably want it to be following that accent color. Like Rachel talked about, we have a few different colors that will follow the users' accent and highlight color selection.

    New in Mojave is a control accent color, which you can use to directly mimic the accented areas on system controls, such as the sides of popup buttons, default push buttons, or the selected segment of a segmented control.

    There's also selected content background color, which is what you see in the background of selected table rows, and you can use to indicate custom selection.

    And selected text background color is exactly what it sounds like. So, going back to our app, we can see that we're using system blue color for this custom tab selection, and, instead, we can just swap that over to using controlAccentColor.

    The next problem here with the tab bar is a little more subtle.

    If we bring our cursor over and press down on it, we can see that we're getting a darkening effect instead of the brightening effect that we should in Dark Mode.

    This is because we are taking that base color and just applying a constant 30% darkening effect to it, assuming that would look fine in the light appearance.

    Instead, we want to describe something that basically this color is being pressed, and that semantic description can carry whatever effect it needs to in the light versus dark appearance. So, with the new system effect API in Mojave on NSColor, we can describe that exact semantic.

    We can take our base color of controlAccentColor, say that we want to get the pressed variant, and it will react appropriately in both the light and dark appearance.

    There's one more area of our application where you can see the accent color, and that's in this photo browser where we draw a selection ring around the selected photo. Here, we were using the selectedContentBackgroundColor, and that, again, automatically adjusts based on the user's selected accent.

    Let's open up one of these photos and take a look at a nice, big, beautiful photo of Chloe. The first thing that stands out is the fact that the background has not adjusted for Dark Mode. It's still using its light translucency effect similar to a hardcoded color.

    This effect is provided by NSVisualEfffectView, which provides the translucent blur materials you see across the system. For instance, there's the sidebars which blur onto the desktop and other windows behind it, as well as things like the title bar, which blur the content that's scrolled underneath.

    NSVisualEffectView also enables the vibrant foreground blending, that Raymond talked about, by taking a grayscale color plus a Blend Mode and making it really pop on top of these backgrounds.

    The advanced Dark Mode talk is going to go into a lot more detail about how you can use those blend modes effectively.

    Turns out that a lot of places automatically get these blur materials for free. For instance, every titlebar of an NSWindow will automatically have a titlebar material showing onto the content behind it. Source list table views and sidebar style split-view items will automatically get a sidebar material showing onto the content behind the window. For custom UIs it's pretty easy to build these custom effects ourselves, as well. But the most important quality of them are the material that you choose to have them represent.

    We have a few nonsemantic materials, which, like hardcoded colors, just describe the exact visual quality of the material and not the intent of what you're trying to represent.

    These will not be adjusted for Dark Mode and will stay with that exact quality.

    However, we have a number of semantic materials, as well, which allow you to describe what type of UI your custom UI is intending to represent. For instance, for a custom menu like UI, you would want to use the menu material. And these not only adjust for Dark Mode, but guarantee that UI to always match those materials even when the system changes in the future.

    We've had a few of these in the past, but in Mojave, we have several more so that you can make sure to really tailor your custom UI to match the material it needs to. Jumping back to our photo here, we can see that we were using the mediumLight material, because we were trying to represent Quick Look style popover windows. And instead, we can just simply swap that over to the popover material and get the exact effect we want to in Dark Mode. Now, this isn't the only area where we get a unique material showing in the background of our UI. Like Raymond talked about, there's this desktop tinting effect that's shown here in the background of our photo gallery. We're getting a little bit of that blue from that desktop behind it, creating this really visually harmonious result.

    It's a lot easier to see on top of a more vibrant background, such as these beautiful flower pictures.

    There's three different variants that have semantics with these background materials. There's the window backgrounds that we see on the backgrounds of generic windows; Under Page Background, which appears behind document areas such as in Preview or Keynote. And perhaps most commonly is the Content Background material, which is white in light appearance and, of course, dark in the dark appearance.

    In fact, all of these are now dark in the dark appearance but also have that wallpaper tinting effect. The great news is that it's really not hard to get these effects. For the most part, it comes completely automatically by using system views. For instance, the default backgrounds of every window has that window background material built right in.

    In addition, views such as NSCollectionView or NSTableView also automatically come with the content background material built right in.

    We've seen a number of places across this system that were actually able to improve their Dark Mode support by deleting an override of these default colors that these views have.

    If you want to customize beyond the default color that these views have, you can explicitly set a variety of system colors as their background color to get the exact material effect you want.

    One really important note here, though, is that if you were to read the RGB values of these colors, they would not include the desktop tint.

    This is because, as Raymond mentioned, this tint is extremely dynamic. As you move your window around on screen, that's getting updated asynchronously to the applications rendering itself, creating a really nice experience as the user is moving around windows.

    So, jumping back to Chameleon Wrangler, we automatically got this content background because we just use a stock NSCollectionView.

    In the vital section, we got that window background material showing through because we had nothing opaque covering it up.

    However, in our notes section, where we have this awesome custom stationary, we have a light grey background that isn't appropriate for Dark Mode and hasn't been adjusted with that under page semantic. We can open up Interface Builder and see where we're setting up this background drawing view and see that, indeed, we are filing it with a custom gray color.

    And pretty quickly in IB, we can change that to using the Under Page Background color that represents that semantic and immediately see that we'll get the right result, making it look just at home with the rest of the document apps in Dark Mode. The next thing that kind of stands out here, though, is the dark foreground on top of light background of our stationary and document area. And because this is a WYSIWYG editor where we, as users of Chameleon Wrangler have complete control over the colors, images, and fonts seen within it, we expect this to stay the same as a light appearing document.

    However, there are a few subtle details that don't seem quite right. For instance, the text highlight color is still getting the dark variant of the text highlights, as well as the autocorrect bubbles have the dark appearance, which really clashes with the light appearance of our document.

    We, basically, want to have everything in this area revert back to the light appearance, and we can do that using NSAppearance. It turns out that NSAppearance is what's been providing the magic of having light versus dark variance automatically switch in Dark Mode this whole time.

    You can conceptualize NSAppearance as a little bundle containing all of the colors, materials, images, and control artwork that you see across the system. Now, when your application does something like request to draw with labelColor, what that does is it looks up in the current appearance for what the exact RGB values should be.

    The same is true for control artwork or the different material effects. Now, what's new in Mojave is the dark appearance, which our designers have meticulously crafted with redefining everything across the system.

    When the system is running in Dark Mode, what happens is that the dark appearance gets applied to your application instead of the light appearance. So, when labelColor goes to draw itself, it references the dark appearance as white value instead of the light appearance as darker value.

    The same is true for all of those materials. And these aren't the only materials in the system. Right, these aren't the only appearances in the system. There are also the high contrast appearances, which get used when the accessibility high contrast setting is turned on, these will get applied to your application instead. And there's actually even more. There are the vibrant appearances that, again, completely redefine all of these colors that appear in sidebars and titlebars. And the advanced Dark Mode talk is going to go into more detail about how you can effectively use the assets that come out of those vibrant appearances to really make them stand out.

    Now, by default, the appearance of your application will follow the system. However, you can explicitly override it by setting the appearance property to whatever you want. So, here we have Chameleon Wrangler in Light and Dark Mode, and we can see it's following the system, but as soon as we set its appearance to always be darkAqua, we can see it's always getting that dark appearance.

    The inverse is true by setting the explicitly light appearance, and, of course, setting it back to nil will have it return back to the default behavior of following the system.

    Now, we know that after a lot of you see your apps running in Dark Mode, you're going to be really tempted to have your app always be dark, because it's just going to look so good.

    But like Raymond mentioned, it's really important to keep in mind "When it is appropriate to have an always dark app?" This should be generally reserved for very media focused apps like QuickTime player or professional color-sensitive workflow apps, where it's important to eliminate all of the light behind the content.

    And, in general, it should be left up to a choice for the user.

    So, in general, this is the system preference. Some of you maybe already have a dark theme for your application controlled via app preference, so your first step would be to tie that back to the system preference so the people using the system can have a consistent experience. And in some ambiguous cases like Raymond mentioned, there may be some additional need for an in-app preference, such as in the mail case, but for the most part, the system preference should be exactly what users go for. If you do decide you need to have an always dark application, it's really important to not to use the Vibrant Dark appearance on the entire window, because that's not appropriate for the opaque window areas of the application and are really only intended for sidebars.

    Instead, you want to use the Dark Aqua appearance if you want to have that always dark look.

    In addition to be able to be set on the window as a whole, you can also set it on an individual window or view scoping, and that's inherited by all of the views contained within it. For instance, here, we're setting the sidebar to always have the darkAqua appearance if we want to experiment with something like that. And all of the text and images within that also get that dark styling, but we can also use this to fix the problem we had before with our text area.

    We can see here that we actually want this entire document area to remain having a light appearance, and so by setting the lightAqua appearance, we can make sure that the text highlighting color gets the correct appearance as well as the autocorrect bubble inheriting that light appearance as well.

    However, in addition to be able to be used for some really cool effects, it can also lead to some hard-to-debug situations. For instance, here, we're using the vibrantLight appearance explicitly on our table view, and that looks perfectly fine in the light appearance, where it's actually already inheriting the vibrantLight appearance. In Dark Mode, this quickly becomes a very visible problem. We can see that the text and images inside that table view are now inheriting that vibrantLight appearance and look bad on top of that dark background. So, for the most part, we just want to remove these explicit overrides in places where we really do not intend to have an always light appearance.

    This can also happen in Interface Builder, where, at the very bottom of the Attributes Inspector, we've accidentally overridden the appearance for our outline view to always be the light Aqua appearance. Here, the fix is simply to change it back to the inherited style so that it can make sure to follow Dark Mode when that's turned on, so do be sure to check for all of those.

    At this point, Chameleon Wrangler's looking really great in Dark Mode.

    But kind of an understated thing here is that, at this point, we've written 0 lines of code specific to Dark Mode.

    The types of changes necessary for being a great Dark Mode citizen is that you need to make sure to express the ideas semantically rather than literally. So, for instance, these same sets of changes allowed our application to not only look great in Dark Mode but also in the light appearance. Adding support for things like the accent color as well as making our label colors more consistent with the rest of the system.

    Further, these same sets of changes needed to be great in Dark Mode are also the same sets of changes needed to have great support for the high contrast accessibility setting. So, to reiterate what those steps were, the first and foremost was linking on the 10.14 SDK using Xcode 10. For a handful of apps that already use system controls and system colors, this is the only step that's going to be needed, and it's already going to look great in Dark Mode. For the rest of us, the next step is to audit our app for the use of static colors, non-template images, and nonsemantic materials, and replace those as appropriate. For instance, this might be using a system color, a semantic material, or, in some cases, defining a custom asset catalog color or image. And, again, it's important to keep an eye out for those accidental appearance overrides.

    The advanced Dark Mode talk is going to go into a lot more detail here, including how to correctly use NSAppearance, how to do custom drawing and effects within NSVisualEffectView, how to make sure all of the myriad of ways you might be drawing custom views work correctly in Dark Mode. Some tips and tricks for using View Debugger and Interface Builder to really polish your app. And because we know that a lot of you and your apps' fans are really going to be wanting to have Dark Mode as soon as possible, we want to make sure you can do that without sacrificing how far you can back deploy. So, in general, a lot of these features are available for a year or more, but the advanced talk is going to go into details about how to take that even further back. We have a few Cocoa Labs, but I also really want to point out the Dark Mode Lab, where, in addition to engineering support, Raymond and other members of the design team will be there to help answer any design questions you might have, as well. So, that's a really special treat that I encourage you to take a look at. Thanks for staying until 6:00 today, and have a great rest of the WWDC.

    [ Applause ]

  • Looking for something specific? Enter a topic above and jump straight to the good stuff.

    An error occurred when submitting your query. Please check your Internet connection and try again.

Developer Footer

  • Videos
  • WWDC18
  • Introducing Dark Mode
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playgrounds
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Extensions
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Curriculum
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Events Overview
    • App Accelerators
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • Entrepreneur Camp
    • Ask Apple
    • Tech Talks
    • WWDC
    To view the latest developer news, visit News and Updates.
    Copyright © 2023 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines