How do I stop dark mode from destroying my css - css

I have a website with css styling. When I view in certain browsers when dark mode is enabled the css is absolutely destroyed and the colours which have changed in my site look absolutely hideous. How can I prevent my css/colourschemes being changed because of dark mode?
When I opened my url via a link sent on whatsapp on my android device the default browser - Android's 'internet' application automatically restyles the CSS because I have dark mode active. If other users go to my page and have dark mode active I would prefer them to see the original styling not the dark mode edited version.
I found out that you can use this media query to set css for dark mode: #media (prefers-color-scheme: dark) {. I could duplicate my whole css file which is currently 3000 lines long with dark and light with the same code between the parentheses but this seems nonsensical. Is there any other methods which would work?

As it turns out, Samsung Internet — the default web browser for a very large number of devices and the one featured in your screenshot — silently applies a filter that transforms colors on websites in a non-trivial way when the user enables dark mode on their device. See this blog post for more information.
The gist of it is that, as of Samsung Internet version 13.0.1.64, this filter is undetectable with javascript or CSS.
The only thing you can do as a web developer is to warn users and urge them to switch to a better browser:
<script>
if (navigator.userAgent.match(/samsung/i)) {
alert("Your browser (Samsung Internet) may not show this website" +
"correctly. Please consider using a standards-compliant" +
"browser instead. \n\n" +
"We recommend Firefox, Microsoft Edge, or Google Chrome.");
}
</script>

Had the same issue. Here's what I found.
I added this meta tag to the header tag:
<meta name="color-scheme" content="light only">
The meta tag above indicates that the color scheme is only supported by light mode.
Another option is the scheme preferred in light mode, but it supports dark mode as well:
<meta name="color-scheme" content="light dark">
Tested on Safari, Chrome, Samsung, Facebook in-app browser and Firefox.
Another method is to use CSS:
:root {
color-scheme: light only;
}
The above indicates that the styling only uses the light version only.

If I understood, you want users to see the so-called light version even if their browser is set to prefer the dark one. What I’m going to suggest is far from being perfect… I mean, I wouldn’t do so, but I think it should work. Simply copy and paste the CSS you wrote under a #media (prefers-color-scheme: dark) query and manually change what doesn’t work there, without changing the code outside its brackets. Users should see the original, light version of your website no matter what they selected in their browser setting. TBH, I don’t know why you want to do this: the ideal approach IMHO would be to provide both a light and a dark theme with a default fallback.

I did some testing and the solution I found is using the !important declaration after the property value that you want to have when browser darkmode is on.
Think about this though, if you are using browser darkmode and go on a website and it stays the same as the lightmode, how would you feel? Personally I get really pissed and leave immediately from a website like that. So I would actually recommend not changing the colors. Users want darkmode for a reason, probably because they don't want bright colourful things hurting their eyes. If they want to use browser darkmode, they understand what will happen to the colors of websites.
The only use case I can see for changing things would be if elements disappear because of darkmode.
That being said, if your elements are disappearing because of this darkmode, look into the root cause first. Understand why they are changing before slapping !important on everything. That is lazy and does not look good on you as a developer.

Before You do all that, please check if you did not do the mistake, that I did -
We're talking here about forced dark theme on mobile, that You think your browser, most probably Chrome, is forcing on every website making it's background black and text white.
What I had was a manually set chrome flag for forcing dark mode.
Go to Chrome and type address chrome://flags then search for "dark"
You'll find "Force Dark Mode for Web Contents" flag. If it's not already - set if to "default".
Hope it saves some time anybody, I've wasted 1h over this.

You will face this issue in Samsung internet browser only. if the user has enabled dark mode In "Samsung internet browser(mobile)", the browser automatically changes the css of website to suit to dark mode. no matter if you applied the same css you applied for light mode/default within #media (prefers-color-scheme: dark){}
So if you want to make your website look better in Samsung internet browser, you can detect the samsung browser using this javascript line navigator.userAgent.match(/samsung/i) and apply separate CSS class for Samsung browser.

Related

Mailchimp Dark Mode: Force CTA-Color via CSS

