Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

CSS Build a Responsive Navigation with Flexbox

jsdevtom
jsdevtom
16,963 Points

Why do my links move themselves on click? (GIF included)

This is the problem:

Problem

After a lot of time diagnosing the problem I know what aspect of my CSS is causing this:

.nav a {
        margin: 10%;
    }

BUT WHY?! w3schools says that margins with a % value "Specify a margin in percent of the width of the containing element".

The containing element has the following CSS:

.nav li {
        margin-left: .65em;
        margin-right: .65em;
    }

I also commented all of the JavaScript out, so I know its not that....

Any clues are appreciated :-)

EDIT Steven Parker and Ben Attenborough thank you for your comments, here is the code pen:

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

Line 203 of the CSS is the above mentioned problem (under a media query so make sure you use the middle Editor Layout in Codepen). I am only using hover states on the li items (as far as I can see/remember).

Steven Parker
Steven Parker
231,248 Points

Could you give a bit more of the code, at least enough to replicate the issue?

2 Answers

Steven Parker
Steven Parker
231,248 Points

I was intrigued, so I did a little experimenting. I was able to reproduce your results using this CSS:

style.css
ul.nav {
  display: flex;
  justify-content: flex-end;
}
.nav li {
  list-style: none;
  margin: 0 .65em;
}
.nav a {
  margin: 10%;
}

and this HTML:

code.html
  <ul class="nav">
    <li><a href="#">Typography</a></li>
    <li><a href="#">Button</a></li>
    <li><a href="#">Form</a></li>
    <li><a href="#">Images</a></li>
    <li><a href="#">Grid</a></li>
    <li><a href="#">Navigation</a></li>
  </ul>

I noticed that the initial spacing of the elements is wrong. Clicking causes the spacing to become correct (sometimes only after multiple clicks!), but I'm not sure why. However, the main concern is why is it displayed wrong to start with.

A percentage margin is calculated on the size of the parent element, in this case a flex item, which has a size and position resulting from another calculation. I'm guessing the actual displayed size has to do with the order in which the calculations are done, and this may be altered somewhat during the operations performed on a click.

I also noticed that when the sizes are wrong, the anchor content actually overflows the list item. You can see this if you add overflow:hidden; to the list items. This leads me to think that the margin on the anchor is being overlooked when the size of the list item is being calculated.

I'm leaning towards this being an internal bug in the CSS, but I have to admit that the concept of having the total size of an element and margins dependent on the size of a parent which sizes itself to wrap its contents, is a tough task for the CSS to handle in any case.

In practice, I would resolve this by setting the margin exclusively in the list item, completely avoiding any order-dependent or recursive calculations.

jsdevtom
jsdevtom
16,963 Points

Wow, thank you for isolating the problem this much! You are right, the problem is caused when an a tag and it's parent element has a margin that is calculated. I went on to eliminate the possibilities that it is in relation with inline-block, flexbox or lists. As you can see in this Codepen.

Ben Attenborough
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Ben Attenborough
Front End Web Development Techdegree Graduate 32,769 Points

Are you using any hover states, looks like the elements change when you hover over them.

Also seeing the html markup would help. It looks like you are mixing selectors a bit. Try targeting the li item OR the link but not both.