Color changing theme through theme setting - javascript

I am doing one project in which I want to change the theme color, icons based on country. For example, Australia people well enter theme color: red so all icons, and text or background color should get a change to red.
Changing/Loading different CSS is one option but, I want the user will enter color and that color should be pass to CSS file and theme will change.
Is there any way through which I can pass user entered input color code in CSS file?

Using vanilla JavaScript and CSS variables :
function customThemeColors ()
{
// Get the flags container
const flags = document.querySelector( '.flags' );
// Reference
let current = null;
// Add a click event
flags.addEventListener( 'click', () => {
// Clicked target
let target = event.target;
// If target is not a button or if it is the last one clicked return
if ( target.nodeName !== 'BUTTON' || target === current ) return;
// Get the color from the button attribute
let color = target.getAttribute( 'data-theme-color' );
// Set the css variable on the whole document
document.documentElement.style.setProperty( '--custom-theme-color', color );
// Reference to the button clicked
current = target;
});
}
// Usage example
customThemeColors();
/* Using CSS variables */
.color
{
color: var( --custom-theme-color );
}
.background-color
{
background-color: var( --custom-theme-color );
}
/* Everything else is not important, it is only for demonstration */
body
{
display: flex;
flex-direction: column;
align-items: center;
}
.flags,
.container
{
display: flex;
justify-content: space-evenly;
align-items: center;
width: 400px;
height: 50px;
}
button
{
width: 75px;
height: 25px;
}
.container > div
{
height: 50px;
width: 200px;
display: flex;
justify-content: center;
align-items: center;
}
<div>CSS variables example</div>
<div class="flags">
<button data-theme-color="#00F">Brazil</button>
<button data-theme-color="#0F0">Australia</button>
<button data-theme-color="#F00">Canada</button>
</div>
<div class="container">
<div class="color">Color</div>
<div class="background-color">Background-color</div>
</div>

No, not unless you generate the CSS file server-side via a controller that accepts a query parameter with the color.

you can create a select tag, that have options with value for example:
<select>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
https://www.youtube.com/watch?v=k2qJ8QbGbAU
heres a video that may help you see clearly what i mean.

It will be better to replace or add the css class or id of your page body so that you can easily change each and every style of that page. You can use jquery click function. For example: when you click on Australia just use addClass() function on body and add red class. You also need to write css for that red color theme as well.
Example:
$(document).ready(function(){
$('.australia').on('click', function(){
('body').addClass('red');
})
})
If necessary you can also remove previously added class while clicking another one. For more jquery function you can follow https://api.jquery.com.
You also need to add css for above red class like:
body.red {
background-color: #FF0000;
}
body.red p,
body.red span,
body.red h1,
body.red i {
background-color: #FF0000;
}
On that way you change color and theme of your whole page.

Related

How can I change color of more than one div of the same id using addEventListener("click")? [duplicate]

