2

I would like to achieve this fully justified horizontal menu: enter image description here

Justifying is done with flexbox and works, but I could not get the separating mid-dots justified, too; they are made by using css-content via pseudo-class. Also, I am wondering if there's a better way to vertically center the items than faking it by adding a padding as I have done it.

Here's my code and the fiddle:

ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: space-between;
}
li.home {
  padding: 0;
}
li {
  vertical-align: middle;
  padding-top: 10px;
}
nav {
  border-bottom: 1px solid black;
  border-top: 1px solid black;
  height: 40px;
}
li::after {
  //padding: 0em 0.4em;
  content: '\00b7';
  pointer-events: none;
}
li.home::after,
li.last::after {
  content: none;
  text-align: justify;
}
<nav id="main-menu">
  <ul>
    <li class="home">
      <a href="/de"><img src="http://dummyimage.com/40x40/000/fff"></a>
    </li>
    <li class="second"><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">One more Item</a></li>
    <li><a href="#">Another Item</a></li>
    <li class="last"><a href="#">Contact</a></li>
  </ul>
</nav>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Madamadam
  • 842
  • 2
  • 12
  • 24

2 Answers2

5

body { margin: 0; }                              /* 1 */

nav {
  height: 40px;
  border-bottom: 1px solid black;
  border-top: 1px solid black;
}

ul {
    display: flex;
    justify-content: space-between;              /* 2 */
    align-items: center;                         /* 2 */
    height: 100%;
    list-style: none;
    padding: 0;
    margin: 0;
}

li:not(.home) {
    flex: 1;                                      /* 3 */
    height: 100%;
    border: 1px dashed red;                       /* 4 */
    background-color: lightgreen;                 /* 4 */
}

li:not(.home) > a {                               /* 5 */
    display: flex;                    
    justify-content: center;
    align-items: center;
    height: 100%;
}

li img { vertical-align: bottom; }                /* 6 */

li { position: relative; }                        /* 7 */

li:not(.home):not(:last-child)::before {          /* 8 */
    position: absolute;
    content: '\26AB';                             /* 4 */
    left: 100%;
    top: 50%;
    transform: translate(-50%,-50%);
    z-index: 1;
    pointer-events: none;        
}
<nav id="main-menu">
  <ul>
    <li class="home">
      <a href="/de"><img src="http://dummyimage.com/40x40/000/fff"></a>
    </li>
    <li class="second"><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">One more Item</a></li>
    <li><a href="#">Another Item</a></li>
    <li class="last"><a href="#">Contact</a></li>
</ul>

jsFiddle

Notes:

  1. Remove default margins on body element
  2. Methods for Aligning Flex Items
  3. Consume all remaining space with flex-grow property
  4. Borders, background colors, and larger bullets for illustration purposes only
  5. Enable anchor elements to fully cover list item space and align text with flex properties
  6. Remove baseline alignment (i.e., whitespace underneath image)
  7. Establish nearest positioned ancestor for absolute positioning
  8. Use absolute positioning to align bullets
Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

You can vertically center the items with align-self: center; but the dot separators are in my opinion impossible to achieve with pseudo elements like :before or :after.

I would recommend to use separate <li> tags for separators like below:

Note that your image element needs display: block; to have a proper height.

ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: space-between;
}
img {
    display: block;
}
li.home {
  padding: 0;
}
li {
  align-self: center;
}
nav {
  border-bottom: 1px solid black;
  border-top: 1px solid black;
  height: 40px;
}
<nav id="main-menu">
  <ul>
    <li class="home">
      <a href="/de"><img src="http://dummyimage.com/40x40/000/fff"></a>
    </li>
    <li class="second"><a href="#">Item 1</a></li>
    <li class="separator">·</li>
    <li><a href="#">Item 2</a></li>
    <li class="separator">·</li>
    <li><a href="#">One more Item</a></li>
    <li class="separator">·</li>
    <li><a href="#">Another Item</a></li>
    <li class="separator">·</li>
    <li class="last"><a href="#">Contact</a></li>
  </ul>
</nav>

Fiddle version

pmate
  • 181
  • 8