0

Building out a navbar that will look something like this:

|----------------------------------------------------------|
|                  link     Logo     link            link  |
|----------------------------------------------------------|

My thought process for creating this layout is to have a html structure that looks like:

<nav>
  <div></div>
  <div>
    link
    logo
    link
  </div>
  <div>
    link
  </div>
</nav>

and then with CSS, I would do something like:

display: grid;
grid-template-columns: 200px auto 200px;
...

My question here is: is there a better way to recreate this layout? I don't like how I use an empty div to create the space.

I know I can remove the empty div and put something like margin-left: 200px on the 2nd div but that seems kinda hacky as well.

Appreciate the input.

sssyn
  • 61
  • 1
  • 8

3 Answers3

1

From the comments from the original question, I was able to find the grid-column-start property and that was exactly what I needed. I appreciate everyone commenting but I feel like the ones saying to use a library/frameworks to build a navbar is overkill. Knowing how to actually build these layouts are what makes you a better developer.

This is what I ended up doing:

<div class="navbar">
    <div class="navbar--content">
        <div class="navbar--content--middle">
            <div class='row row__align-center row__center'>
                <a href="#">shop now</a>
                <a href="#">logo</a>
                <a href="#">FAQ</a>
               </div>
        </div>
        <div class="navbar--content--right">
            <a href="#">user img</a>
            <a href="#">bag</a>
        </div>
    </div>
</div>

And the css:

.navbar {

    &--content {
        padding: 20px 0;

        display: grid;
        grid-template-columns: 200px auto 200px;
        align-items: center;

        &--middle {
            grid-column-start: 2;

            a {
                width: 100px;
                text-decoration: none;
                font-weight: 600;

                &:first-child {
                    margin-right: 100px;
                }

                &:nth-child(2) {
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: center; 
                }

                &:last-child {
                    margin-left: 100px;
                }
            }
        }

        &--right {
            text-align: right;

            a {
                &:first-child img {
                    height: 30px;
                    margin-right: 10px; 
                }

                &:last-child img {
                    height: 35px;
                }
            }
        }
    }
}
sssyn
  • 61
  • 1
  • 8
0

This is a tricky design. You have to use multiple concept of CSS to achieve this design for example pseudo and position absolute will help you. You can check with other framework but again as per your design you need to write custom CSS as per limitation. I have written optimized CSS & markup of this design for you using pseudo elements and "position:absolute" for the fourth div. Please try code (you can change width of nav as per your requirement) and let me know if you need any more information or have any queries. Thanks in advance.

nav {
        width: 100%;
        max-width: 600px;
        margin: 0 auto;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;   
        position: relative;
        border-top: .05em #000 dashed;
        border-bottom: .05em #000 dashed; 
      }

      nav .lft-rgt-seperator {
        position: absolute;
        width: 103%;
        height: 14px;
        border-top:4px solid #fff;
        border-bottom:4px solid #fff;
        top: 50%;
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
        z-index: 2;
      }


      nav:before {
        content:"";
        width:.05em;
        height: 49px;
        position: absolute;
        top: -6px;
        left: -4px;
        background: #000;
      }

      nav:after {
        content:"";
        width:.05em;
        height: 49px;
        position: absolute;
        top:-6px;
        right:-4px;
        background: #000;
      }

      nav ul {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        width: 100%;
        z-index: 4;
      }

      nav ul li {
        margin: 8px 15px;
      }

      nav ul li a, nav .lftlink a {
        color: #000;
        text-decoration: none;
        font-size:18px;
        cursor: pointer
      }

      nav ul li a:hover, nav .lftlink a:hover {        
        text-decoration: underline;
      }

      nav .lftlink {
        position: absolute;
        right:20px;
        top: 50%;
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
        z-index: 5;
      }
<nav>     
      <div class="lft-rgt-seperator">
      </div>

        <ul>
          <li>
            <a href="#" title="Link">Link</a>
          </li>
          <li>
            <a href="#" title="Logo">Logo</a>
          </li>
          <li>
            <a href="#" title="Link">Link</a>
          </li>    
        </ul>

        <div class="lftlink">
            <a href="#" title="Link">Link</a>
        </div>
    </nav>
Himanshu Joshi
  • 292
  • 2
  • 10
  • I believe the usage of the :before & :after psuedo selectors in this case is too much. All those extra lines of code to add spacing doesn't seem right to me. I was able to figure out a better solution. – sssyn Feb 16 '20 at 18:47
0

Here's a basic implementation based on your code. It's basically a combination of CSS Grid Layout and Flexible Box Layout.

Inside the main <nav> container use grid-template-columns to distribute the available width using the fr unit. Then use flexbox to layout the content inside each of the <div> containers:

nav {
  display: grid;
  grid-template-columns: 2fr 1fr;
}

.links-and-logo,
.just-link {
  display: flex;
  justify-content: flex-end;
}
<nav>
  <div class="links-and-logo">
    <a href="#">Link</a>
    <img src="https://source.unsplash.com/100x100/?technology" alt="Nature">
    <a href="#">Link</a>
  </div>
  <div class="just-link">
    <a href="#">Link</a>
  </div>
</nav>
Juan Marco
  • 3,081
  • 2
  • 28
  • 32
  • This wont work as flexbox works best with undefined widths. I already got my solution but a main factor was being able to center the logo image directly in the middle of the page. That makes grid a better choice than flexbox – sssyn Feb 17 '20 at 15:42