Dark Mode for Welcome Messages (Not Available in current versions of iOS)

Dark Mode In Welcome Messages

Disclaimer:

This apparently does not work in current versions of iOS, it may be supported in please check back later for updates.

Introductory Notes

After being implemented in macOS Mojave, many browsers have gained support for Dark Mode. Dark Mode is now a feature in iOS/iPadOS 13. This thread discusses how you can change the style of your welcome message based on whether the user has Dark Mode enabled or not.

Two welcome messages

TWO IMPORTANT NOTES:

  1. We will be using the CSS prefers-color-scheme media feature to style the page depending on the user’s preference. At the time of this post, this media query is still considered an ‘experimental’ technology; the functionality could potentially change in the future.

For further documentation on styling pages with the prefers-color-scheme media feature, I find the Mozilla Developer Network to be helpful.

  1. I highly advise you not to use the <font> tag when making your welcome message compatible with Dark Mode. Some examples of why are shown later.

Required Knowledge

Section 1 (CSS Styling):

  • Fundamental CSS syntax knowledge such as:
    • CSS Properties
    • CSS Selectors
  • Fundamental HTML syntax knowledge such as:
    • Basics of HTML tags
    • HTML/CSS IDs and Classes
  • CSS Media Queries (Optional)

Section 2 (Images)

  • CSS Media Queries
  • The prefers-color-scheme media feature

Section 3 (Programmatic Styling)

  • Fundamental JavaScript knowledge
  • CSS Media Queries
  • The prefers-color-scheme media feature

If you want to learn more, W3Schools has a tutorials on most of the above.

If you don’t know anything about CSS media rules, you can familiarize yourself with them at W3Schools. You can keep reading without any knowledge of media rules, but knowing how they work will help.

CSS Styling

We are going to use the @media rule and the prefers-color-scheme media feature, this is how it looks:

@media (prefers-color-scheme: dark) {
   /*CSS RULES GO HERE*/
}

Media Feature Values

The media feature prefers-color-scheme, has 3 different values:

  • dark
  • light
  • no-preference

dark

Applies CSS rules when the user has Dark Mode enabled.

light

Applies CSS rules when the user is in Light Mode. This is useful if your welcome message is dark by default, and you want to have a lighter theme. You can also use this if you want the generic page style, which is applied if the user’s device doesn’t support Dark Mode, to look different than when the user has Light Mode enabled (this isn’t as confusing as it may sound).

no-preference

Applies CSS rules when the user has no preference set. I have not found this value to be useful at all.

Placement

You must place all your CSS, including media rules, inside opening and closing <style> tags. You may notice that I do not put the style tag in every example. The tag is still required when putting it into your welcome messages, but I have left them out to focus more attention on the actual CSS.

Examples

Correct:

<style>
@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}
</style>

Incorrect:
There is no closing style tag. Not closing a style tag can break a welcome message.

<style>
@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}

Incorrect:
The closing style tag is missing the /.

<style>
@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}
<style>

Incorrect:
The closing tag has the / in the wrong place.

<style>
@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}
<style/>

The browser engine reads CSS from top to bottom. This means that the CSS rules you put closer to the bottom take priority over rules that you create above it. You should put all your media queries at the bottom below all your other CSS rules or it will not work.

Examples

Correct:

body {
   background-color: white;
   color: black;
}

@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}

Incorrect:
The media rule is above the body rule. The body rule will take priority since it is closer to the bottom.


@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}

body {
   background-color: white;
   color: black;
}

Incorrect:
The prefers-color-scheme: dark media rule is above the body rule. The body rule and prefers-color-scheme: light will take priority since it is closer to the bottom.


@media (prefers-color-scheme: dark) {
   body {
      background-color: black;
      color: white;
   }
}

body {
   background-color: white;
   color: black;
}

@media (prefers-color-scheme: light) {
   body {
      background-color: black;
      color: white;
   }
}

Implementation

When you want to change the style of something in your welcome message, you (hopefully) use CSS to do it. To use Dark Mode on your welcome message, you put at least two sets of rules. One for the default style, and one for the darker style. If your welcome message is already dark and you want a lighter theme, you can implement it the same way you usually would, except using the 'light' media feature value instead.


