EarthIsHome
EarthIsHome

Reputation: 735

Trying to center an image within a flex item using flexbox. What's going on here?

I'm trying to center an image in the fixed nav menu of a flex item. I've tried using the justify-content: center; command, but I don't think it did anything.

Below is the CSS and abbreviated HTML. Codepen: http://codepen.io/anon/pen/XmQQgb

CSS:

body {
  padding:0;
  margin:0
}

.wrapper {
  display: flex;
}

nav { 
  flex: 0 0 300px;
  background: gray;
}
.nav-wrapper {
  position: fixed;
  top: 0; left: 0;
}

section {
  flex: 1 1;
  padding: 20px;
}

.navImage {
  display: block;
  margin: 0 auto;
}

HTML

<div class="wrapper">
  <nav role="navigation">
    <div class="nav-wrapper">
      <img class="navImage" width="100" height="100" src="https://upload.wikimedia.org/wikipedia/commons/5/56/Run.svg">

      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Clients</a></li>
        <li><a href="#">Contact Us</a></li>
      </ul>
      <blockquote><i>Please, make me fixed!</i></blockquote>
    </div>
  </nav>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero.</p>
  </section>
</div>

Upvotes: 1

Views: 882

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371231

The width of your nav element is 300px.

nav { 
    flex: 0 0 300px;
    background: gray;
}

The width of your .nav-wrapper element (the child of nav) is undefined.

.nav-wrapper {
    position: fixed;
    top: 0;
    left: 0;
} 

Because .nav-wrapper has position: fixed it is taken out of the normal flow of the document and has a default width of 0, which will expand only enough to wrap content.

As the width of .nav-wrapper is limited to the width of the content, centering occurs within this limited space. If you add a border around .nav-wrapper, you'll see that the image is actually perfectly centered... within the available width.

DEMO

To center the image along the full width of the nav column you could specify a width for .nav-wrapper equal to the width of nav.

Try this:

.nav-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    width: 300px; /* new */
}

So essentially you were almost there. You just needed one more line of code.

DEMO


Addressing the justify-content issue...

Defining the Flex Items

You've set the outer container (.wrapper) to display: flex, which makes it a flex container.

This converts the child elements of .wrapper into flex items. In other words, nav and section become flex items.

Note that the descendents of a flex container beyond the children are not flex items and flex properties don't apply to them. Hence, any flex code added to .nav-wrapper or .navImage would be ignored, unless their parents became flex containers.

justify-content

The justify-content property won't work in your current code for these reasons:

  1. The img element is not a flex item (as described above), so flex properties won't apply to it.

  2. Even if you make the img parent (.nav-wrapper) into a flex container, justify-content may not be a good solution because img has two siblings: ul and blockquote, and all three would be centered with justify-content.

  3. If you wanted to make img (and its siblings) flex items, then it may be more efficient to use a column-direction, not a row-direction, flex container. In this case, you wouldn't use justify-content for horizontal centering. You would need to use align-items or align-self. Learn more about the main axis, the cross axis and alignment properties.

Upvotes: 2

Related Questions