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 Answers
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.
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.
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>
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)
}
}
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%);
}
}