skip to Main Content

In a section of website I’m working on I have a NAV element that contains three sections: About, Portfolio, Contact. I’m trying to make it so that when you hover over the Portfolio section, a drop down appears allowing you to choose between two other sections, “Writing Samples” and “Photoshop.” I am trying to accomplish this using only CSS.

This is my HTML section:

<nav>
            <ul>
                <li>
                    <a href="index.html" >About</a>
                </li>
                <li class="subNav">
                    <a class="selected" >Portfolio</a>
                    <ul>
                        <li><a href="writing_samples.html">Writing Samples</a></li>
                        <li><a href="photoshop.html">Photoshop</a></li>
                    </ul>
                </li>
                <li>
                    <a href="contact.html">Contact</a>
                </li>
            </ul>
        </nav>

And CSS:

nav {
position: absolute;
bottom: 0;
right: 0;
padding: 10px 0;
} 

nav ul {
list-style: none;
margin: 0 10px;
padding: 0;
}

nav li {
display: inline-block;
}

nav a {
font-weight: 800;
padding: 15px 10px;
}

nav ul li.subNav ul {
display: none;
} 

nav ul li.subNav:hover ul {
display: block;
}

I have reached the point that when I hover over the Portfolio list item, you see the resulting list items “Writing Samples” and “Photoshop”, except that it displays these two items as a part of the original unordered list, and moves the “Portfolio” list item above the rest of the items. I would like “Writing Samples” and “Photoshop” to appear vertically under “Portfolio”, but I can’t quite figure this out with CSS.

2

Answers


  1. This is the basics of it:

    nav {
      position: absolute;
      padding: 10px 0;
    }
    nav ul {
      list-style: none;
      ;
      padding: 0;
    }
    nav > ul > li {
      display: inline-block;
      position: relative;
      border: 1px solid lightgreen;
      /* for demo */
    }
    nav a {
      font-weight: 800;
      padding: 5px 10px;
      display: block;
    }
    nav > ul > li.subNav ul {
      display: none;
      position: absolute;
      top: 100%;
      left: 0;
      white-space: nowrap;
      background: pink;
    }
    nav ul li.subNav:hover ul {
      display: block;
    }
    <nav>
      <ul>
        <li>
          <a href="index.html">About</a>
        </li>
        <li class="subNav">
          <a class="selected">Portfolio</a>
          <ul>
            <li><a href="writing_samples.html">Writing Samples</a>
            </li>
            <li><a href="photoshop.html">Photoshop</a>
            </li>
          </ul>
        </li>
        <li>
          <a href="contact.html">Contact</a>
        </li>
      </ul>
    </nav>

    The parent li is given position:relative to provide positioning context.

    The submenu is positioned absolutely, at the bottom of the parent li and aligned left.

    Note that I have used the direct child selector > to target only the elements I want to.

    Then, since the submenu is too wide to be contained within the parent’s width, I added white-space:nowrap so that the text will flow as required.

    Login or Signup to reply.
  2. You have the right idea; the comment tags in the HTML below are used to remove space between the “li” elements.

    Instead of using display:none, I use visibility: hidden for S.E.O purposes.

    Even though you use position: absolute, you should also use z-index so that menu elements are able to be clicked if they are overlapping other content.

    .mm,
    .sm {
      list-style: none;
    }
    .mm {
      position: relative;
      margin: 0px;
      padding: 0px;
      background-color: #000;
      border-bottom: 4px solid red;
    }
    .sm {
      position: absolute;
      z-index: 1;
      visibility: hidden;
      background-color: #000;
      border-width: 0px 4px 4px 4px;
      border-style: solid;
      border-color: red;
    }
    .mm > li {
      display: inline-block;
    }
    .mm > li > a {
      display: inline-block;
      padding: 8px;
    }
    .sm a {
      display: block;
      padding: 8px;
    }
    .mm > li > a:hover + .sm,
    .sm:hover {
      visibility: visible;
    }
    .mm a {
      text-decoration: none;
      color: #FFF;
    }
    .mm a:hover {
      text-decoration: underline;
      color: yellow;
    }
    <nav>
        <ul class="mm">
    	    <li><a href="#" title="#">AAA</a></li><!--
            --><li><a href="#" title="#">BBB</a>
                <ul class="sm">
                    <li><a href="#" title="#">SUB</a></li><!--
                    --><li><a href="#" title="#">SUB</a></li><!--
                    --><li><a href="#" title="#">SUB</a></li>
                </ul>
            </li><!--
    		--><li><a href="#" title="#">CCC</a>
                <ul class="sm">
                    <li><a href="#" title="#">SUB</a></li><!--
                    --><li><a href="#" title="#">SUB</a></li><!--
                    --><li><a href="#" title="#">SUB</a></li>
                </ul>
            </li>
        </ul>
    </nav>
    
    <h1>CSS NAVIGATION</h1>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search