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

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.

Related

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!

Change the position of button text and button icon

I have a button which contains an icon and some text. I want this button to be reusable. I also want to have the option of putting the icon left of the text or right of the text. I am passing in a prop (either "right" or "left") which will then adjust the CSS. Could anyone help me out with the CSS to swap the position of these two.
export const IconButton = ({icon,text, position}) => {
return (
<StyledIconButton className={position}>
<img src={icon} />
{text}
</StyledIconButton>
);
};
The StyledIconButton has a few default styles, but nothing important.
I am trying to use float but haven't been successful. Ideally I would avoid using flexbox as well.
.right {
img {
float: left;
margin-right: 0.375rem;
}
}
.left {
img {
float: right;
margin-left: 1.5rem;
}
}
As requested I am adding in the styles for StyledIconButton:
.styledbutton {
display: flex;
font-size: 1rem;
line-height: 2rem;
}
The above code won't actually swap the position.
I think using a flexbox and switching the direction would be the easiest way. You can learn about flexbox here.
But you can set left and right classes to decide on the direction of the flex.
.right {
flex-direction: row-reverse;
}
.left {
flex-direction: row;
}
And you would have set spacing and all other required styles on text and img separately, but this should do the trick

Color changing theme through theme setting

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.

Change CSS class by Javascript when default class is set by ID

I have a DIV that has CSS applied to it in an external stylesheet by ID, such as:
<div id="myFavoriteDIVever">Stuff</div>
#myFavoriteDIVever {
display: none;
}
Then, in a Javascript function, I set the following class to that same DIV:
document.getElementById('myFavoriteDIVever').className = 'superCoolClass';
.superCoolClass {
display: block;
}
For some reason, when I do it this way, the DIV is not set to display as block. It remains not displayed in the DOM. But if I change it so the DIV has a default CSS class applied to it that sets display: none; then I set a different CSS class to it with Javascript later that sets display: block; it works as expected and displays the DIV as a block element.
Why would the CSS class override the ID CSS? So, when I apply a new className it should override the #element settings. No?
Ascending order of specificity
The following list of selectors is by increasing specificity:
Universal
selectors Type
selectors Class
selectors Attributes
selectors Pseudo-classes
ID selectors
Inline style
You can overwrite it using inline-styling
document.getElementById('myFavoriteDIVever').style.display = 'block';
#myFavoriteDIVever {
display: none;
width: 300px;
height: 400px;
background: red
}
<div id="myFavoriteDIVever" class="myFavoriteDIVever">Stuff</div>
Ids have a higher priority so adding a class will not have any effect. Your best shot is:
<div id="myFavoriteDIVever" class="myFavoriteDIVever">Stuff</div>
.myFavoriteDIVever {
display: none;
}
document.getElementById('myFavoriteDIVever').className = 'superCoolClass';
The issue isn't with your javascript, its with the CSS. There is a concept called specificity. The idea is that each CSS entry has some specificity value (1000, 100, 10, 1). The style that will be applied is the one that is the most "specific". An ID selector = 100. A class selector = 10. The id will win. Try changing the css for the class from
.superCoolClass {
display: block;
}
to
#myFavoriteDIVever.superCoolClass {
display: block;
}
This should do fine:
HTML:
<div id="myFavoriteDIVever">Stuff</div>
CSS:
#myFavoriteDIVever {
display: none;
}
#myFavoriteDIVever.show {
display: block;
}
JS:
document.getElementById('myFavoriteDIVever').className = 'show';

Icon aligns to center when using display: table and margin: auto, but when I change to display:none it does not align to center after .show()

This works and properly aligns the icons:
#stepSuccess {
display: table;
margin: auto;
}
#stepFailure {
display: table;
margin: auto;
}
Here are the icons themselves:
<i class='icon-ok icon-4x icon-green'id='stepSuccess'></i>
<i class='icon-remove icon-4x icon-red'id='stepFailure'></i>
However, I need it to be at display: none for javascript purposes. When I try the code below it does not align to the center after I use .show() to display the icon.
#stepSuccess {
display: none;
margin: 0 auto;
}
#stepFailure {
display: none;
margin: 0 auto;
}
Here is the jQuery
if(checked)
{
//display correct-answer dialogue
$("#stepSuccess").show();
{
else
{
//display wrong-answer dialogue
$("#stepFailure").show();
}
How do I keep display: none and still have the code properly align to the center of the div (after .show() in javascript)? I also tried text-align: center;
Any help would be appreciated.
I suspect that when you use .show(), it sets display: inline instead of display: table. Instead of .show(), I would set up two classes, one for show and one for hide, and toggle the class.
Alternatively, you could also use:
if(checked)
{
//display correct-answer dialogue
$("#stepSuccess").css('display','table');
{
else
{
//display wrong-answer dialogue
$("#stepFailure").css('display','table');
}
instead of .show().
For the sake of less code, would you be able to just set the opacity to 0, rather than hide?

Categories