0

I'm trying to write a simple HTML+CSS menu without any absolute positioning or JS. My problem is regarding submenus, where it either expand the current selected item or displace it:

submenu problem

The HTML is straightforward:

<ul id="menu">
    <li>Item 1</li>
    <li>Folder 1
    <ul>
        <li>Item 2</li>
    </ul>
    </li>
    <li>Item 3</li>
</ul>

And so is the CSS:

#menu, #menu ul {
    border-style: solid;
    border-width: 0px;
    border-top-width: 1px;
    float: left;
    list-style: none;
    margin: 0px;
    padding: 0px;
    width: 180px;
}

#menu li ul {
    background-color: cyan;
    display: none;
    position: relative;
    right: -168px;
    width: auto;
}

#menu li:hover ul {
    display: block;
}

#menu li {
    border-style: solid;
    border-width: 1px;
    border-top-width: 0px;
    padding: 10px;
}

#menu li:hover {
    background-color: lightgrey;
    font-weight: bold;
}

I thought the submenu could only affect the layout after being repositioned, which seems to not be the case here. I'm a bit at a loss.

2
  • 1
    You need absolute positioning to prevent elements from being "displaced". That is what absolute positioning is for. Commented Aug 9, 2013 at 19:28
  • 1
    @Diodeus: position: absolute means "don't touch your parent's layout and the put the element at x", and position: relative means "change your parent's layout and reposition the element"? Commented Aug 9, 2013 at 19:33

2 Answers 2

2

Using this type of menu pattern, you should use position:relative on the parent LI of the sub-menu, and position:absolute on the UL child menu. The allows the child element to appear outside of the layout flow, relative to its parent.

It's also good practice to put all non-position styling on the A-tag inside each LI and use display:block. It would be difficult for you to style the text on "Folder 1" without it.

Simple example: http://jsfiddle.net/Diodeus/jejNy/127/

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry, I don't quite get it. position: absolute does prevent any changes to the parent li, but the sumbenu ul needs to be moved relative to where it should originally be, which can't be done with position: absolute, nor by moving its containing li.
position:relative sets the origin point for absolutely-positioned children.
1

Use position:absolute on the ul and position:relative on the LI:

HTML:

<ul id="menu">
    <li>Item 1</li>
    <li>Folder 1
      <ul>
        <li>Item 2</li>
      </ul>
    </li>
    <li>Item 3</li>
</ul>

CSS:

#menu, #menu ul {
    border-style: solid;
    border-width: 0px;
    border-top-width: 1px;
    float: left;
    list-style: none;
    margin: 0px;
    padding: 0px;
    width: 180px;
}

#menu li ul {
    background-color: cyan;
    display: none;
    position: absolute;
    top:-1px;
    left: 178px;
}

#menu li:hover ul {
    display: block;
}

#menu li {
    position:relative;
    border-style: solid;
    border-width: 1px;
    border-top-width: 0px;
    padding: 10px;
}

#menu li:hover {
    background-color: lightgrey;
    font-weight: bold;
}

Check out this CodePen

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.