/* Default content style rules go here. If there is a 
   'prefers-color-scheme: light' media query, the rules here are applied to devices that do not support Dark Mode. 
*/

@media (prefers-color-scheme: dark) {
   /* Dark theme content style rules go here. */
}

@media (prefers-color-scheme: light) {
   /* Light theme content style rules go here. 
     (If you only want dark and light style, this media rule is optional.) */
}

Everything you can normally style with CSS, you can style for Dark Mode inside the media rules.

Issues With Using the <font> Tag

Many people like using the font tag over CSS is because it is “easier.” While there are several reasons it is more tedious than using CSS, it becomes more apparent when you have to use CSS. You cannot style your welcome message for Dark Mode without using CSS, and if you try to use the font tag with it, you can create a conflict and get unexpected results. You should get rid of the font tag and start using up-to-date practices instead to avoid issues.


Images

Media Queries For Pictures

To display an image on your welcome message, you have to specify the source URL of the image using the src attribute.

<img src="https://example.com/images/img.png" />

Some images are very bright and could be replaced with darker images when the user has Dark Mode enabled. We can do this with two HTML tags: <source> and <picture>.

The source tag specifies an alternative source URL and uses it when a media query matches it; this is how it looks:

<picture>
   <source srcset="https://example.com/imgDark.jpg" media="(prefers-color-scheme: dark)" />
   <img src="https://example.com/img.jpg" />
</picture>

The source tag uses two attributes; srcset and media.

srcset

The image URL that will change whenever the media query matches.

media

The media query that must match before it uses specified URL. Do not put the @media rule or {} inside the media attribute. Put only the media query. You can use the media queries the same way you did in CSS.

Examples

Correct:

media="(prefers-color-scheme: dark)"

Incorrect:

media="@media(prefers-color-scheme: dark)"

Placement

The <img> (image) tag must go under all <source> (source) tags, or it will not work correctly. The order of where the source tags are placed shouldn’t make a difference in this case as long as they are above the image tag and inside the opening and closing <picture> (picture) tags.

​___

Programatic Styling

You can use JavaScript to programmatically change the style and content of a welcome message based on whether the user is in Dark Mode, Light Mode or doesn’t support either one. In this section, we are going to be using the matchMedia() method of the window object. We will also use the addListener() method to change the welcome message dynamically.

First, we need to create a JavaScript constant to hold the media query. While the example uses the value 'dark' here, you can also use 'light'.

const colorSchemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

We then need to use some if-else statements to tell whether the window matches the media query we specified.

const colorSchemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
 
if (colorSchemeDarkMediaQuery.matches == true) {
 /* Run code here if our media query is true. 
      If we set the media query value to dark, the 
             code here changes it to dark */
} else {
 /* Change the [page] if our media query is false. 
     If we set the media query value to dark, the code here changes it to the default. */
}
 

If we want a dark, light, and separate default theme for unsupported browsers, we can add a light media query.

const colorSchemeDarkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const colorSchemeLigjtMediaQuery = window.matchMedia('(prefers-color-scheme: light)');

if (colorSchemeDarkMediaQuery.matches == true) {
 /* Run code here if our media query is true. 
      If we set the media query value to dark, the 
             code here changes it to dark */
} else if (colorSchemeLightMediaQuery.matches == true) {
 /* Change the welcome message if our media query is false. 
             If we set the media query value to dark, the 
         code here changes it to the default. */
} else {
 /* Change the [page] if our media query is false. 
             If we set the media query value to dark, the code here changes it to the default. */
}

Dynamic Change

We want JavaScript to change the welcome message to the preference the user has set, not just when it loads, but also when the user changes the preference. For example, if the user opens the control center and changes the preference to dark, they expect the welcome message to change accordingly.

We need to make a function that runs when the event listener calls it. To do this, we put our if statements inside the function.

const colorSchemeDarkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

function colorSchemeChanged() {
   /* Code goes here */
}
// Calls the function when the welcome message first loads
colorSchemeChanged()
// Calls the function when the user changes their preference
colorSchemeDarkMediaQuery.addListener(colorSchemeChanged());

The event listener only listens for media changes in the window; it will not change the content when the welcome message is first loaded. It is important to call the function just after you declare it.

