Is it possible to assign a class to :root? - javascript

As I am thinking about solutions to another problem of mine, I am trying to understand to which extend CSS elements can inherit from other elements. Specifically, having the following definition
.dark {
background-color: black;
}
.light {
background-color: white
}
is it possible to programmatically assign (with JS, probably) one of these classes to the :root element?

It can be done easily with JS.
Select the element:
const root = document.querySelector(':root')
Assign the class to it:
root.classList.add('light')
All together:
const root = document.querySelector(':root')
root.classList.add('light')
Or, instead of having two classes, it might be better to have a :not() selector:
:root:not(.dark){
background-color: white;
}
:root.dark{
background-color: black;
}

I would use (and have used) CSS variables for this.
:root {
--background-color: black;
}
.background {
background-color: var(--background-color);
}
Then change the CSS variable with javascript.

In HTML, :root is equivalent to <html> (doc):
In HTML, :root represents the element and is identical to the
selector html, except that its specificity is higher.
A possible solution would be to apply the class to <html>:
document.getElementsByTagName("html")[0].classList.add('dark')
.dark {
background-color: red;
}
<html>
hello
</html>

Related

Using dark or light mode

what is the best way to incorporate something like this into my site? I've tried using plugins but I cant get it to work. Doesn't have to be fancy.
Does anyone have it or have used one in the past they can recommend? Otherwise, is there a way to code it using JavaScript?
You could just set a button to trigger a boolean for example and based on its values, change the background-color of the items you want to change into dark mode.
I personally used react context for this one, something like this (kinda perfect how they used theme as an example). You should study it.
It depends on your framework, but if you use Material-UI, it has this option.
you can change palette type from light to dark and vice versa to achieve your requirements. Take a look here.
But if you don't use any framework, you should make a css structure that has two classes, light and dark, have some properties like color and background color and etc., and when the toggle theme button clicked, you will change all your classes from light to dark for example, also you can use animation for the effects.
There is a multiple solutions for this problem, if you are using a specific framework I suggest you check if there a way to do it with it, if you are not using any framework you still have multiple solutions and I suggest to create for each element you want to change his properties to dark mode another CSS class for each one, and with JavaScript create a function (that can call by a button on the html) that change all the element you want to those external classes, and if you click this button once again is reverse the function and make all the classes be with the original CSS classes
Maybe this should help you to kickstart.
<html class="theme-light">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.theme-light {
--color-primary: #0060df;
--color-secondary: #fbfbfe;
--color-accent: #fd6f53;
--font-color: #000000;
}
.theme-dark {
--color-primary: #17ed90;
--color-secondary: #243133;
--color-accent: #12cdea;
--font-color: #ffffff;
}
.container {
display: flex;
width: 100%;
height: 100%;
background: var(--color-secondary);
flex-direction: column;
justify-content: center;
align-items: center;
}
.container h1 {
color: var(--font-color);
}
.container button {
color: var(--font-color);
background: var(--color-primary);
padding: 10px 20px;
border: 0;
border-radius: 5px;
}
</style>
<script>
// Set a Theme
function setTheme(themeName) {
localStorage.setItem('theme', themeName);
document.documentElement.className = themeName;
}
// Toggle From light and dark theme and Vice-Versa
function toggleTheme() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-light');
} else {
setTheme('theme-dark');
}
}
// Onload Theme
(function() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-dark');
} else {
setTheme('theme-light');
}
})();
</script>
<body>
<div class="container">
<h1>Theme Switcher</h1>
<button id="switch" onclick="toggleTheme()">Switch Theme</button>
</div>
</body>
</html>
This is a simple approach that I've used several times:
On the main html file, I load the default theme, for example the light one:
<link rel="stylesheet" href="/themes/light/theme.css" id="linkTheme" />
Then, on the theme changer button/menu option, I change the CSS file of the above link to load the corresponding one, something like:
const handleToggleTheme = (dark) => {
const lightUrl = "/themes/light/theme.css";
const darkUrl = "/themes/dark/theme.css";
if (dark) {
document.getElementById('linkTheme').setAttribute('href', darkUrl);
}
else {
document.getElementById('linkTheme').setAttribute('href', lightUrl);
}
}

