When the user clicks on a button, I hide few blocks by display:none
,
and the problem occurs. The nth-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-class
The :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.