Using .css() on pseudo elements with jQuery - javascript

var navIcon1 = $('.nav-toggle span, .nav-toggle span:before, .nav-toggle span:after');
if (iconPos >= audPos && iconPos < eventPos) {
navIcon.css('color', 'black');
navIcon1.css('color', 'black');
}
I am trying to change the color of bootstrap navigation. I tried this code but it is not working for me.
Can I change the CSS of pseudo elements with jQuery?

Rather than adding css in your if, add a clas to "nav-toggle" for the given position and add your color for that class

The only one of the elements you can modify using this method is .nav-toggle span, you could do:
if (iconPos >= audPos && iconPos < eventPos) {
$(".nav-toggle span").css('color', 'black');
}
As to the other ones: :before, :after etc. are pseudo elements - jQuery can't access them the way you are trying to do it.
Adding a class containing your preferred color to the elements you want to change would be a way of achieving what you want to achieve.

Related

Select a css3 element by grandparent's parent's class

Im implementing multiple rangesliders into my site and because this is code generated in real time I need to select some elements by their parents parent class.
this is the code the timeline class is the last one i can set myself and i need to be able to edit the .irs-line-right without changing my other sliders
In your question you stated that you want to access an element through a parent element. I don't see why this is necessary, but it's surely possible. You can change the element style, attribute, etc. through js. However, it's best to simply use css if you only need to change the style of the span with the class 'irs-line-right'. I'll show how to do this in both css and javascript.
CSS Example
In css you can change the style of the 'irs-line-right'
by referencing the 'timeline' div (and no other ids or classes) as follows:
https://jsfiddle.net/2t3w0826/
.timeline > div:nth-of-type(2) > span > span > span > span:nth-of-type(3)
{
background-color: red;
}
Javascript Example
https://jsfiddle.net/8qceLgw8/
var array_of_all_timelines = document.getElementsByClassName("timeline");
for(var loop=0; loop < array_of_all_timelines.length; loop++)
{
var element_irs_line_right = array_of_all_timelines[loop].children[1].children[0].children[0].children[0].children[2];
element_irs_line_right.style.backgroundColor = "red";
};

Zebra stripes ignoring hidden elements

Say I have a table whose rows can be dynamically assigned .hidden classes. Rows with that class are hidden via CSS. The rows are also styled with alternating colours, like so:
tr:nth-child(even) {
background-color: $light-grey;
}
However, I want every even, unhidden row to be shaded. So hidden rows are not counted when :nth-child(even) is applied, and the pattern appears consistent. The following is my immediate attempt, but it doesn't do what I'm hoping for.
tr:not(.hidden):nth-child(even) {
background-color: $light-grey;
}
:nth-child() is simply referring to the rows' original indices, not the current selection scope from tr:not(.hidden). The two are simply 'filtered through' on top of one another.
Is there a :nth-of-scope/selection() (or simply :nth()) meta class in CSS? Are there any equivalents or alternate methods?
Or must I resort to Javascript?
(I should say that I can also use jQuery)
There is no way to do this in pure CSS as adding display:none or visibility:none doesn't remove the elements from the DOM, which is what CSS uses.
As a result, you will need to add a little JavaScript (which runs once the page has loaded) to do this, like so
var trs = document.getElementsByTagName("tr"), // Select whichever ones you need
count = 0; // Counter for the non-hidden ones
for(var i = 0; i < trs.length; i++) {
if(!trs[i].classList.contains("hidden") && (count++)%2 == 0) { // Odd ones
trs[i].style.background = "black";
} else if(!trs[i].classList.contains("hidden")) { // Even ones
trs[i].style.background = "lightgrey";
}
}
Turns out using jQuery is much simpler than any sort of CSS hack:
rows = $('table tbody tr');
rows.find('tr:visible:odd').css('background-color', '#f7f7f7');
And to specify styles for both even and odd:
rows.find('tr:visible').each(function(i) {
if (i%2) {
$(this).css('background', '#f7f7f7');
} else {
$(this).css('background', 'none');
};
});
I know, I've answered by own question—I should have made it clear that I can use jQuery!
I just wish :visible and :even would hurry up and make it into the CSS standard.
I've just managed to solve this by just adding an extra <tr> element with display: none; set (via CSS in my case but could use a style attribute) when a block of hidden rows has an odd number of elements. This won't meet every use case, but for cases where you're using multiple rows to create expanding tables it works quite well.
Not sure this is possible with pure CSS. Using display:none; and visibility:hidden; the items still exist in the DOM and so the table background color is displayed incorrectly. You can get this to work using JQuery remove() You can see my simple example on js.fiddle here
Pure CSS (no JS) solution:
The trick is to hide a row with different tag, not class. "ul/li" tags must go. In my example I use "del" tag to hide.
.list div:nth-of-type(odd) { background: ghostwhite; }
.list del { display: none; }
<div class="list">
<div>1</div>
<div>2</div>
<div>3</div>
<del>4</del>
<div>5</div>
<del>6</del>
<div>7</div>
</div>

Issues with addclass and selectors

