5

I have successfully used the jQuery :nth-child() selector to remove the right margin from every fourth element in a long list of div's. It looks like this:

$(".myDivClass:nth-child(4n+4)").css("margin-right", 0);

But the page is also open for user interaction (via jQuery) and one of the things that the user can do is hide/show elements. When an element is hidden, its style is set to "display:none". The elements are floated so if you remove one element in the middle of a row, an element from the row below will jump up, like this:

Problem with margin when an element is removed

My first thought was to redo the whole thing by first adding a margin to all elements and then remove it from every fourth visible element; something like this:

$(".myDivClass").css("margin-right","20px");
$(".myDivClass:visible:nth-child(4n+4").css("margin-right", 0);

But the second row does nothing and I don't think you can stack pseudo selectors like in the example above(?)

Is there a solution to this problem? Is there a better way to do this?

Thanks in advance!

/Thomas

tkahn
  • 1,407
  • 2
  • 21
  • 37
  • Maybe try using a class that you add and remove to make it easier to target? And yes you should be able to stack pseudo selectors – Mottie Jan 24 '11 at 15:21

2 Answers2

5

I know this isn't directly an answer to your question, but when I do similar things with floating a bunch of block elements with some spacing between them, I usually will keep the margin on all of them but make their parent container have (in this case) a negative margin-right equal to the spacing between the elements.

This way the parent will still fit where you want it but the children will just float as they should with the space they need.

nemophrost
  • 567
  • 1
  • 8
  • 11
  • This would work just fine for me as the solution I'm looking for is merely for layout purposes. I'll try this! – tkahn Jan 25 '11 at 07:50
  • I tried this and the layout works, but I still get a horizontal scrollbar in the browser window indicating that the container is wider than it should be? – tkahn Jan 26 '11 at 07:55
  • Perhaps putting the container in another wrapper div. This perhaps with overflow: hidden;? Hard to say for sure without any code to test. – nemophrost Jan 26 '11 at 16:48
1

Hmm, ok the nth-child() selector seems to not function as it should. It seems to ignore the hidden elements. So you may have to .remove() or .detach() the closed elements. Here is a demo, but it modifies the border instead of the margin to make it more visible for demo purposes.

$('.box:visible:nth-child(5n+5)').addClass('noSide');

$('.close').click(function() {
    // needs to be removed or detached because the nth child
    // appears to ignore hidden elements
    $(this).parent().detach();
    $('.noSide').removeClass('noSide');
    $('.box:visible:nth-child(5n+5)').addClass('noSide');
});
Mottie
  • 84,355
  • 30
  • 126
  • 241
  • It actually works just as intended. As this answer points out — http://stackoverflow.com/questions/2175694/jquery-nth-child-that-is-currently-visible — the docs state: "With :nth-child(n), all children are counted, regardless of what they are […]". – polarblau Jan 24 '11 at 16:43
  • Yes, I think the :nth-child() selector is working as it should and as polarblau points out, the problem in my case is that it counts elements that are hidden, not that it ignores them. In any case, I don't think I can use remove() or detach() since I need to be able to display the elements again at the same position if the user chooses to show them again. – tkahn Jan 25 '11 at 07:55