1

I'm trying to implement a menu with submenus displayed in a dropdown.

The menu is composed of a header, the menu elements and a footer. To do so, I've used a simple display: flexon my parent element, two fixed sizes for the header and the footer and the rest for the content with flex: 1.

In order to manage the scroll in the content, I also have to set a overflow: auto on the content container. This causes the dropdown menu to show in the X axis scroll.

I'm not sure of what to do to fix this issue, I've tried to play with the position: fixed, as mentioned in this question but it doesn't work when I try to scroll.

Here's the JSFiddle with the failed attempt to use a fixed position.

Current HTML template :

<div id="app">
  <div class="menu">
    <div class="menu-header">
      <h1>
        Header
      </h1>
    </div>
    <div class="menu-content">
      <ul>
        <li class="element" v-for="(element, index) in elements" :key="index" 
          @mouseenter="element.childrenVisible = true"
          @mouseleave="element.childrenVisible = false">
          <h2>
            {{ element.title }}
          </h2>
          <div class="children-wrapper" v-if="element.childrenVisible && element.children && element.children.length">
            <ul class="children">
              <li v-for="(child, childIndex) in element.children" :key="childIndex">
                <h3>
                  {{ child.title }}
                </h3>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
    <div class="menu-footer">
      <p>
        Footer..
      </p>
    </div>
  </div>
</div>

The JS only contains an instance of Vue and some test data, formatted like so :

{
  title: '1',
  childrenVisible: false,
  children: [{
    title: '1.1',
  }],
},

And the CSS (sass) looks like this :

.menu {
  width: 100px;
  max-height: 500px;
  background-color: #0a6e89;
  display: flex;
  flex-direction: column;

  .menu-header, .menu-footer {
    height: 70px;
    flex-shrink: 0;
    background-color: #f9f8f2;
  }

  .menu-content {
    flex: 1;
    overflow: auto;
  }
}

.menu-content {  
  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .element {
    position: relative;

    .children-wrapper {
      position: absolute;  
      top: 0;
      left: 100%;
    }

    .children {
      position: fixed;
      background-color: #f9f8f2;
      border: 1px solid black;
    } 
  }
}
1
  • Please include your code, not just a link to it (which might someday break) Commented Oct 4, 2017 at 15:13

1 Answer 1

1

If you use a method in @mouseenter rather than directly toggling the childrenVisible flag, you get an event passed to the parameter of the method.

This has screen coordinates and a reference to the parent element, and it's children.

@mouseenter="mouseEnter"

methods: {
  mouseEnter (event) {
    // adjust child position here
  }
}
Sign up to request clarification or add additional context in comments.

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.