Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

CSS

Tom Nunn
Tom Nunn
16,333 Points

Help Needed with :nth-child Selector

Hi all,

I need a little help with finding the correct :nth-child selector. I have inserted a link to a screenshot, where I am trying to stack these logos into 3 columns using pseudo classes.

Here is my code so far:

    .home-showcase .one-sixth {
        float: left;
        width: 31.623931623931625%
        margin-left: 2.564102564102564%;
    }

    .home-showcase .one-sixth:nth-of-type(3n+1) {
        clear: both;
        margin-left: 0;
    }

Any ideas?

http://s17.postimg.org/yx0vp5zrz/responsive_css3_help.png

Hi Tom,

3n + 1 is the correct expression for a 3 column grid so the problem is likely to be something else.

Can you explain what is going on with the html because it seems inconsistent? The first six div's are in a row-one div but the next 6 are not.

Structural pseudo classes are dependent upon the structure of the html so it's important to get that right.

The one-sixth class seems misleading since each one is taking up about a third of the space or I have misunderstood what you're trying to do.

Are these images background images on the div's?

What's happening with the .first class?

Tom Nunn
Tom Nunn
16,333 Points

Hi Jason,

Yes, I should have explained the HTML, I feel like I was cheating a little here. If you look at the screenshot below, I had to add a DIV for the first 6 Logo's to apply the following:

.home-showcase .row-one img {
    margin-bottom: 14px;
}

and the .first class adds the following:

.first {
    clear: both;
    margin-left: 0;
}

In terms of the one-sixth class, this is from Bootstrap Column Classes (http://twitter.github.io/bootstrap/assets/css/bootstrap-responsive.css), I understand this can seem misleading when adding responsive declarations.

You nailed it though, I removed the row-one class and now the logos stack nicely into 3 columns. Which leads me to wondering how I can add margin-bottom to the first 6 logos.

http://s12.postimg.org/bgqaq2kn1/showcase_logos.png

2 Answers

Edit: I mixed up "row" and "div" in the 3rd paragraph. "...the first row in each div" should be "...the first div in each row"

The bootstrap link didn't work, it only took me to the main bootstrap page for an older version.

Do you specifically need the images to have a bottom margin or are you only trying to get space between the rows?

Since you have the first div in each row clearing the previous floats it should be enough to assign a bottom margin to the first div in each row.

Also, the "first" class probably isn't necessary since those elements can be targeted with the proper nth-child expression.

If you really need to select the first 6 div's only to target the images then that could be done with

.one-sixth:nth-of-type(-n+6)

That is saying to start with the 6th div and then everyone before it, i.e. the first 6.

But is there a 3rd row, 4th row, etc..? Or do you only have 12 images?

Does that help? I can offer more suggestions but I'm still not totally sure what the overall goal is.

The best I can gather from the screenshots and html/css posted is that you want 3 columns at mobile size and 6 columns at desktop sizes? If that's true then I can try to give you the basic css you could use to accomplish this.

Tom Nunn
Tom Nunn
16,333 Points

Cheers Jason,

Yes there is only 12 Images in total, 2 Rows and 6 Columns on Desktop, 3 Columns below 768px and then 2 Columns below 480px.

I've just added margin-bottom to each div/image to create the space, It seems to working okay and looks good. If you wanted to suggest an alternative, that would be great!

Thanks for your help Jason!

You're welcome.

I just thought of something else before I come up with a basic demo.

Do the div's only have an img element in them and are all images in the same aspect ratio? What I'm getting at is whether the div's are all the same height or is there a possibility they will have different heights?

The float clearing is really only necessary if the div's are different heights.

Tom Nunn
Tom Nunn
16,333 Points

Yes, all the images are the same dimensions :)

Hey Tom,

Here's a demo of the basic css (framework agnostic) that you could use to accomplish the layout you describe: https://codepen.io/anon/pen/RrOeMo

It's not necessarily the best or only way to do it but I don't think it's a bad way to go. It doesn't require extra html markup and you don't have to worry about assigning the "first" class to the correct elements.

I'm not sure if you can incorporate this into your project or not.

Let me know if you have any questions about it.

Tom Nunn
Tom Nunn
16,333 Points

Thanks Jason, much appreciated!

Tom Nunn
Tom Nunn
16,333 Points

Hi Jason,

I'm having some difficulties trying to stack the divs into two columns, I have the following:

    .home-showcase .one-sixth {
        width: 48.717948717948715%;
    }

    .home-showcase .one-sixth:nth-of-type(odd) {
        clear: none;
        margin-left: 0;
    }

It seems the code is still taking the (3n+1) declaration from the larger media query (768px). Screenshot URL: http://s16.postimg.org/x7o2ik8cl/Screen_Shot_2016_02_18_at_14_19_02.png

Which I'm struggling to overwrite...

Any ideas?

I see 2 columns in the screenshot.

First off, I would get rid of the "first" classes because they are only really correct for the 6 column layout and it might be unnecessarily complicating this.

One thing is that it looks like you are taking a desktop first approach and the codepen demo is mobile first. So everything is going to be reversed but same overall principle.

Basically, in each media query, you need to select the previous pattern and set clear and margin-left back to what they should be for all items and then you select the new pattern for the current number of columns and do clear left and the margin to 0.

Each subsequent media query follows that process. I forked the previous demo and reversed it to a desktop first approach which should help you figure this out. https://codepen.io/anon/pen/WrBrZr

I've included below the last media query with comments to explain the process you want to follow.

@media (max-width: 375px) {
  div {
      width: 48.75%;
  }

/* Select the previous 3 column pattern and set properties back to what they should be for all items */
/* I think this is the step you're missing in your most recent comment. */
/* When this media query kicks in the 768px media query is still active. If there are any styles
in there that you no longer want then you have to override them in this media query */
/* That's what's happening in the following rule. You no longer want the 3n + 1 items to be clearing the floats and having a zero margin. This will mess up the 2 column layout. */
  div:nth-of-type(3n + 1) {
    margin-left: 2.5%;
    clear: none;
  }

/*  Now select the 2 column pattern and zero out the margin and clear the floats. */
  div:nth-of-type(odd) {
    margin-left: 0;
    clear: left;
  }
}

This same process applies to the previous 768 breakpoint but with different patterns. You can check that in the demo.

Let me know if that helps clear it up for you.

Tom Nunn
Tom Nunn
16,333 Points

Perfect Jason,

This makes much more sense now and will help me in future projects!

Nicholas Grenwalt
Nicholas Grenwalt
46,626 Points

Not sure exactly which ones you are trying to target based on what you have stated. But I'll help you better understand the nth-child-selector. As you have it now you are targeting the 1st element and every third element after that (1, 4, 7, 10). The single number on the right always acts as the number at which you want to start out at and the left side defines the rule thereafter. So, for example, 4n + 2 would target the 2nd item and then each 4th item after that (6,10). Hope that provides some clarification.

Tom Nunn
Tom Nunn
16,333 Points

Thanks Nicholas!