I want to add another class to a element, but some of those elements already have an existing class, however the class I am adding I want it to be the first class added in the class field and don't want to append it; because from what I know, in general, rules in the last listed class will overwrite rules in the former classes, correct!?
I know of a jquery method as below..
$("p").addClass("myClass");
However from what I understand this just appends the class and you can't choose where to put it.
Is there any way to do this easily or will I have to start removing classes and re-adding them?
Not sure if there is any need to do something like this, I personally like advice of #bwoebi just change specifity.
But still if you need it, this might help
HTML
<div class="second">Lorem text</div>
jQuery
var $div = $('div'),
classes = $div.attr('class');
$div.attr('class', 'first' + ' ' + classes);
You can put your variable which contains class's name in place of 'first'
Demo
You add multiple classes to an element by simply separating the classes using a space. For example:
<p class="key_paragraph dark no_border">Your text here</p>
<p class="key_paragraph dark">Your text here</p>
The order in which the classes are listed in the html attribute does not matter. What matters is the stylesheet.
In your stylesheet (css file), if you want any of the classes to override another you could change the order of the rules in the stylesheet. For example, if the class 'dark' has a border and the class 'no_border' does not, you must place 'no_border' after 'dark' in your stylesheet to ensure 'no_border' overrides 'dark' for the first paragraph. Like so:
.dark {
border: 2px solid red;
}
.no_border {
border: none;
}
Secondly, you could add specificity regardless of the order of the css rules. For example, combining classes to say 'if an element has the classes dark and red' is more specific than either of the two above rules. See here for more info on specificity. Thus, the following rule would ensure there is no border on elements with the classes 'dark' and 'no_border' regardless of the order in which they appear on the stlesheet:
.dark.no_border {
border: none;
}
.dark {
border: 2px solid red;
}
A third option is to use the css :not selector to target all elements with the class 'dark' that do not also have the class 'no_border'. Again, the order of rules in the stylesheet will not matter here. This is done as follows:
.no_border {
border: none;
}
.dark:not(.no_border) {
border: 2px solid red;
}
There are other ways to do this, but hopefully I have explained three easy ways in a manner you can understand. There is a more jquery-specific demo here (see the third example). Let me know if you have any questions.
Just for fun in case you wanted to add the new class at a specific index inside the current classes:
http://jsfiddle.net/ckzVk/
function addClassAtIndex(elementId,classNameToAdd,index){
var element = document.getElementById(elementId);
var elementClasses = element.className.split(" ");
elementClasses.splice(index,0,classNameToAdd);
var newClasses = elementClasses.join(" ");
element.className = newClasses;
}
To add class "man" to div:
<div id="stuff" class="cool bro sweet">The div.</div>
JS:
addClassAtIndex("stuff","man",1");
Result:
<div id="stuff" class="cool man bro sweet">The div.</div>
Related
Handlebars.js question
Making background color for {{#each}}
<form action = "/ editday" method = "post">
<div class = "row" style = "background-color: {{striped #index}}">
I use my helper striped.It`s Ok.
I wanted to change the background color via CSS:
.row.striped> div: nth-child (even) {
background-color: # 000;
}
But nothing happened. Because the CSS is applied before the handlebars {{#each}} loop runs. CSS doesn't see the final document yet with a set of <div class = "row". Thus, for all row, background-color will be applied to all the same or none. nth-child (even), nth-child (odd).
Is there any other more convenient way to do striped?
Why does your CSS selector target .row.striped? There is no "striped" class in your template. The only class you have is "row", as in <div class="row">.
"striped" is the name of your Handlebars helper, which you are using to generate a background-color applied with an inline-style attribute.
I think your problem is that your inline-style is overriding your CSS.
As you alluded to in our discussion in the comments, you can do this purely with CSS. Just eliminate the style attribute from your template and add the required CSS rules. Just make sure you are not targeting the missing "striped" class. The CSS would look something like:
.row {
background-color: whitesmoke;
}
.row:nth-child(even) {
background-color: black;
}
Here is an example fiddle.
For the sake of completeness, I will explain how you could use the Helper. You would remove the CSS rules and just apply the desired color based on the index. The helper would be:
Handlebars.registerHelper('striped', function (index) {
return (index % 2 === 0) ? "WhiteSmoke" : 'black';
});
I have a fiddle for this as well.
I have to modify an existing HTML5 app that has two different types of themes.
For example, I have something like this:
<body class="theme1 theme2">
<div id="div1">I'm happy with both themes</div>
<div id="div2">I just want theme 2</div>
</body>
This example is overly simplified. I know that I could just apply theme2 to div2. But the point is that those themes classes are in the body and I cannot "easily" change that.
I naively thought that I could just do something like this in JS:
getElementById('div2').classList.remove('theme1');
But this does not seem to work. I think that this only work on classes directly applied to the element. I would prefer a "pure CSS" solution anyway.
The info that I find seems related to preventing inheritance of specific properties. In my case, I want to prevent inheritance of any property under the theme1 class for div2 and all its children.
Properties are inherited, classes are not.
The only way to stop a property being inherited is to assign a value to that property for the given element.
The code doesn't work because 'theme1' is not a class of div 'div2'.
I don't know of a way to selectively remove the inheritance as you asked. The closest solution I can think of is to use nesting to create a more specific selector and override the undesired styles. Simple example:
.theme2 {
font-style: italic;
}
.theme2 #div2 {
font-style: normal;
}
This would "remove" the italic style from div2. You would have to redefine all the undesired styles. From a maintenance standpoint this may or may not be an acceptable solution. But it does solve the problem.
No, that's not how CSS works. If properties are getting applied to a descendent because of a class on an ancestor, and you cannot change that class or the properties, then you have to override the properties (via a more specific selector) that you don't want inherited.
e.g.
body.theme2 div { background: #000; }
#div2 { background: transparent; }
Let's start with some common.js:
//<![CDATA[
var doc = document, bod = doc.body, IE = parseFloat(navigator.appVersion.split('MSIE')[1]);
bod.className = 'js';
function gteIE(version, className){
if(IE >= version)bod.className = className;
}
function E(e){
return doc.getElementById(e);
}
function removeParentClassName(childId, removeClassName){
var cn = new RegExp('(\s+)?'+removeClassName, 'i'), pn = E(childId).parentNode;
pn.className = pn.className.replace(cn, '');
}
//]]>
Now on your current page:
removeParentClassName('div2', 'theme1');
One way you could do this with pure CSS would be to set up you CSS rules like so
.theme1 .div1,
.theme2 .div1,
.theme1 .div2,
.theme2 .div2 {font-style:normal;} /* apply theme1 and theme2 styles here */
.theme1.theme2 .div2 {font-style:italic;} /* apply theme2 only rules here */
Is it possible in Javascript to set different element's styles at once, in such way that only one reflow is triggered? For example, is it possible to set at once the color style for different elements as in the below code snippet, in a way that just one reflow is triggered instead of three reflows?
document.getElementById("elem1").style.color = '#000';
document.getElementById("elem2").style.color = '#fff';
document.getElementById("elem3").style.color = '#abc';
I am familiar with techniques (as explained here) that minimize reflows/repaints such as using document fragments or using css classes instead of manipulating css styles through javascript, but I don't see how they can be applied on this case.
EDIT: the three elements on the example are siblings but there might exist, or not, other sibling elements between them, meaning that we cannot assume that they are defined necessarily by that order in the html structure. For example, its possible that we have a structure like this:
<div id="parent">
<div id="elem1">elem1</div>
<div id="elem2">elem2</div>
<div id="elem4">elem4</div>
<div id="elem3">elem3</div>
</div>
Much appreciated for any help!
Cheers
As far as I am aware the is no way to set the class of multiple elements at once. However, the browser may actually batch these changes for you anyway. Providing you don't read styles as well as writing them I believe this should hold true.
This article provides some insight into how reflow and repaint are triggered http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
You can prepare class like this :
.color1{
color : #000;
}
.color2{
color : #abc;
}
And set to your elements like this :
document.getElementById("elem1").className = document.getElementById("elem1").className + " color1";
document.getElementById("elem2").className = document.getElementById("elem2").className + " color2";
Depending on your element structure. For example assuming those elements are sibling DIVs, you can define CSS as:
div.myclass {
color:#000
}
div.myclass + div {
color:#fff
}
div.myclass + div + div {
color:#abc
}
Then a single JS command:
document.getElementById("elem1").className = "myclass";
Would set color for all 3: http://jsfiddle.net/PjZ77/1/
If it makes sense in your case, use css classes and swap the container class.
HTML structure could be :
<div id="container1">
<div id="elem1" class="clsA">A</div>
<div id="elem2" class="clsB">B</div>
<div id="elem3" class="clsC">C</div>
</div>
and in CSS:
#container1 .clsA { color: #000; }
#container1 .clsB { color: #111; }
#container1 .clsC { color: #222; }
#container1.mystate .clsA { color: #DDD; }
#container1.mystate .clsB { color: #EEE; }
#container1.mystate .clsC { color: #FFF; }
You can set document.getElementById("container1").className with mystate class (or empty class, or any class name that makes sense you defined in the css.
Class change occurs for only one element (the container), so the elem(n) child items will be refreshed at the same moment.
Suppose we have 2 css files
First has
.x { background-color="red" }
second has
div { border=1 }
div:hover { border=2 }
How can we get style of by javascript without creating new element just to get its style?
And even if we need to create new element for get the style or not. How we can get it with and without hover ?
Are there any functionality like document.queryStyle({ type:"div",class:"x",hover:true }) or anything like this?
There is usually no problem with creating the element and removing the element right after, because the visitor will never see it.
Solution with jquery:
$div = $('<div class="border"></div>');
$('body').append($div);
var css = $div.css("border");
$div.remove();
HTML
<div class="content">
hello world
</div>
CSS
div.border {
border: 1px solid black;
}
JsFiddle example: http://jsfiddle.net/ypUKC/
If you really can't create the element, google for "Javascript CSS Parser".
By the way, your CSS Syntax is incorrect. It's "div { border: 1px; }", not "div { border = 1 }"
Thanks for you all's help. I have found a method I need for retrive style with event selector
I'd like to apply a CSS to some linkbuttons on page load but one of them <a id="lb1">logoff</a> must keep its style, no hover nor other event must change its style.
The linkbuttons have no class and the css applied to all of them is done to tags, this way:
a
{
//style
}
a:hover
{
// style
}
Is it possible?
No, you can't.
You can use more specific selectors (or even inline CSS with the style attribute) so that they are less likely to be overridden accidentally.
You can use the (eugh) sledgehammer of !important so they will only be overridden by another !important rule.
There is no way to prevent them being overridden though.
Please please please please please avoid using !important whenever possible. You will run into SO many annoying problems and issues from using this. I consider it a very lazy hack.
What you want to do is append a class to the link that you don't want overwritten. Classes are given a higher priority than general selectors (such a, p, b). So if you append this class to the link, the CSS will override the default CSS you have set for a.
CSS:
a {
color: red;
}
a:hover {
color: blue;
}
.derp:hover { /*you can add everything you want to preserve here, essentially make it the same as the link css. you can also change it to #lbl:hover, although there's no good reason to be using an ID as a CSS selector*/
color: red;
}
HTML:
this will turn blue on hover
<a class="derp" href="#">this will stay red on hover</a>
Here's a fiddle to show you. The second link has a class appended that preserves the original style: http://jsfiddle.net/p6QWq/
Why not add a class to all the link buttons you want to change, and not add it to the one you don't want to change.
Then you can call:
$(".myClass").css("backgound-color", "blue");
This would change the background color for every element with a class of myClass to a blue background.
Or you could add a whole new class to the link buttons that have a class of myClass:
$(".myClass").addClass("myExtraClass");
This would then make the class attribute of your link button class="myclass myExtraClass"
Seeing your code posted makes it a little more clear on what you want to do. Try this:
a {
text-decoration: none;
color: orange;
}
a:hover {
text-decoration: underline;
color: blue;
}
This would apply a default style to all <a> elements. Now you could overwrite this default style by providing a specific style for the anchor with the id you gave above:
#lb1 {
color: black;
text-decoration: none;
}
#lb1:hover {
color: black;
text-decoration: none;
}
I mocked this up in a quick and dirty jsFiddle. See if this gives you the desired result. IDs take precedence over classes and default element styling. So if you have one that you want to keep the same, apply and ID and style the particular element accordingly. This would also help you by preventing you from having to apply a class to several elements. It's less coding to apply one ID than to apply twelve classes. (Just an exaggerated example. I don't know how many links you have.)
Hope this helps.
css is cascading by definition, so any style you apply to a tags will apply to this specific one, except if you overwrite it.
You'll have to either assign a class to all the other buttons or overwrite all the default properties for this specific button.
Also, do not forget the pseudo-classes :visited and :active.
You should use !important in your css like :
a {
/* style */
background: #FFF !important;
}
a:hover {
/* style */
background: #FFF !important;
}
You could always overwrite your css by simply creating another stylesheet and place it at the END of your stylesheet links in the head of your html.
<head>
<link rel="stylesheet" href="location/location/first_stylesheet.css">
<link rel="stylesheet" href="location/location/revised_stylesheet.css">
</head>
This is not the most productive method of overwriting your css however; one would be well advised to eliminate the necessity for this separate stylesheet by simply appending elements with a class attribute. The class attr will allow you to modify basic html elements, tags and overlay a final layer to "rule them all". Enjoy!