How to detect Night Mode event - CSS / JavaScript? - javascript

Is there any CSS prefix for night mode or javascript event that trigger when user change the mode? I want custom colors for the element if the user enables night mode from the browser setting.
Thanks

It’s almost 2020 and we have now css media query to detect night mode.
#media (prefers-color-scheme: dark){
body {
background-color: black;
color: #ccc;
}
}

There is a CSS filter, I'm not sure that Twitter used something like this (no images were inverted only text and background.
note1: you can lower index of invert filter, for ex: .8
note2: no IE support :( but Edge support it
$('button').on('click', function(){
$('.wrap').toggleClass('day night') ;
});
.wrap{
background: white;
}
.day{
filter: invert(0);
}
.night{
filter: invert(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap day">
<img src="https://placeimg.com/200/150/any" />
<p>Lorem ipsus </p>
<button>Day / night</button>
</div>

Actually, today we can not only use #media (prefers-color-scheme: dark) in CSS like you've mentioned, but also check with js
const isDarkMode = window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches
and listen to changes in it:
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', event => {
if (event.matches) {
//dark mode
} else {
//light mode
}
})
(gratefully copy-pasted from this article, which may be not the original as the code is repeated in several others)
I'm not sure how to determine whether current browser will detect anything with these. I presume one should check if window.matchMedia('(prefers-color-scheme: dark)') is an object, but this is only my hypothesis, I haven't found any definitive info about this.

Because "night mode" will involve not only changing the background color, but also font colors (plus potentially a lot of other things) I would recommended a solution such as this:
Example HTML:
<body class="night">
Now, in standard mode the body tag wouldn't have the night class by default, but you would add this via a toggle class function such as jQuery's toggleClass.
Then in the CSS do something like...
CSS:
body {
color: #000;
background-color: #fff;
}
body.night {
color: #fff;
background-color: #000;
}
NB: Example only, please don't use white text on a black background :)
Now when the class is toggled and the night class is added, all the colors will change and the page will be in "night" mode.
Unsure if you also want instructions on making this mode "stick" during page refresh/navigation; if so, that is probably best handled with a session or a cookie that expires on browser close.

Related

Trouble with <input> styling and autofill

I am building a login modal and would like to use input tags to enable browsers to autocomplete username and password however I am struggling to fully reset the User Agent Stylesheet styling for input tags. Whenever autocomplete does its thing the old styling comes back.
Here's my (simplified) react login form:
<form id="login-popup-container">
<div className="login-field-container">
<div className="login-value-title user">email</div>
<input className="answer login-info" type="text" />
</div>
<div className="login-field-container">
<div className="login-value-title password">password</div>
<input className="answer login-info" type="password" />
</div>
</form>
I have added this in my index.css:
input, input:focus, input:active, input:hover, input:-webkit-autofill, input:autofill, input:indeterminate, input:enabled, input:valid {
outline: none !important;
border:none !important;
background-image:none !important;
background-color:transparent !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
box-shadow: none !important;
}
It works in a chrome incognito browser well enough
But in a regular chrome tab when autofill is performed by chrome this action brings the User Agent Stylesheet styling back to the input elements like this. As you can see above I have tried adding all the pseudo classes I could think of to the input tag reset styling but with no success.
Has anybody experienced this issue before / know why this is happening?
You can't override UA styles with !important
The user agent style sheets of many browsers use !important in their :-webkit-autofill style declarations, making them non-overrideable by webpages without resorting to JavaScript hacks.
https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill
Also, more efficiently reset every single style on your inputs with the CSS all property!
input {
all: unset;
}
You can use these global values:
initial - set all properties to property default defined by CSS
unset - if normally inherited: inherit, if not: initial
revert - set all properties to default for element defined by UA
For anybody experiencing this issue... the answer to my question turned out to be a combination of Zach Jensz's answer and adding a transition delay to <input> elements. It's definitely more of a hack than an answer, but for me it works.
My css reset looks like this:
input {
all: unset;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
transition: all 5000s ease-in-out 0s;
}
and my styling for inputs looks like this:
.classname-used-for-my-inputs {
background: transparent;
background-color: transparent;
color: white;
border: none;
}
The reason the delay hack is necessary is because even after unsetting all the styles, upon an autocomplete of the email/password event the User Agent styles kept coming back (I could not figure out how to prevent this). But at least now the delay time is so long that for all practical purposes no one will ever notice them and so for my purposes it works.
If somebody explains why / proposes a non hacky solution I will update this.
Also for styled-components, you could only apply it in your global.styles folder
input {
all: unset;
}

Can I make an element inherit the properties of other elements?

We're providing a pre-populated WordPress site for multiple members to use on their servers. The theme has a selector where they can customize their heading colours and fonts. Each member will have different colours based on their branding.
The site also includes a knowledgebase plugin and it uses its own colours which can be customized within its interface. Instead, we'd like to be able to set the knowedgebase colours/properties based on the theme's colour palette. (Ultimately, we'd like the member to only have to change the colors for the theme in one place rather than customize every single plugin.)
So, if H1 is globally set to blue, we'd like to be able to tell the knowledgebase's element (.kb-header) to be the same colour as H1.
Is this at all doable via CSS or Javascript or something?
Many thanks!
You can make an element to inherit the properties of a parent element. For example:
p { color: red; }
a { color: inherit; }
<p>Paragraph with link</p>
But definitely this won't work for what you're asking if your .kb-header is not a child of your h1.
Instead you could use different approaches to get the desired result. For example with custom properties (a.k.a CSS variables)
:root {
--user-color: red;
}
h1 {
color: var(--user-color);
}
.kb-header {
color: var(--user-color);
}
<h1>Title</h1>
<header class="kb-header">This is the header</header>
This way you could, for example, output your :root selector defining all your custom properties in your <head> tag using PHP. And your CSS would be totally independent from it.
If you want to inherit (Object Oriented Programing like) if the html tags doesn't have any relationship, you can use SCSS, for example SASS, it's a text pre processor that generates the CSS with a CSS-like coding with the addition that you can use variables and much more.
For more details visit SASS lang webpage i think this can help you a lot for mostly all your projects.
If you don't want to use SASS, you can even use javascript (with or without libraries) to reach this job, as plain CSS is not capable to conditionally apply styles between non-related tags.
I've written a miniature version of what you're looking for. Hope this helps :P
<html>
<style>
h1 {
background-color: blue;
}
</style>
<body>
<h1>Hey!</h1>
<div class="kb-header">I'm a div :)</div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var bgColor = $("h1").css("background-color");
$(".kb-header").css({"background-color": bgColor});
});
</script>
<body>
</html>
In CSS you can combine selectors with a comma and have a single block of rules for both:
.a, .b { property: value; }.
And still style one or another selector with other declarations (example below).
When selectors are unrelated, it causes maintenance problems but if it's generated by a theme generator, that should be OK (you don't want to style those given components but have a clear documented list of what has to be styled with a set of colors).
h1,
.kb-header {
color: darkred;
}
h1 {
font-size: 2rem;
}
#media (min-width: 961px) {
.kb-header {
border: 1px solid tomato;
}
<h1>Title</h1>
<p>Unstyled paragraph</p>
<header class="kb-header">This is the header</header>
You can also add a utility class to all elements that are to be styled with a border, a background color and a color:
/* Theme 1
Primary color: #0055D0
Secondary color: #080;
*/
.c-primary {
color: #0055D0;
}
.bd-secondary {
border: 1px solid #080;
}
/* Common styles */
h1 {
font-size: 2rem;
}
.kb-header {
padding: 1rem;
}
<h1 class="c-primary">Title</h1>
<header class="kb-header bd-secondary c-primary">This is the header</header>
Other answers talking about a Sass environment (or other preprocessors like PostCSS and LESS) and CSS "Variables" (if you don't have to support old browsers like IE11 and Edge ~15 + Saf (iOS and OS X) 9.2 https://caniuse.com/#search=custom%20prop are also fine solutions to your problem IMHO.

Change cursor color on web page?

Is it possible to change the color of the mouse pointer, so it matches the theme of your web site?
Not the color. You can create your own cursor image though, and apply it in css with the cursor property:
body {
cursor: url(myCursor.cur);
}
This page is relevant.
The "cursor" CSS property can be given the URL of an image to use:
.foo { cursor: url(whatever/cursor.cur) auto;
Different browsers have differing support for this; Opera has none I think.

:touch CSS pseudo-class or something similar?

I am trying to make a button, such that when the user clicks on it, it changes its style while the mouse button is being held down. I also want it to change its style in a similar way if it is touched in a mobile browser. The seemingly-obvious thing to me was to use the CSS :active pseudo-class, but that didn't work. I tried :focus, and it didn't work too. I tried :hover, and it seemed to work, but it kept the style after I took my finger off the button. All of these observations were on an iPhone 4 and a Droid 2.
Is there any way to replicate the effect on mobile browsers (iPhone, iPad, Android, and hopefully others)? For now, I am doing something like this:
<style type="text/css">
#testButton {
background: #dddddd;
}
#testButton:active, #testButton.active {
background: #aaaaaa;
}
</style>
...
<button type="button" id="testButton">test</button>
...
<script type='text/javascript' src='http://code.jquery.com/jquery-1.6.1.min.js'></script>
<script type='text/javascript'>
$("*").live("touchstart", function() {
$(this).addClass("active");
}).live("touchend", function() {
$(this).removeClass("active");
});
</script>
The :active pseudo-class is for desktop browsers, and the active class is for touch browsers.
I am wondering if there is a simpler way to do it, without involving Javascript.
There is no such thing as :touch in the W3C specifications, http://www.w3.org/TR/CSS2/selector.html#pseudo-class-selectors
:active should work, I would think.
Order on the :active/:hover pseudo class is important for it to function correctly.
Here is a quote from that above link
Interactive user agents sometimes change the rendering in response to user actions. CSS provides three pseudo-classes for common cases:
The :hover pseudo-class applies while the user designates an element
(with some pointing device), but does
not activate it. For example, a visual
user agent could apply this
pseudo-class when the cursor (mouse
pointer) hovers over a box generated
by the element. User agents not
supporting interactive media do not
have to support this pseudo-class.
Some conforming user agents supporting
interactive media may not be able to
support this pseudo-class (e.g., a pen
device).
The :active pseudo-class applies while an element is being activated by
the user. For example, between the
times the user presses the mouse
button and releases it.
The :focus pseudo-class applies while an element has the focus
(accepts keyboard events or other
forms of text input).
Since mobile doesn't give hover feedback, I want, as a user, to see instant feedback when a link is tapped. I noticed that -webkit-tap-highlight-color is the fastest to respond (subjective).
Add the following to your body and your links will have a tap effect.
body {
-webkit-tap-highlight-color: #ccc;
}
I was having trouble with mobile touchscreen button styling. This will fix your hover-stick / active button problems.
body, html {
width: 600px;
}
p {
font-size: 20px;
}
button {
border: none;
width: 200px;
height: 60px;
border-radius: 30px;
background: #00aeff;
font-size: 20px;
}
button:active {
background: black;
color: white;
}
.delayed {
transition: all 0.2s;
transition-delay: 300ms;
}
.delayed:active {
transition: none;
}
<h1>Sticky styles for better touch screen buttons!</h1>
<button>Normal button</button>
<button class="delayed"><a href="https://www.google.com"/>Delayed style</a></button>
<p>The CSS :active psuedo style is displayed between the time when a user touches down (when finger contacts screen) on a element to the time when the touch up (when finger leaves the screen) occures. With a typical touch-screen tap interaction, the time of which the :active psuedo style is displayed can be very small resulting in the :active state not showing or being missed by the user entirely. This can cause issues with users not undertanding if their button presses have actually reigstered or not.</p>
<p>Having the the :active styling stick around for a few hundred more milliseconds after touch up would would improve user understanding when they have interacted with a button.</p>
The much upvoted comment by #gion_13 solved the issue for me:
Add ontouchstart="" to your page's body element and the :active selector will work more as expected on touch screens. Still not perfect in Chrome.