The regular background color of my CTA-button is #6BBD45 with #fff font color. However, when viewed on my iPhone in dark mode it becomes much darker (duh...) – background color #2d601d, font color #222126 – hence completely using its vivid, attention-drawing effect.
Is there a line in CSS that I could use to force Mailchimp to render the original colors? Ideally, I am looking for a solution that works across all devices and email clients.
I know that there are potential workarounds, such as creating visuals in Adobe XD or the like and then adding the button or even the entire section as an image file. However, I am looking for a sustainable solution that saves me time and troubles in the long run.
Thank you!
Unfortunately, this not something Mailchimp can do much about. Each email client with a dark mode has a different way to apply a forced dark mode. You didn't mention which email client nor which system you took your screenshot in so I'll go through the main three.
Apple Mail
In the case of Apple Mail, you can usually maintain your initial colors by adding the following to the <head> of your email:
<meta name="supported-color-schemes" content="light" />
<style>
:root {
color-scheme: light;
}
</style>
(The <meta> tag is for Apple Mail 12 while the CSS version is for newer versions.)
Apple Mail may still enforce its dark mode though. So what you can try it to set a slightly different shade of grey instead of pure white. For example, use #fffffe instead of #ffffff.
Outlook
On iOS, Android and on Outlook.com, the forced dark mode is applied by setting new color inline in CSS. The previous color is saved in custom proprietary data-ogsc or data-ogsb attributes. While you won't be able to force your text to white here, you can still try to tweak things by setting a different background-color to your button for example.
<style>
[data-ogsb] .button {
color: #5eba7d;
}
</style>
Gmail
In iOS and Android, Gmail forces its dark mode and there ain’t really much we can do about it. There’s a solution involving CSS Blend Modes. But it’s complex and only works with white text on any background. (Which would work in your case.)

Tailwind not rendering colors right on my Brave browser

This image is from Chrome, notice the color of the text-red-900
You can see the example output on the right side, the Aa.
https://tailwindcss.com/docs/text-color
**This image is from Brave Browser, notice the color of the text-red-900 is lighter than most of the other text-red-xxx classes.
Why is this? Both are using my computed system default dark mode.
You can see there is a inline style overriding the CSS color for this element, where is this inline style coming from? and how do I prevent it?
--darkreader-inline-color: #e17d7d;
Note: I have 2 macbook pro Os Monterey M1s. This is only happening on one of them, the other is rendering colorrectly.
I completely uninstalled Brave Browser, including all the files for Brave within the ~/Library folder like Preferences and what not.
Then I reinstalled, and seems to be working without any additional settings.
Is there some setting that would force elements to be lighter in Brave Browser to support Accessibility.
I believe it was some extension called Dark Reader that was brought over from chrome (disabled on chrome, but enabled on Brave) What an annoying extension.

How to force CSS prefer-color-scheme to dark globally in all chrome pages

There is a known bug in Chromium where it can't detect the preferred theme of the system OS, so it always sets it as default (light theme).
An often given "solution" is enable the Chrome flag #enable-force-dark, but it doesn't really solve the problem, the CSS "prefer-color-scheme" media query is always set to light, no matter what you do.
One temporary solution that I think is to force the "prefer-color-scheme" query globally on Chrome. I know that you can force it in the Dev tools at F12 Three dots > More tools > Rendering > Emulate CSS media feature prefers-color-scheme, but it will only be active in the current page context for Developing purposes, so, How can I set the prefer-color-scheme to dark globally?, maybe with a Chrome extension?

Chrome is forcing a white background on frames only on some websites

