3

After having had troubles trying to display three containers in a row with the middle one being centered on the page and the side ones being of a fixed width I came across the CSS Flexbox model, mentioned in a Stackoverflow question.

Using display: flex instead of float: left or displaying the containers as inline-box whilst messing with margin seems to be working quite well, with way fewer lines of code.

However, I ran into an issue with flexbox that I can't seem to solve on my own:

I want a container #menubar to hold three containers in a row: #logo, nav and #search.

<div id="menubar">
    <div id="logo"></div>
    <nav>
        <ul>
            <li><a href="#">Articles</a></li>
            <li><a href="#">Images</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Disclaimer</a></li>
        </ul>
    </nav>
    <div id="search"></div>
</div>

The #logo-container as well as the #search-container are of a fixed size (width: 80px, height: 80px). One should be placed at the very left side of the #menubar-container and one should be placed at the very right.

The nav-container should be centered within the middle of the #menubar-container. Basically the positioning is working and I get the desired layout:

[#logo left]    [nav centered]    [#search right]

However, for some reason the #logo-container is being displayed at the specified dimension of 80px width * 80px height while the #search-container is being displayed at 79px width * 80px height, even through the CSS looks like:

header div#menubar div#logo {
    width: 80px;
    height: 80px;
    background-color: orange;
}

header div#menubar div#search {
    width: 80px;
    height: 80px;
    background-color: orange;
}

To confirm I made a screenshot and zoomed in with Photoshop, selecting the container to view its dimensions.

Layout missing pixel

I can't figure out why the #search-container is missing one pixel in width.

Here is a JSFiddle with the HTML and CSS I am using.

  • Am I using flexbox correctly?
  • How do I fix it so both side-containers are 80x80 pixel in dimensions?
Community
  • 1
  • 1
phew
  • 808
  • 1
  • 15
  • 34
  • 2
    Add `flex-shrink: 0` to both `#logo` and `#search`. See section ***The `flex-shrink` factor*** here: http://stackoverflow.com/a/34355447/3597276 – Michael Benjamin Aug 25 '16 at 14:32
  • I've just tried adding `flex-shrink: 0`, viewing the page in Mozilla Firefox still shows 79px in width for the `#search` container: [JSFiddle](https://jsfiddle.net/as387bhy/3/) – phew Aug 25 '16 at 14:49
  • 2
    In your [revised fiddle](https://jsfiddle.net/as387bhy/3/), both `#search` and `#logo` are 80x80 (computed) in FF, Chrome, Edge and IE11. – Michael Benjamin Aug 25 '16 at 14:54
  • This is odd. I even cleared Firefox' cache and I still get 79px for `#search`. Also tried with Chrome, still 79px for me. Could my screen resolution of 1920x1200 or anything else be the cause? – phew Aug 25 '16 at 15:01
  • 1
    I don't think screen resolution is an issue. I can't reproduce the problem. Getting 80x80 all around. – Michael Benjamin Aug 25 '16 at 15:07
  • Holy cow, it must be "Lightshot", which I was using, to cut off the right-most column of pixels when taking a screenshot. I just viewed the container in the Inspector tool (CTRL+SHIFT+I) and it shows the 80px width :) Thank you for the help, `flex-shrink: 0` does the job even though I go with the "more proper" solution of using `flex: 0 0 80px`. – phew Aug 25 '16 at 15:24
  • 1
    Glad you found your solution. In the link I referred in my first comment, it discusses the advantage of using `flex: 0 0 80px`. Cheers! – Michael Benjamin Aug 25 '16 at 15:25

1 Answers1

3

Am I using flexbox correctly?

Yes and no

Instead of width you should, ideally, be using the flexshorthand property combining, flex-grow, flex-shrink and flex-basis.

header div#menubar div#logo {
    flex: 0 0 80px;
    height: 80px;
    background-color: orange;
}

Alternatively, you can ensure that the element doesn't shrink by using width AND the flex-shrink value of 0

* {
  margin: 0;
  padding: 0
}
body {
  background-color: #dfe3e5;
}
header div#top {
  height: 22px;
  /*background-image: url('../img/colorbar.png');
    background-position: top left;
    background-repeat: repeat-x;*/
  background-color: gray;
}
header div#menubar {
  background-color: #1c2227;
  display: flex;
  justify-content: space-between;
}
header div#menubar div#logo {
  flex: 0 0 80px;
  height: 80px;
  background-color: orange;
}
header div#menubar nav {
  display: table;
  text-align: center;
  background-color: darkred;
}
header div#menubar nav ul li {
  display: inline-block;
  margin-left: -4px;
  list-style-type: none;
  line-height: 80px;
  text-align: center;
}
header div#menubar nav ul li a {
  outline: 0;
  display: block;
  text-transform: uppercase;
  padding: 0px 20px;
  font-size: 1.1em;
  font-family: 'Raleway', "Trebuchet MS", Arial, Helvetica, sans-serif;
  color: #eee;
  text-decoration: none;
}
header div#menubar nav ul li a:hover {
  color: #000;
  background-color: orange;
}
header div#menubar div#search {
  flex: 0 0 80%;
  height: 80px;
  background-color: orange;
}
<header>
  <div id="menubar">
    <div id="logo"></div>
    <nav>
      <ul>
        <li><a href="#">Articles</a>
        </li>
        <li><a href="#">Images</a>
        </li>
        <li><a href="#">About</a>
        </li>
        <li><a href="#">Disclaimer</a>
        </li>
      </ul>
    </nav>
    <div id="search"></div>
  </div>
</header>

Then you get the right result

enter image description here

Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • Thank you for the information, I'm going with your primary suggestion of using `flex: 0 0 80px`. Seems to be displaying fine now! – phew Aug 25 '16 at 15:26