You can also add an event listener to the colorSchemeLightMediaQuery constant instead but you SHOULD NOT run both event listeners at once. Running both at the same time can cause unusual behavior such as false positives. Please use one event listener or the other to avoid issues.

WM Framework

@Wingysam has created a framework to help players more easily create their welcome messages. While this is a nice tool, there is currently no good way to implement Dark Mode styles while using it.

Copy and Paste Backgrounds

(Such as GlitterGraphics and Fillster)

Many players use these backgrounds on their welcome messages, and they can also be used in Dark Mode.

GlitterGraphics and Filster put TONS of junk CSS that you do not need in your welcome message. The only thing you really need is the background image. You will need to hunt through the code and find it. It should look like one of two things:
background:url(http://www.example.com/images/backgrounds/filsterImg.gif);
or
background-image: url('http://example.com/pub/glitterGraphicsImg.jpg');

After you have the URL of the image you want to display in a Light Mode or default, and the URL of the image you want to display in Dark Mode, you will need to put them inside the body rule in CSS. You will also need to add this property: background-repeat: repeat;.

Note that if you don’t want a background if the user is in Dark Mode but you do in Light Mode or default, or vice-versa, you can set the background-image property to none instead of the URL.

body {
/* The default background image */
   background-image: url('http://dl3.glitter-graphics.net/pub/945/945722nnr1azx3a7.jpg');
   background-repeat: repeat;
}

@media (prefers-color-scheme: dark) {

   body {
      /* The darker background image */
      background-image: url('http://dl3.glitter-graphics.net/pub/945/945722nnr1azx3a7.jpg');
      background-repeat: repeat;
   }

}

Last Updated: 6:22PM 09/19/2019 (UTC)

6 Likes

You should probably update to iOS 13 first and then test it. :wink:

I plan too, but currently holding out because I have heard the transition might not be quite as smooth this year as usual for some apps I use. WebKit should work the same on iOS as it does on MacOS. I assume welcome messages will use whatever the latest version of WebKit is avalible. If anyone finds these examples don’t work, please let me know.

I’m gonna update while I sleep I need a dark mode definitely

I’ve tested this on iOS 13, and, unfortunately, it shows light even when set to dark :frowning:

<div id="custom-top">
  <style>
    @media (prefers-color-scheme: dark) {
      /* Dark theme content style rules go here. */
      .light {
        display: none;
      }
    }
    
    @media (prefers-color-scheme: light) {
       /* Light theme content style rules go here. 
         (If you only want dark and light style, this media rule is optional.) */
      .dark {
        display: none;
      }
    }
  </style>
  <div>
    <span class="light">theme: light</span>
    <span class="dark">theme: dark</span>
  </div>
</div>

I see theme: light but not theme: dark :frowning:

Hopefully Apple will fix this soon.

Edit: I’ve tested this with Discord. The in-app browser shows light, but when I tap the Safari icon, it shows dark.

1 Like

What do you mean?

So you’re saying that it only works in Safari right now? I think the macOS App Store had an issue like this that was eventually fixed, we will keep waiting and see if anything changes.

Edit: I have confirmed this works in MacOS Safari.

1 Like

It’s just going to fix itself?

When macOS Mojave was first released, the accounts of the App Store was just a webpage that showed up inside the app. The theme was white when it should have been dark, I am thinking something similar may be haplening here. If so, it might be fixed in a future update.

If it doesn’t work by iOS 13.1, I will get rid of this thread.


Also, if someone has an Android device, I would appreciate if they could give me feedback of what happens on their system. :slight_smile:

Do you mean iOS 13.1? If so, that means by September 24th?

Yes, sorry. I meant iOS 13.1 :laughing: I keep getting so confused. It still feels like iOS 12 just came out…

This is correct.

No! Don’t! It’ll probably be fixed later, just put a notice at the top that it doesn’t work yet.

1 Like

Does it work with iOS 13.1.2? Does it work with iPadOS 13.1.2?

Not for me :confused: I am on 13.1.2

iOS 13.1.2 or iPadOS 13.1.2?

Both.

iPadOS is just fork of iOS.

Oh, strange…

Would someone else be willing to test this out?

1 Like

The code works on safari.

If I’m provided with a link to a site that supports day and night themes I will. I have my iOS13 tablet on auto.

Mac rumors