I'm building a Web Extension that injects a local page and I reached a strange Chrome limitation on some websites: I can't set the iframe to be transparent:
Try this on GitHub.com (after login) or on Google:
document.body.insertAdjacentHTML(
'afterbegin',
'<iframe style="background: red" srcdoc="<style>body {background:none}">'
)
You'll see that the iframed page’s background (white) is shown instead of the element’s background (in this case made red to highlight the issue).
If you try the same code on StackOverflow or Twitter you'll find that the iframe is red.
I assume this is due to security but strangely it's even happening on this simple website that lacks any security header: https://sjmulder.nl/en/textonly.html
Firefox and Safari are not affected.
For anyone looking for a quick copy-paste answer: include a color-scheme meta header in the injected iframe. It must match the color-scheme header of the web page, if one exists. Do not add the meta header if a website does not have one. As this requires programmatic effort to figure out if such header exists a what the content value is, those steps are omitted, but once the scheme is known, the injection code would look something like this:
document.body.insertAdjacentHTML(
'afterbegin',
'<iframe style="background: red" srcdoc="' +
'<meta name=\'color-scheme\' content=\'light dark\'>' +
'<style>body {background:none}">')
Next a more detailed answer, and how I discovered it.
The screenshots show macOS in dark mode. If you go to OS settings and toggle the appearance between light and dark, this should alternate the white color and red color behind the iframe. Try and see if this happens.
After some experimentation, I discovered iff a website has a meta header for color-scheme:
<meta name="color-scheme" content="light dark">
as is the case with Github.com and sjmulder.nl, an iframe without matching header is only able to handle light mode correctly, and renders a white background if user device is set to prefer dark mode. I suspect this is because "major browsers default to light mode if not otherwise configured".
You can experiment with this and switch the color mode header on a test website to "light" (only) and "dark" (only) without specifying anything in the injected iframe; or define it in the iframe and not on the website, then switch the device color mode preference to see the effect. The conclusion I reached was the headers must match for iframe background color to get applied correctly.
I reached a strange Chrome limitation on some websites
When a website has not defined a color-scheme meta header and the injected iframe has not defined one either, there is no mismatch, and there is no issue, which is why this problems only presents on some websites. I also tried other browsers (Edge, Opera) and they have this same issue, at least on macOS. But it can be fixed in an extension by first checking if there exists a meta header on the page, and if yes, applying that same header to the injected iframe.
Read #neea’s answer for a broader explanation, but here's a quick fix that works anywhere: Add the CSS color-scheme: normal to the iframe, either via stylesheet or inline:
<iframe style="border: 0; color-scheme: normal" src="your-url.html">
Only do this if the iframed page will display correctly on both dark and white backgrounds. You might also need to set color-scheme: normal in your iframed page via meta tag, but this should not be necessary.
Why Chrome does this
Light schemes generally show black text and white background and dark schemes are the opposite. Chrome uses the color-scheme property to understand what schemes a website supports. The lack of it means it only supports the light scheme.
If the main page is being shown in a dark schemes and the iframed page isn't, with a transparent background you would get the iframed page’s black text on the main page’s black background.
This is a safety mechanism to ensure that the iframed content is still readable. If you drop it, you will need to manually ensure that the iframed page is readable on a dark background too.
Live demo
You can see that neither iframe has a background in both dark mode and regular mode.
Page only has one scheme, iframe never shows a white background: live link
Page only 2 schemes, iframe never shows a white background: live link
Following what #neea has said, which is true, I want to propose another code fix, since the color-theme fix doesn't do anything for me.
Since you use the iframe for a chrome extension, you simply need to have the iframe injected with a content script and then get the value of the page of the meta tag, which can be done easily with document.querySelector('meta[name="color-scheme"]')?.content
Personally, in my project I used react and react-frame-component, and I got it by inserting this into the head (I also use TS):
<meta
key="1"
content={
(document.querySelector('meta[name="color-scheme"]') as any)
?.content ?? 'light'
}
name="color-scheme"
/>,
I verify if the site has that tag, then I take and if not, it defaults to light mode.
This needs to be injected into your iframe HEAD. Then it will work for sites such as google dark mode or github.
Element.insertAdjacentHTML()
The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position. It does not reparse the element it is being used on, and thus it does not corrupt the existing elements inside that element. This avoids the extra step of serialization, making it much faster than direct innerHTML manipulation.
It has something to do with how chrome parses HTML and the order it uses.

Firefox: How to test prefers-color-scheme?

In Firefox 67, one can use media queries to detect user preference on light or dark theme.
In my version of Firefox (under Ubuntu), it seems that my preference is light theme. That is, the following CSS gives a blue background:
#media (prefers-color-scheme: light) {
:root {}
body {
background-color: blue;
}
}
How can I change my Firefox preferences so that prefers-color-scheme: dark
evaluates to true?
I found an add-on that seems to do the trick, but I must be doing something wrong with my own CSS, as it does not work on my page.
Dark Website forcer
Good news -- from Firefox 87 this is now enabled by default, without the need to set a configuration flag! You can find it in the inspector tab:
Choosing the sun button simulates light mode;
Choosing the moon button simulates dark mode;
With no button selected, your operating system default will be used, as per normal.
In some older versions of Firefox, this feature existed behind a flag. To test on one of those versions, you can thus enable this by going to about:config, and setting the devtools.inspector.color-scheme-simulation.enabled property to true. Once that's done, you'll find the controls for it in the same place as in the modern devtools, but as a single paintbrush icon rather than today's sun/moon toggle buttons.
You can update the style used by Firefox by going to about:config and adding a new property ui.systemUsesDarkTheme of integer type with value 1.
It doesn't automatically update the value on active pages in the same way that it does when you're updating OS settings in Windows or Mac, but if you refresh the page after updating it will pick up.
You can confirm the browser setting is correct by viewing the example on mdn
Edit:
On firefox 71 the update is applied to active pages without refresh
Just for the sake of completeness: If everything fails, there is a Firefox add-on called “Dark Website Forcer” (also on GitHub).
It changes the style by reading the CSS of the website and re-applying the parts for the dark version again, if you want to have a dark one. As such, it also can only force a dark website, not the light one. The Readme has a detailed explanation why.
Disclosure: I'm the author of this add-on. 🙂

Resources