19
votes

I was working for iOS 13 with Xcode 11 beta. Is there any way to support dark mode on web views? I have created a color set for all the other views except WKWebviews. How to change web view background and text color for dark mode?

5
Be more specific. What do you need to have happen with your web view between light and dark mode? Edit your question with details (don't reply in a comment).rmaddy

5 Answers

45
votes

Assuming your question is asking how to change the colors of the HTML content you are displaying in a WKWebView based on whether light or dark mode is in effect, there is nothing you do in your app's code. All changes need to be in the CSS being used by your HTML content.

I have some local HTML files I use in a WKWebView. I was able to support dark mode by updating my css file.

Let's say you currently have a css file with the following:

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

a:link {
    color: #0078b5;
    text-decoration: none;
}

Those are fine in light mode. To also support dark mode, you can add an @media section to your css:

@media (prefers-color-scheme: dark) {
    body {
        background-color: rgb(38,38,41);
        color: white;
    }
    a:link {
        color: #0096e2;
    }
    a:visited {
        color: #9d57df;
    }
}

When in dark mode, the colors in this @media section will override the corresponding colors defined outside the @media section.

5
votes

Same challenge I faced when I was migrating my iOS app because we do login using WKWebView and when I consulted I found below example to handle this situation. Just need to create variable for the color and need to handle this in CSS.

Before

body { color: black; }
h1 { color: white; }
.header {
    background-color: #FFFFFF;
    color: white;
}

After

:root {
    color-scheme: light dark;
        --h1-color: #333;
        --header-bg-clr: #FFF1FF;
        --header-txt-clr: white;
    }
    @media (prefers-color-scheme: dark) {
    :root {
        color-scheme: light dark;
        --h1-color: #333;
        --header-bg-clr: #FFF1FF;
        --header-txt-clr: white;
        }
    }

body { }
h1 { color: var(--h1-color); }
.header {
    background-color: var (--header-bg-clr);
    color: var(--header-txt-clr);
}

After Integrating this change you can use Safari to test (First you need to enable the developer menu option in Sarafi, Preferences, Advanced). Open wen inspector (using Command + Options + I) and you will see this screen with the option to toggle light/dark mode.

enter image description here

NOTE Just to add little more information. You can also handle different images just like colors.

BEFORE

<img src="day.jpg">

AFTER

<picture>
<source srcset="light.jpg" media="(prefers-color-scheme: light)">
<img src="day.jpg">
</picture>
4
votes

Swift 5

For WKWebView, below code worked for me.

extension RichTextController : WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let cssString = "@media (prefers-color-scheme: dark) {body {color: white;}a:link {color: #0096e2;}a:visited {color: #9d57df;}}"
        let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
        webView.evaluateJavaScript(jsString, completionHandler: nil)
    }
}
2
votes

More simple, just invert all colors & style except for images :

@media (prefers-color-scheme: dark) {
    html{
        filter: invert(1)  hue-rotate(.5turn);
    }
    img {
        filter: invert(1)  hue-rotate(.5turn);
    }
}
1
votes

Root tag will invert all the components color except the table and images will be in negative form.

To perform perfect color invert check the below CSS file

   @media (prefers-color-scheme: dark) {
     /* root tag inverting all the components color except the table.*/
     : root {
            color-scheme: light dark;
        filter: invert(100%);
       -webkit-filter: invert(100%)
     }
    /*table tag needed for inverting table content.*/
    table {
            filter: invert(100%);
     }
    /* If We do color invert in : root , images will be color inverted and it will be in negative. If we invert again these negative images, it will be positive.*/
     img {
         filter: invert(100%);
     }
    }