This question already has answers here:
JavaScript and getElementById for multiple elements with the same ID
(13 answers)
Closed 1 year ago.
Good day,
I have a CSS grid of 9 square divs, and I would like to add a click event for all of them so that their color changes from limegreen to black, and then changes back to limegreen when the mouse leaves. I am able to do so if I give each div a unique ID and use .addEventListener, but then the issue is I have to write a click event for each div. When I try to give each div the same ID and use .addEventListener, the click event only happens with the first div.
I have spent the past hour or two searching Stackoverflow, Google, forums, and other websites, along with tinkering with my code based on what I've found, but I can't find anything that has helped so far.
Here is my code, but I've only included the HTML/CSS for the first two divs, since the rest of the divs are like the 2nd div and don't respond to clicks:
const dude = document.getElementById("dude");
dude.addEventListener("click", function(){
dude.style.backgroundColor = "black";
});
dude.addEventListener("mouseleave", function(){
dude.style.backgroundColor = "limegreen";
})
.container {
display: grid;
margin: 7rem;
position: relative;
grid-template-columns: auto auto auto;
align-items: center;
justify-content: center;
column-gap: 2.5rem;
row-gap: 2.5rem;
}
.box {
background: limegreen;
width: 10rem;
height: 10rem;
position: relative;
}
.box2 {
background: limegreen;
width: 10rem;
aspect-ratio: 1/1;
position: relative;
}
<div class="container">
<div class="box" id="dude"></div>
<div class="box2" id="dude"></div>
</div>
Thank you very much for your help!
In HTML, two or more elements cannot have the same ID.
In your HTML, add a common class to the div(s) inside of .container.
<div class="container">
<div class="box gridbox"></div>
<div class="box2 gridbox"></div>
</div>
Now use this Javascript code:
/**
* Use this because we're getting the elements with
* their class, not id. This method returns an array
* of the elements with matching class.
*/
const dudes = document.getElementsByClassName("gridbox");
/** Loop over the whole array */
for(let dude of dudes){
/** Add click event handler */
dude.addEventListener("click", () => {
dude.style.backgroundColor = "black";
});
/** Add mouseleave event handler */
dude.addEventListener("mouseleave", () => {
dude.style.backgroundColor = "limegreen";
});
}
This should work fine.

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);
}
}

CSS changing to display: flex affects how classes are applied to button

I have an unordered list whose li elements each contain a button as a child within them.
In Javascript I toggle adding a 'done' style (which crosses off the text) on the li elements when they are clicked like so
function crossOffList(e){
if (e.target.nodeName === "LI"){
e.target.classList.toggle("done");
}
}
The following is the li style:
li {
margin: 10px 0px;
**display: flex;**
justify-content: space-between;
align-items: center;
align-self: center;
}
The issue is that when I add display: flex; to the li style, the button also becomes crossed off after the li item is clicked, like so:
This is how the buttons are created and added to the li elements
function addDeleteButton(element){
element.innerHTML += " ";
var button = document.createElement("button");
button.appendChild(document.createTextNode("Delete"));
button.addEventListener("click", function(e) {
ul.removeChild(element);
})
//button.classList.add("delete-button");
element.appendChild(button);
}
// initialise all starting list elements
for (var i of document.getElementsByTagName("li")){
addDeleteButton(i);
i.addEventListener("click", crossOffList);
}
This behaviour of the button also becoming crossed off does not occur if the display is not set to flex. What is causing this behaviour and is there any way to use flex while having the button not be crossed off after click?
CSS text-decoration does not get inherited in the same way as other properties, it gets propagated. It cannot be overwritten (but it can be added to) by setting another value in a child element. There is some discussion of this at Override text-decoration on child element
However, MDN documentation states that this propagation does not apply when the child element is floating or absolute.
I have not been able to show any improvement using float but there is some improvement if we position the button absolutely when, and only when, the parent LI element has display:flex
For example putting class flex on each LI element if you want them flexed and removing it if not and changing the CSS to:
li {
position: relative;
margin: 10px 0px;
justify-content: space-between;
align-items: center;
align-self: center;
background-color:cyan;
}
li.flex {/* add .flex class to each li if you want them flexed*/
display: flex;
}
li.done {
text-decoration: line-through;
}
.flex button {
position:absolute;
right:0;
}
Some work will be needed to make sure the desired layout is achieved but at least this method does not strike out the button text in both flex and non-flex cases.

How do I bind style to onclick element using Javascript?