Change Element's Class Name without affecting CSS values

I have an DOM element and I want to only change the className of the element. I want to remain the css values as it. (For both external css and inline css)
For example, if I have this:
.sample{
display: block
font-size: 10px,
font-color: #fff
}
<div class="sample">...</div>
After doing some JavaScript operation I need to reach this:
.newCss{
display: block
font-size: 10px,
font-color: #fff
}
<div class="newCss">...</div>
Note: There is no strict rule for css, there can be a css selector with 100 values or with only 1 one.
Note2: There is no css selector such as .newCss, I should transform the css properties from .sample, to a new one called .newCss
You can get the computed style for the element prior to making the change:
const style = getComputedStyle(theElement);
and then apply that styling to the element directly:
theElement.style.cssText = style.cssText;
Then removing the class won't change the element's styling, because it's styled inline.
Example:
const theElement = document.querySelector(".sample");
console.log("before:", theElement.className);
setTimeout(() => {
const cssText = getComputedStyle(theElement).cssText;
theElement.className = "newCss";
theElement.style.cssText = cssText;
console.log("after: ", theElement.className);
}, 800);
.sample{
display: block;
font-size: 10px;
color: #fff;
background-color: black;
}
.newCss {
background-color: yellow;
}
<div class="sample">this is the div</div>
If the new class has styling associated with it in CSS, that might affect the styling of the element. If you need to prevent that, change the class first, then assign the CSS text:
Example:
const theElement = document.querySelector(".sample");
console.log("before:", theElement.className);
setTimeout(() => {
theElement.style.cssText = getComputedStyle(theElement).cssText;
theElement.className = "newCss";
console.log("after: ", theElement.className);
}, 800);
.sample{
display: block;
font-size: 10px;
color: #fff;
background-color: black;
}
<div class="sample">this is the div</div>
You have to use JavaScript. In order to use JavaScript, you have to assign a ID to the <div> tag. Then manipulate it by JavaScript. Example: document.getElementById("id1").className="sample";
Also make sure that you using semicolon(;) after CSS properties.
function f1()
{
document.getElementById("id1").className="sample";
}
.sample{
display: block;
font-size: 10px;
font-color: #fff;
color: red;
}
.newCss{
display: block;
font-size: 10px;
font-color: #fff;
color: green;
}
<div id='id1' class="newCss"><p>Hello</p></div>
<button onclick="f1()">Click</button>
Well, if you want to change className to a class which is identical, you can simply redefine the class in the style sheet to be equivalent, or you can use inline styles, but the purpose of CSS classes is to keep a unique set of rules, so two identically-ruled CSS classes would defeat the purpose for which they exist, to be unique definitions of CSS rules, so if you want the CSS rules exactly the same, then there wouldn't be a reason to change the className, unless you were referencing it with other JavaScript functions, or if you wanted to add additional styles while keeping the old ones, in such a case:
use classList to dynamically add or remove certain individual classes, while keeping others.

Changing the background color and the main content background in wordpress

