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

Help positioning 3 rows of List Items

Howdy,

I'm trying to position 3 rows of list items I have styled as circles.

I made a codepen here: http://codepen.io/45519/pen/HzcAe/

I want three on the first row, then two, then one, stacked on top of each other. I successfully got it to break using nth-last-child and changed that to block, but when I try to select the 4th LI and reset to inline-block, it puts it right back to the first line.

I want it to look like:

3 black circles 2 red circles 1 blue circle

I don't want to use floats or javascript.

Thanks!

Emma Willmann
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Emma Willmann
Treehouse Project Reviewer

So, just clarifying...Are you wanting the 2nd and 3rd rows centered under the first, or justified left?

1 2 3 4 5 6

1 2 3 4 5 6

4 Answers

If you can allow a width to be set on the ul then set it wide enough to contain 3 circles. Then next 3 circles will be on the next line because there's not enough room. Then give the 5th circle a little margin on the right so that there's not enough room for the blue circle.

http://codepen.io/anon/pen/guoiw

This is kind of the opposite idea as what you might do if you had a grid of items. Each item might have a right margin to space them apart but then you want to remove that margin on the last item in each row so it has room to fit and doesn't drop to the next line. In this case, we don't want it to fit.

Also, you didn't say if absolute positioning was ok. You could certainly position them all that way too.

Luke Buśk
Luke Buśk
21,598 Points

Interesting solution, thank You. Makes it easier for me to understand positioning and block elements.

Hello,

Since you are using only one ul, the outcome you are experiencing is the expected result. It has to do with the CSS rules you used.

.frisbee ul li {
    display: inline-block;
}

This will take all of the lis and put them inline. Your next rules cannot achieve want you want them to.

.frisbee ul li:nth-last-child(-n+3) {
    display block;
}

This CSS rule will take the selected children, and makes each one a block level element, which causes the second "row" you are wanting.

Note: The :nth-last-child(-n+3) selector starts from the last child, moves three elements toward the beginning, and then counts back toward the end again. The same effect can be achieved by counting from the beginning in the first place. :nth-child(n+4) yields the same result.

The moment you apply your next CSS rule, you are putting the selected li back inline.

.frisbee ul li:nth-child(4) {
    display: inline-block;
}

There are a couple ways you can achieve what you want:

1. Use more uls

HTML:

 <div class="frisbee">
     <ul>
        <li></li>
        <li></li>
        <li></li>
     </ul>      
     <ul>
        <li></li>
        <li></li>
     </ul>
     <ul>
        <li></li>
     </ul>
 </div>

CSS:

// This is for that 50px margin you had.
.frisbee {
    margin-top: 50px;
}

.frisbee ul {
    list-style: none;
    margin: 0;
}

.frisbee ul li {
    display: inline-block;
    width: 50px;
    height: 50px;
    margin: -3px;
    background-color: black;
    border-radius: 50%;
}

.frisbee ul:nth-child(2) li {
    background-color: red;
}

.frisbee ul:nth-child(3) li {
    background-color: blue;
}

2. Use float and clear

HTML:

 <div class="frisbee">
    <ul>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
   </ul>
 </div>

CSS:

ul {
    list-style: none;
    margin: 50px 0px;
}

.frisbee ul li {
    float: left;
    width: 50px;
    height: 50px;
    margin: -3px;
    background-color: black;
    border-radius: 50%;
}

.frisbee ul li:nth-child(4) {
    background-color: red;
    clear: left;
}

.frisbee ul li:nth-child(5) {
    background-color: red;
}

.frisbee ul li:nth-child(6) {
    background-color: blue;
    clear: left;

1 does change the structure of the document which may or may not be a concern.

I need to write support about editing comments it seems to be broken.

Sorry, I used # and it made an h1 I think. I wasn't shouting or anything like that.

This is super awesome. Thanks for the help.

Emma, I was just trying to get them to swing to the next line, but still be inline. I figured I'd tool around with them to get them to be in the exact place once I figured that part out.

Rand, thanks for the advice. I was trying to avoid both those scenarios. The reason I didn't want to use floats is because I have this div sitting on top of a bunch of other divs, and many of them are using ::before and ::after, so I didn't want to have to figure out which one was collapsing or how to apply the clear to generated content. In other words, I was being lazy. But I can see how those would be helpful though.

Jason, thanks for the tip! I totally did not even think about using width on that ul. That solution looks like it will solve my problem, so I really appreciate it!

Thanks!

jon

Emma Willmann
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Emma Willmann
Treehouse Project Reviewer

So, just clarifying...Are you wanting the 2nd and 3rd rows centered under the first, or justified left?