Select odd even child excluding the hidden child
Pseudo-selectors don't stack, so your :not
doesn't affect the :nth-child
(nor would it affect :nth-of-type
etc.
If you can resort to jQuery, you can use the :visible
pseudo-selector there, although that's not a part of the CSS spec.
If you're generating the HTML and can change that, you can apply odd/even with logic at run-time, eg in PHP:
foreach ($divs AS $i => $div) {
echo '<div class="box ' . ($i % 2 ? 'even' : 'odd') . '">x</div>';
}
Even trying to do something tricky like
.box[class='box']:nth-of-type(even)
doesn't work, because the psuedo-selector doesn't even stack onto the attribute selector.
I'm not sure there's any way to do this purely with CSS - I can't think of any right now.
How to get nth-child selector to skip hidden divs
When the user clicks on a button, I hide few blocks by
display:none
,
and the problem occurs. Thenth-child
selector also counts hidden
elements.Is there way to ignore those specific blocks, so that again every row
has different style?
The problem is that the nth-child()
selector looks at all siblings under the same parent regardless of styling. It doesn't matter that you've applied display: none
because CSS doesn't remove the element from the DOM, and therefore it's still a sibling.
From the spec:
6.6.5.2.
:nth-child()
pseudo-classThe
:nth-child(an+b)
pseudo-class notation represents an
element that has an+b-1 siblings before it in the document
tree, for any positive integer or zero value of n, and has a parent
element. (emphasis mine)
In order for the nth-child
rules you've declared to work after a user clicks to hide divs, you need to remove the hidden divs from the DOM, so they no longer exist as siblings.
In your question you request a CSS-only solution. But in your comments you say that the HTML is open for changes. You also use a bit of jQuery to hide elements.
With one small line of code added to your jQuery the problem can be solved:
$('.hidden').remove();
The .remove()
method takes elements (and its descendants) out of the DOM. In this case it removes all elements with a class hidden
.
CORRECTION
The problem with remove()
is that elements taken from the DOM with this method can't be restored, and this breaks the toggle function.
Fortunately, jQuery offers an alternative: detach()
.
The
.detach()
method is the same as.remove()
, except that
.detach()
keeps all jQuery data associated with the removed
elements. This method is useful when removed elements are to be
reinserted into the DOM at a later time.
So if we replace the original code...
$('.hide-others').click(function () {
$('.css--all-photo').toggleClass('hidden');
})
...with this code...
var divs;
$('.photos-board-item').each(function(i){
$(this).data('initial-index', i);
});
$('.hide-others').on('click', function () {
if(divs) {
$(divs).appendTo('.row').each(function(){
var oldIndex = $(this).data('initial-index');
$('.photos-board-item').eq(oldIndex).before(this);
});
divs = null;
} else {
divs = $('.css--all-photo').detach();
}
});
... the grid works as intended. (code credit: @JosephMarikle)
DEMO
Now, regardless of which divs or how many are hidden, they can be toggled on and off without disrupting the visual design because the nth-child
selector is counting only "visible" siblings. No changes to the CSS. No changes to the HTML.
:nth-child(even/odd) selector with class
In general what you want is not possible, but there is a way to achieve the desired behavior for limited numbers of "excluded" elements: the general sibling combinator ~
.
The idea is that for each occurrence of a non-.parent
element subsequent .parent
elements will have their colors toggled:
.parent:nth-child(odd) {
background-color: green;
}
.parent:nth-child(even) {
background-color: red;
}
/* after the first non-.parent, toggle colors */
li:not(.parent) ~ .parent:nth-child(odd) {
background-color: red;
}
li:not(.parent) ~ .parent:nth-child(even) {
background-color: green;
}
/* after the second non-.parent, toggle again */
li:not(.parent) ~ li:not(.parent) ~ .parent:nth-child(odd) {
background-color: green;
}
li:not(.parent) ~ li:not(.parent) ~ .parent:nth-child(even) {
background-color: red;
}
See it in action.
Of course there is a limit to how far one would be willing to take this, but it's as close as you can get with pure CSS.
How do you apply CSS to odd/even visible rows after a javascript function has been used to filter out some rows? (incorrectly flagged as duplicate)
Instead of changing the display propriety add/remove a class
tr[i].classList.add("active");
tr[i].classList.remove("active");
So then you can simple change the css like so
tr.active {
display: block;
}
tr {
display: none;
}
tr.active:nth-child(even){
background-color: #F6F6F6
}
tr.active:nth-child(odd){
background-color: #EEEEEE
}
As Stephen P pointed out my original answer was wrong, it look like ntl-child ignores the class, so a suggestion to solve this can be something like the following, for simplicity, as MarsAndBack said you can split this into multiple functions.
function Filter(n) { var input, filter, table, tr, td, i, txtValue, count; input = document.getElementById("searchbox" + n); filter = input.value.toUpperCase(); table = document.getElementById("mytable"); tr = table.getElementsByTagName("tr"); for (i = 0, count = 0; i < tr.length; i++) { td = tr[i].getElementsByTagName("td")[n]; if (td) { txtValue = td.textContent || td.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { tr[i].style.display = ""; if (count++ % 2 == 0) { tr[i].style.background = "#F6F6F6"; } else { tr[i].style.background = "#EEEEEE"; } } else { tr[i].style.display = "none"; } } }}
tr:nth-child(even){ background-color: #F6F6F6}
tr:nth-child(odd){ background-color: #EEEEEE}
<table id="mytable"> <tr> <th> <div>A</div> <input id="searchbox0" type="text" onkeyup="Filter(0)" placeholder="Filter.."> </th> <th> <div>B</div> <input id="searchbox1" type="text" onkeyup="Filter(1)" placeholder="Filter.."> </th> </tr> <tr> <td>04718J00065</td> <td>2100305513</td> </tr> <tr> <td>29417J01131</td> <td>2100305513</td> </tr> <tr> <td>07416J01979</td> <td>2100029648</td> </tr> <tr> <td>02518J01169</td> <td>2100030939</td> </tr></table>
p:nth-child(even) and p:nth-child(odd) losing count with intermediate div's placed after a few p 's
I think you probably want the functionality of nth-of-type
instead of nth-child
based on what you're describing. Article on the difference here https://css-tricks.com/the-difference-between-nth-child-and-nth-of-type/
Your example: https://jsfiddle.net/nh16ytq7/
Related Topics
Why Doesn't [CSS Feature] Work in [Browser] But Works in Others
How to Use CSS to Position a Fixed Variable Height Header and a Scrollable Content Box
How to Apply Border Radius in IE8 and Below IE8 Browsers
How Do Browsers Read and Interpret CSS
First-Child Full-Width in Flexbox
Inner Border Over Images with CSS
How to Code CSS Media Queries Targeting All Mobile Devices and Tablets
How to Apply a Style to All Children of an Element
Does Less Have an "Extend" Feature
What Does @-Moz-Document Url-Prefix() Do
Bootstrap Table Striped: How to Change the Stripe Background Colour
Google Maps V3 - Prevent API from Loading Roboto Font
Bootstrap Modal Sitting Behind Backdrop
Why Is Backface-Visibility Hidden Not Working in Ie10 When Perspective Is Applied to Parent Elements