If Browser, Use Javascript?

I have a script that detects what browser (and version) someone is using, and I'd like to set it up so that for certain browsers, a div class gets an animation on hover. I'd like to do this using jQuery, but I'm open to whatever.
My idea for the JavaScript is this...
if (browser == IE || browser < Firefox 4) {
// somehow animate a div class on hover (could be id-based too)
} else {
// do nothing
}
The CSS I have set up for this is something like this
.item {
height: 100px;
width: 100px;
/* css3 */
transition: height .5s, width .5s;
-moz-transition: height .5s, width .5s;
-webkit-transition: height .5s, width .5s;
}
.item:hover {
height: 200px;
width: 200px;
}
And then the HTML is (obviously)
<div class="item" id="item">
<p>Content here</p>
</div><!-- end item -->
The purpose is a CSS3 fix for older browsers. Transitions are, in my opinion, one of the best things about CSS3, and it annoys the hell out of me that IE9 doesn't include support for them.
Instead of this, how about using something like the Modernizr library?
http://www.modernizr.com/
Modernizr adds classes to the element which allow you to target specific browser functionality in your stylesheet. You don't actually need to write any Javascript to use it.
You can then do stuff like this:
.multiplebgs div p {
/* properties for browsers that
support multiple backgrounds */
}
.no-multiplebgs div p {
/* optional fallback properties
for browsers that don't */
}
You're going down a very dangerous path here using browser sniffing like that.
What you should be trying to do instead is use feature detection. There are libraries out there like the fantastic Modernizr which can do this for you.
Use $.support to check if the browser supports it and not even have to mess with version detecting. This helps future proof your code and more accurately models what you really want to do.
In fact, there's already a jQuery plugin to do this specifically. :D
Browser sniffing is not the best way to write JS-code.
If you prefer jQuery, here is jQuery.browser object
Some examples:
if ($.browser.webkit) {
alert( "this is webkit!" );
}
var ua = $.browser;
if ( ua.mozilla && ua.version.slice(0,3) == "1.9" ) {
alert( "Do stuff for firefox 3" );
}
if ( $.browser.msie ) {
$("#div ul li").css( "display","inline" );
} else {
$("#div ul li").css( "display","inline-table" );
}
You could do something like this:
<![if (IE 6)|(IE 7)|(IE 8)]-->
<link type="text/css" rel="stylesheet" href="nocss3.css" />
<script type="text/javascript" src="nocss3.js"></script>
<![endif]-->
You can use the library Modernizer (http://www.modernizr.com) which detects and fixes support of various HTML 5 and CSS3 features on different browsers.
Here's what they have in their documentation about CSS3 transitions:
http://www.modernizr.com/docs/#csstransitions
CSS Transitions are an incredibly
useful new part of CSS3. Using them,
you can let the browser animate—or
rather, transition—from one state to
the other. You only have to specify a
start and end and the browser takes
care of the rest.
In Modernizr we test for CSS
Transitions using the transition
property with all vendor prefixes.
Transitions can typically be used
without using Modernizr's specific CSS
class or JavaScript property, but for
those occasions you want parts of your
site to look and/or behave differently
they are available. A good example use
case is to build Modernizr into an
animation engine, which uses native
CSS Transitions in the browsers that
have it, and relies on JavaScript for
the animation in browsers that don't.
Sample Usage:
a {
color: #090;
-webkit-transition: color .2s ease-out;
}
a:focus,
a:hover {
color: #9f9;
}
You might look in to this tutorial https://developer.mozilla.org/en/Browser_Detection_and_Cross_Browser_Support

Categories

Resources