I have a button, which when clicked loads an additional CSS file, that overrides a great part of the basic CSS files. (this is for accessibility purposes if you wonder)
Let's say I have a background and background-color properties used in multiple selectors for input[type='text']. I want to reset/delete those. I DON'T want to set a new value for those background properties, I want to remove them, so that the browser will render everyting as it would by default.
The reason for this is because in high contrast mode with black background color to the body in Firefox, any background set to input or button will override it with a value equal to the text color which will make the value of the input or the button unreadable. But that's another story...
EDIT: Since everybody so far is telling me to set some new property to those, I'm writing it in bold big letters - I DON'T NEED TO SET NEW PROPERTY FOR background. :) The reason behind that if that property is present Firefox defaults it to black if the background set in the high contrast mode is black as well. To test this, go to Preferences -> Content -> Colors and check Allow pages to choose their own colors, instead of my selections above. Here's how my options look.
You can remove the original stylesheet. Just assign it an id and use jQuery.remove(...).
The alternate solution is to alter the first stylesheet to use some kind of namespace+, for example:
/* these are the rules that you want to be removed */
.stylesheet1 { }
.stylesheet1 h1 { }
.stylesheet1 p { }
.stylesheet1 a { }
.stylesheet1 input { }
/* these rules can co-exist with the next stylesheet */
nav { }
article { }
aside { }
section { }
Inside your HTML add the stylesheet1 class to body. When you load the other CSS file (presumably via JavaScript) then you remove this class. All namespaced rules will become ineffective.
* CSS preprocessors e.g. SASS and LESS make it easier for you to manage these rules.
Do a css reset/normalize at the beginning in your first css file. Then at the beginning of the second one do it again.
You can leave out the first reset, but this will give you consistent results.
It sounds like the best solution for you is to have two different CSS classes targeting a single input, and toggle back and forth between the two. There are several ways to do this:
CSS:
input[type="text"].a {...}
input[type="text"].b {...}
Here we have two different classes, a and b. When defining the input initially, set class="a". We'll then swap that with b when the button is clicked. Again, there are several ways of doing this:
jQuery:
$('.a').click(function(){
$(this).removeClass('a').addClass('b');
});
Plain JS
var button = document.querySelector('.a');
button.addEventListener('click', function(){
button.classList.remove('a');
button.classList.add('b');
});
This is the generally preferred method for achieving this kind of behaviour. It adheres strictly to standards, in that it separates logic, markup, and presentation into their respective pieces.
Note: The plain JS method listed above uses some pretty modern native JS code. Take a look at You Might Not Need jQuery to find suggestions for making this functionality cross-browser.
Instead of adding or removing properties to elements, I think the better way to do it is to put these extra properties in a CSS class and then add or remove this extra class to the elements as needed. And if you need override, then use !important. Now it's just about add/removing classes.
Here's an example in jQuery
.MyControl{background: blue;}
.MyControlAccessibility{background: red !important;}
$(SomeControl).click(function () { $(this).addClass('MyControlAccessibility'); }
$(SomeControl).click(function () { $(this).removeClass('MyControlAccessibility'); }
Using a global class on the body is good as mentioned.
Another way could be to put your light and dark "theme"-specific styles into separate stylesheets from the common CSS and then disable the one you do not want. This will avoid conflicts and needing to use !important, and you can keep things clean without having to hack away at various bits of jquery.css().
For example
base.css
a { text-decoration:none; }
dark.css
body { background-color:#000; }
a {color:#fff; font-size:1.2em;}
light.css
a {font-size:1.5em;}
Note that light.css has no properties for background-color etc. so when they switch from dark to light, the defaults will be used again.
To do the switch, you can do something along these lines:
for (var i = 0; i < document.styleSheets.length; i++) {
var ss = document.styleSheets[i];
// some browsers store in url, others in href
if((ss.href || ss.url || '').indexOf('dark.css') > -1) {
ss.disabled = true;
}
}
By disabling instead of removing the current one, it should be easier to switch between the two.
Related
I want the element to use only css that are in the "A" section and ignore the "B" section.
Is it possible?If javascript can do this, How?
Thanks you.
You can not do that with the example you've provided. The C in CSS stands for Cascading, the styling rules cascade down the DOM tree.
You have to reset the styling of the element to what you want with a more specific selector, e.g. #Examplewrapper input{}. By using a more specific selector, it'll overwrite/suplement the previous styling, without the need for !important.
Alternatively, you can set the most upper selector more specific, e.g. #content input{}. This way, when you place a form in the #footer, it will not have the styling, as #content doesn't have a #footer in it (it cant cascade).
I do recommend to define a general input as you have. This way, all forms have the same font, size and styling throughout your website. If you want another color border, you only have to change that one settings. This is the way many (profesional) sites work, because it is the most efficient.
This is how the inheritance works. You can only overwrite styles if others are set globally (i.e. for all input elements).
You can always limit the global styles of input with some classname, like input.myStyle so the raw input will have no styles set.
I like BEM a lot, and I usually use a variant of BEM where I use state classes to toggle sub-items on/off, leading to easy to understand rules in my SASS like:
.my-block{
&__element {
color : blue;
// I prefer state-classes over modifiers for state
&.is-selected { color : red; }
&--small { height: 50%; }
}
}
The problem I wonder how to solve in the most BEM-ish way is how to deal with a state change in my javascript that should apply to a lot of elements in a block. For instance, say I have a component that should hide or show different elements depending on whether you are in step1, step2 or step3 of a process.
The BEM bits are easy enough if I should just apply state classes on each of the elements, but that is just the problem. If I have 10 elements where 7 needs to be hidden on step 2 then that is 7x as much javascript to add as if I had just added a rules on the not so BEM-pure form of
&__element {
display: none;
// -- this --
.my-block.is-step4 & { display : block }
}
I could then activate all of those rules with one myBlock.classList.toggle("is-step4"), as opposed to one for each element.
My solution was a pragmatic middle point of developer convenience and pure BEM, but I wonder if there is a "pure" BEM solution that is also friendly in terms of line of codes needed in the javascript to update the elements?
Just use nested selectors for this case. So you'll have step modifiers on the parent block which contains all the rest of blocks you need to affect (and don't be afraid if such parent is the whole page).
See https://en.bem.info/methodology/faq/#can-i-use-nested-selectors — it's recommended solution.
I learned, that there are ways to change the color of single texts. However I'd like to find out how to change the color of all texts of my website at one time.
I found the document.body.style.backgroundColor = "black"; function and hoped that there would be something similar for fonts.
Edit: I am sorry. I guess I was misleading some people. I know what CSS is ofcourse... I wanted to find a way to change the colors while using the website. So I'd like to find a way to change the CSS properties via JavaScript.
If you really want to change the color of all text on a web page using Javascript, then I would use the following code
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
all[i].style.color = "red";
}
<div>This is text that will change colors!</div>
<div id="SomethingOtherAnswersWontChange"><span style="color:green;">Other answers will leave this text green.</span></div>
It's not exactly optimal, but it is robust. This code will change the font/text color of every element. It does this by looping through every element in the webpage and modifying the style of the elements to apply the CSS attribute "color: red;".
It is important to bear in mind that for very large web pages, this method might be a little slow, but it should get the job done.
Note: I am not 100% sure, but circumstantial CSS classes like a:hover might not be affected by this.
Use the CSS color property:
CSS
* {
color: [color-value];
}
This will change the font color of all elements using the universal (*) selector. If necessary, you may need to use the !important declaration (not recommended, but useful: see link) to override other styles.
JavaScript
document.body.style.color = [color-value];
Use .color instead of using .backgroundColor.
document.body.style.color = "red";
<div>This is text that will change colors!</div>
As stated in the comments above, you should really think about using CSS like this:
body{
color:red;
}
<div>This is text that will change colors!</div>
So, I have an element that has some "pre-existing" behavior attached to it. So, I found that just moving it (as required by some new requirements) retains the existing behaviors = good. But the issue is, when I move the element I need to give it "new styles".
So, if I have something like this:
<div id="existingStructure">
<div id="legacyElement"></div>
</div>
Now, that has pre-existing styles attached to both. I can rearrange these styles etc.. but I can't change them. The styles are attached to the "id's" rather than a class definition. I believe I can change that if needed.
Now, I need to move "legacyElement" when certain things happen to a "new div".
I just
jQuery('#newStructure').append('#legacyElement');
<div id="newStructure">
<div id="legacyElement"></div>
</div>
Unfortunetly, the styles I have on newStructure don't seem to be applying to *legacyElement" when it gets moved here dynamically.
I was thinking of moving all the styles to a class rather than associated to the ids, and when I move it.. I just jQuery().addClass / jQuery().removeClass etc...
Is there a better/easier more robust way that I can just have the legacyElement loose its styles when it sits under existingStructure and then get new ones when moved to "newStructure" etc.. and vice versa. That element "legacyElement" will be pinging back and forth.. so, I need it to have the styles under each parent div as it goes there.
so when an action happens on page, I move it back:
jQuery('#existingStructure').append('#legacyElement');
If I am not succinct enough, please let me know.
The EXISTING styles are in an external CSS file and are like so..
#existingStructure {
// bunch of css
}
#existingStructure .item1 input[type="text"] {
// bunch of css
}
#legacyElement{
// bunch of css
}
and new styles are sorta the same except 'additional styles' might be applied.
#newStructure {
// bunch of css
}
#newStructure .item1 input[type="text"] {
// bunch of css
}
You can certainly target your div styles by their parents:
#existingStructure #legacyElement {some styles}
#newStructure #legacyElement {some other styles}
To explain futher, this arrangement should result in greater specificity, overriding styles that are simply applied to either #existingStructure or #legacyElement. I'm hoping no one did anything foolish like using !important on them.
Short answer: It should.
Here's an example I quickly made in jsFiddle: http://jsfiddle.net/CCm4J/1/
So then why isn't yours? Most likely you have css rules that are embedded that apply only when in the existingStructure id/class perhaps? Without see more of your css I'm not sure how specific I can get. I would just verify that your css rules are allowed to apply outside of existingStructure (and even that existingStructure might have rules for its parent too!)
I am using jQuery monthly calender, in which every day is a cell, onClick in the cell, I am able to print the alert, but I also want to change the background color of the cell, on which I clicked. But I am not getting the way to call CSS using Javascript. Please help me out.
In jQuery, you may use the css method to change the background-color of the cell:
// let's say this is in a loop
$(this).css('background-color', '#f00');
And in plain JavaScript:
var element = document.getElementById("myElement");
element.style.backgroundColor = "#fff";
Steve
Using JS to change the style property of any element creates a very high specificity rule which is hard to detect and remove, and less flexible when dealing with multiple style effects (say you wanted a border as well as a background, now you have twice as much work to do).
Almost invariably it is far better from a maintenance, flexibility, and separation-of-concerns point of view not to modify the style of an element directly, but to change it's class and let CSS do the work for you.
e.g I want to change to this border+background style, so I'll define a class in my CSS
.highlight
{
border: 1px solid black;
background: white;
}
and then I'll modify the element where I need to like so:
document.getElementById('myElementId').className += " highlight"; //note the space
Now in practice I'd actually wrap that class modifying code in a more general wrapper to protect myself from assigning the same class twice, and make removing it again easier, but in principle you can see that it would now be trivial to change the effect of "highlight" at just a single point, it allows for normal cascading, and it's much easier to detect the element has a highlight class than it is to check if it's got a background colour of FOO and a border of BAR.
It also, quite importantly adds semantic value. Self documenting code is a very good thing.
To set one css property:
$("#myCalender").css("background-color","SomeColor");
To set an entire class:
$("#myCalender").addClass("DifferentBGColorClass");
To change the background color you could use:
document.getElementById("").style.backgroundColor = "#ffffff";