Whenever I click on the left arrow icon, I want the style of the menu to change. Is it possible to bind specific css style when using onclick function?
i.fas.fa-chevron-circle-left.left
#sidebar-container .menu
width: 18rem
transition: 200ms
How I want it to look after onclick function.
#sidebar-container .menu
width: 10rem
Make a class containing the styles you want and you can toggle those on and off using javascript:
document.getElementById('my-element').classList.toggle('my-class');
This will add the my-class class if the element doesnt have it, and remove the my-class class if the element does have it. You may also use classList.add and classList.remove if you'd like to set it on or off.
You can easily bind this to a button with inline javascript. It is recomended to use event listeners but this should do the trick:
<button onclick="document.getElementById('my-element').classList.toggle('my-class')">Click me to toggle the class</button>
You can change my-elemment to be the ID of the element you want to toggle the class for and my-class to the classname you'd like to use.
It is possible to bind to an element. You can use document.querySelector() to find that element.
for example:
const el = document.querySelector("i.fas.fa-chevron-circle-left.left")
el.addEventListener("click", function(){
el.style.transition = "";
});
It's almost always easier to just add an overriding class instead of editing single style properties:
el.classList.add("override");
and have that class in css somewhere.
.override {
transition: none !important;
}
You can create a secondary class for styles you want when it is clicked. You can toggle the class like this
const menu = document.querySelector("#sidebar-container .menu");
menu.addEventListener('click', function () {
// by adding class name
menu.classList.toggle("menu-clicked");
});
#sidebar-container {
width: 200px;
height: 100vh;
background: #ccc;
display: flex;
padding-top: 20px;
align-items: flex-start;
justify-content: center;
transition: all ease 200ms;
}
#sidebar-container .menu {
background: #ddd;
padding: 20px;
display: block;
width: 100%;
cursor: pointer;
}
#sidebar-container .menu.menu-clicked {
background: green;
}
<div id="sidebar-container">
<div class="menu">
Menu
</div>
</div>
Hope it helps. Cheers!

Changing Text Color On Click

I'm trying to change the text from black to blue when I click. I have it as an "if" statement and I know it doesn't need to be an "if" statement, but I'm just wondering why it doesn't work. I'm just asking, "If this color is black, change it to blue."
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
if (myvar.style.color == "#000000") {
myvar.style.color = "#0000FF";
}
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
<div class="mydiv" id="thisdiv">Click Me</div>
JSFiddle
I'm not really looking for a solution to make it go from black to blue as I'm sure there's other ways I could figure out to do it, but more just wondering why the way I have it isn't working.
style only holds styles that were added using the style attribute in the HTML. It doesn't contain the computed style from applying <style> tags or stylesheets.
To get the computed style, use window.getComputedStyle(). Note this is read-only.
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
if (window.getComputedStyle(myvar).color === "rgb(0, 0, 0)") {
myvar.style.color = "#0000FF";
}
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
<div class="mydiv" id="thisdiv">Click Me</div>
A better strategy though is to add or remove CSS classes to elements, so that you get separate presentation from functionality.
Okay, so the reason the code is not working is because myvar.style.color is undefined. When you use a stylesheet, it doesn't affect the JavaScript style properties, which should be the same as the styles defined in the style attribute of the element. What you want is something like the following.
// undefined!="#0000ff", success
if(myvar.style.color!="#0000ff") {
myvar.style.color = "#0000ff";
}
If you want to use JQuery, you can try something like the following.
// JQuery always returns opaque colors in rgb(r, g, b) form
// regardless of the original format.
if($(myvar).css("color")=="rgb(0, 0, 0)") {
myvar.style.color = "#0000ff";
}
I strongly suggest using an additional class for this, to account for its state.
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
/* if (myvar.className === ""){
myval.className = "active";
} else {
myvar.className = "";
} */
// Same as below, toggle the class of #thisdiv from active to blank
myvar.className = myvar.className === "" ? "active" : "";
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.mydiv.active{
color: #0000ff;
}
You could also probably make use of the :visited pseudo selector and get rid of the click function entirely. You'd need to make your div one big link though. Something like this;
<a class="mydiv" id="thisdiv">Click Me</a>
.mydiv{
display:block; /* since it's a link and will be inline by default */
}
.mydiv:visited{
color: #0000ff;
}

Categories