I've been searching on this topic for almost 1 hour and I couldn't find an answer, as you know most youtube videos out there are completely useless. My website is on WordPress and I would like to change the background color, and the main content in specific pages
Here's the code that I tried to add to the Custom CSS box
.page-id-2
{
background: #FFFFFF
}
.page-id-2 .content {
background: #FFFFFF
}
It didn't do anything
Here my website: www.graspdating.com
Try this. The selector you want is an ID (#) not a Class (.)
EDIT
.page-id-2 #content,
.page-id-2 #content article,
.page-id-2 #content #search-2,
.page-id-2 #content .enl-widget-title,
.page-id-2 #content #secondary,
.page-id-2 #content .arc-entry-meta { background-color: #FFFFFF }
This should completely "white-out" the background of the content area. If there are certain elements you want to have a different color, you can remove accordingly.
You will need to override the current class properties using another class properties. There are different ways in which properties can be overridden. Assuming you have the following for your .site-content:
.blog .site-content { background: #eeeeee;}
e.g. any of the following would override it:
.blog .site-content { background: red !important;}
body .blog .site-content { background: red;}
.page-id-2 .blog .site-content { background: red;}
body.page-id-2 .blog .site-content { background: red;}
the first one "wins" by !important, a blunt instrument... The rest “win” by selector specificity;
By saying that, you can override properties by the selector specificity (https://www.w3schools.com/css/css_specificity.asp) and/or using the !important (https://css-tricks.com/when-using-important-is-the-right-choice/)
You can easily do it using dependency like
body .page-id-2 { background: #FFFFFF; }
similarly you can also use
body.page-id-63 #content { background: #FFFFFF; }

Parse CSS into JavaScript with selector awareness

I want to build something that could consume a .css file return a function that would take an array of class names and return the styles that would apply to an element with those class names, as a JavaScript object. (Such an tool would be suitable for use with Glamor, Fela, or other CSS-in-JS technologies.)
E.g., if you have this CSS file:
.btn {
border: 1px solid gray;
}
.btn.primary {
background: blue;
border-color: blue;
}
.btn-group {
display: inline-block;
}
then you could do something like this:
import css from "./btn.css";
import applicableStyles from "applicable-styles"; // what I want to build
const btnStyles = applicableStyles(css, ['btn', 'primary']);
// Expected value:
{
border: "1px solid gray"
background: "blue";
border-color: "blue";
}
In this example, .btn-group gets ignored because we only asked what style would apply to .btn.primary.
This is new territory for me, but I know there are tools out there for parsing CSS. What libraries might be most promising to take a look at? (Or, does something like this exist already?)
This should be possible using some of the various npm packages out there.
For example, the css-object-loader package allows you to require a .css file, which is converted to an object with keys corresponding to the selectors, which you can then access.
p {
font-size: 14px;
}
h1 {
text-indent: 20px;
}
.centered {
width: 100%;
margin: 0 auto;
}
var selectors = require('./rules.css');
// Get the
selectors['.centered']
I've also seen SCSS destructured at import, like:
import {btn, primary} from './btn.scss';
but unfortunately I can't remember what loaders were used to do this.

Select element based in css property

I want to select a child element that has a specific background color.
For example, I have my parent #xxx (id) and it has lots of direct children. I want to select all the children from this parent #xxx that have bakground:#000
I searched a lot and couldnt find an answer. Could you help me? Something like this (of course it does not work):
#xxx > div(background:#000) {
}
You can't do this with css, but you can use jquery for that:
$('#xxx div').filter((index, el) => {
return $(el).css('backgroundColor') == 'rgb(0, 0, 0)'
}).css('color', 'white');
.a {
background: red;
}
.b {
background: green;
}
.c {
background: blue;
}
.d {
background: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="xxx">
<div class="a">a1</div>
<div class="b">a2</div>
<div class="c">a3</div>
<div class="d">a4</div>
</div>
As far as I know this isn't possible.
You could do it with jQuery.
But a better option might be something like this:
.black { background-color: #000000; }
.red { background-color: #ff0000; }
#xxx > .black { padding: 10px; }
If you don't want to use JQuery, There is a pretty good way to use CSS3 [attribute*=value] Selector to achieve that:
#xxx > div(style*="background:#000")
{
...
}
BUT
Notice 1: keep this in your mind that as attribute selectors don't support regular expressions, you can only perform exact sub-string matches of the attribute value.
Notice 2: You have to use inline mode style, otherwise it does not work.
I hope to be helpful :)
Some of you said this is not possible but it is possible. It's very possible. You just need to take care with the color, browsers (Chrome and Firefox latest that I could try) allow selection based in the background color BUT it has to be in RGB format and you need to use a space after the comma in the color. This will work perfectly:
#xxx[style*="background: rgb(255, 255, 255)"]>div:hover{
border:10px solid #000000;
}

Categories