I'm pretty green with jQuery so I'm sure this is an obvious error - but nonetheless it has me stumped. I'm trying to make a pretty simple navbar that shifts from 500px down the page to absolute positioning at the top after you scroll past it.
The issue: I can't seem to get the js to find the navbar when I'm using a div ID of navbar and a selector of #navbar.
Here is the js:
$(document).ready(function () {
$(window).bind('scroll', function () {
var scrollDepth = 500;
if ($(window).scrollTop() > scrollDepth) {
$('#navbar').addClass('fixed')
} else {
$('#navbar').removeClass('fixed')
}
})
})
Here is a jsfiddle of the issue: http://jsfiddle.net/ayGwn/475/
It is an issue with specificty. A CSS rule for an id will override a CSS rule for a class. If you change the .fixed { ... } to #navbar.fixed { .. } it should work. Assuming you are not using .fixed for anything else.
MDN article about CSS selectors specificty
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style
You should use #navbar.fixed, instead of .fixed only. Because id style gets more priority than class style. In your case javascript is working fine. the .fixed class is being added. But as you have defined position:absolute for you #navbar id, it is overriding style rules for .fixed class.

How come changing background color via JavaScript overrides any CSS selectors on my object?

Just a quick question... how is it that if I have the following CSS:
li { background:red; }
li:hover { background:blue; }
With the following JS (or something similar):
document.getElementsByTagName("li")[0].style.backgroundColor="yellow";
My list elements no longer turn blue when I hover over them? I've tested this both on Chrome and FF. And example can be seen here: http://jsfiddle.net/42bQr/. Any ideas?
This is because inline styes are more specific, you can override inline styles with the following:
li:hover { background:blue !important; }
It's because the style is "inline," which takes priority.
Check out this fiddle here to see what's happening: http://jsfiddle.net/9m3qw/
The output of the fiddle is:
<div class="red-bg" style="background-color: yellow;">hello</div>
The reason is because you are setting the style as an inline style which is the most specific. So when you click on a list item, the result is effectively:
<li style="background-color: yellow;">My List Element 1</li>
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style
To get around this, you could instead assign a class to the list item with:
var listEls = document.getElementsByTagName("li");
for (var i = 0; i <= listEls.length - 1; i++) {
listEls[i].onclick = function () {
this.className = 'yellow'
};
}
where
.yellow {
background:yellow;
}
jsFiddle example
This is happening because you have applied inline style to your selector which has more specifity.
Try this Fiddle
li:hover { background:blue; !important}
If you prefer to use Javascript, then you can use Element ClassList API. But it is only supported in major browsers. Browser Compatibility Matrix. Check out this code
Javascript
var listEls = document.getElementsByTagName("li");
function addYellowClass() {
this.classList.add('bg-yellow');
}
for (var i = 0; i <= listEls.length - 1; i++) {
listEls[i].onclick = addYellowClass;
}
JSBIN Example
As the others have said the inline style takes priority when you click it. You may want to use a hover/mouseover event to add a class ie $(this).addClass('blueBG') with the background of blue that is removed onmouseout if that is the effect you are going for.
"background-color" is more specific than "background" thus it takes priority in your final style. essentially your JavaScript code is overwriting both of CSS properties because it has more weight.
try using background-color as a property in both the CSS and in the JavaScript.

Update CSS rule property value

I have a html element which is styled (using jquery) with a background image targeted thru its class name.
When I remove the class the background image stays - which is not what I expected or want.
test.html
<div id='log' class='tile'>HELLOWORLD</div>
test.css
.tile{
background: none;
}
test.js
$('.tile').css("background-image", "url(tile.jpg)"); // We see image
$('#log').toggleClass('tile'); // We still see image
After banging my head I think I know whats happening. The css is being applied to the element - NOT to the 'class'.
How can I target a specific css rule so that its key values can be updated?
If that makes sense.
If you wan to change the css rules of the ".tile" class, then you can do it.
There is a post that explains it very well :
function changeBackgroundImage(className, value){
var ss = document.styleSheets;
for (var i=0; i<ss.length; i++) {
var ss = document.styleSheets;
var rules = ss[i].cssRules || ss[i].rules;
for (var j=0; j<rules.length; j++) {
if (rules[j].selectorText === className) {
rules[j].style.backgroundImage = value;
}
}
}
}
You can call it like this :
changeBackgroundImage(".tile","url(tile.jpg)");
The problem is that you´re setting the background-image as an inline stlye that overrides any stylesheet rules. Toggling the class won´t have any affect.
You can either have set the background through a styleheet rule and then add a class that removes it;
#log {
background-image: url(tile.jpg);
}
#log.tile {
background: none;
}
or you could just use !important as;
.tile {
background: none !important;
}
...it might be the other way around but you get the point? :)
try removing class tile and applying new class with bg: none
in effect - when needed apply class with bg, when not needed - without
No need for jQuery in this case. You can use plain old JavaScript. Check out this tutorial:
javascriptkit.com - Changing external style sheets using the DOM
You can't change the class itself without re-writing that declaration in the stylesheet, you ARE working only with the element in the selector.
Try:
$('.tile').css("background-image","none")
$('#log').toggleClass('tile',true);
I would make the background image part of the class as a css style:
.tile {background-image: url('tile.jpg')};
and then remove the class when necessary with jquery
$('#log').removeClass('tile');
you could have two classes in your css...
.tile{
background: none;
}
.tile-w-image
{
background-image: url(tile.jpg);
}
and then with jquery just toggle the classes...
$("#log").toggleClass('tile').toggleClass('tile-w-image');
I'm sure this is just one of many ways of doing this. I hope it helps.
You are very close.
It seems like you are adding inline CSS to your element and then trying to toggle the class. You should keep CSS styling separate in most cases:
HTML:
<div id='log' class='tile'>HELLOWORLD</div>
jQuery (I imagine this should be done on click or another event):
$('#log').toggleClass('tile'); // We still see image
If the "tile" class is already written to the HTML, then toggle-ing it will remove it.
CSS:
.tile{
background-image: url(tile.jpg);
}

Categories