flex column wrap in position absolute

Viewed 665

I can't seem to wrap my head around this. I'm working on an (existing) menu structure. The current menu never intended the amount of sub-items we have, and as such it overflows from the viewport. Since its sticky some items aren't accessible which is problematic. Since flexbox has an issue where the flexbox itself doesn't adjust its width when wrapping columns, the background of the sub-menu doesn't continue. Again problematic since floating text, over other text, is annoying. Having read up on it, it appears the writing-mode solution is mostly used. However when I try to apply it, it still gets a singular row since the header element has to have position: fixed attached to it.

example to clarify:

html:

<header>
  <div class="wrapper">
    <ul class="parent">
      <li class="child">Menu item 1</li>
      <li class="child">Menu item 2</li>
      <li class="child">Menu item 3
        <ul class="sub-parent">
          <li class="sub-child">Sub item 1</li>
          <li class="sub-child">Sub item 2</li>
          <li class="sub-child">Sub item 3</li>
          <li class="sub-child">Sub item 4</li>
          <li class="sub-child">Sub item 5</li>
          <li class="sub-child">Sub item 6</li>
          <li class="sub-child">Sub item 7</li>
          <li class="sub-child">Sub item 8</li>
          <li class="sub-child">Sub item 9</li>
          <li class="sub-child">Sub item 10</li>
          <li class="sub-child">Sub item 12</li>
          <li class="sub-child">Sub item 13</li>
          <li class="sub-child">Sub item 14</li>
          <li class="sub-child">Sub item 15</li>
          <li class="sub-child">Sub item 16</li>
          <li class="sub-child">Sub item 17</li>
          <li class="sub-child">Sub item 18</li>
          <li class="sub-child">Sub item 19</li>
        </ul>

      </li>
      <li class="child">Menu item 4</li>
      <li class="child">Menu item 5</li>
      <li class="child">Menu item 6</li>
    </ul>
  </div>
</header>
<div class="content">
Sub-items should wrap till end of viewport
</div>

css:

header{
 position: fixed;
 top: 0;

}

.wrapper{
  background: #8AB9B5;

}

.parent{
  display: flex;
  background: #C8C2AE;
  list-style: none;
  width: 100vw;
}

.child{
  margin: 0.5em;
}

.sub-parent{
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  max-height: 80vh;
  background: #D0CDD7;
  position: absolute;
  margin: 0;
  list-style: none;
  padding: 0;
  writing-mode: vertical-lr;
}

.sub-child{
  background: #ACB0BD;
  display: block;
  margin: 0.5em;
  writing-mode: horizontal-tb;
}

.content{
  margin-top:100px;
}

https://jsfiddle.net/Tristanschaaf/7pd504hj/99/

Current result: enter image description here

Expected/wanted result: enter image description here

It's possible that the sub-items also have a sub-item structure.

I can't seem to find a way to make the flexbox to see it can expand vertically. Additionally there is an issue in Firefox on which the height seems to be initially set to 0 until a viewport resize is triggered.

I am very aware that this structure can cause it's own UX issues but I'm not here to discuss those, as per usual, the impact of that impacts other sides of the business as well and I cannot change it for now.

3 Answers

You have to just remove writing-mode: vertical-lr; property from .sub-parent element and just need to give fix-width to this element width:200px;.

Not sure this what exactly you needed or so, But what i did is gave some width(200px here) to .sub-parent ul and also some width(fit-content here) to it's children li and then removed/commented one or two from your code to make it look like this. If any doubt do ask

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<style>
  
header{
 position: fixed;
 top: 0;

}

.wrapper{
  background: #8AB9B5;

}

.parent{
  display: flex;
  background: #C8C2AE;
  list-style: none;
  width: 100vw;
}

.child{
  margin: 0.5em;
}

.sub-parent{
  display: flex;
  /* flex-direction: row; */
  flex-wrap: wrap;
  /* max-height: 80vh; */
  width: 200px;
  background: #D0CDD7;
  position: absolute;
  margin: 0;
  list-style: none;
  padding: 0;
  justify-content: center;
  /* writing-mode: vertical-lr; */
}

.sub-child{
  width: fit-content;
  background: #ACB0BD;
  display: block;
  margin: 0.5em;
  writing-mode: horizontal-tb;
}

.content{
  margin-top:100px;
}
</style>


<body>
  
  
<header>
  <div class="wrapper">
    <ul class="parent">
      <li class="child">Menu item 1</li>
      <li class="child">Menu item 2</li>
      <li class="child">Menu item 3
        <ul class="sub-parent">
          <li class="sub-child">Sub item 1</li>
          <li class="sub-child">Sub item 2</li>
          <li class="sub-child">Sub item 3</li>
          <li class="sub-child">Sub item 4</li>
          <li class="sub-child">Sub item 5</li>
          <li class="sub-child">Sub item 6</li>
          <li class="sub-child">Sub item 7</li>
          <li class="sub-child">Sub item 8</li>
          <li class="sub-child">Sub item 9</li>
          <li class="sub-child">Sub item 10</li>
          <li class="sub-child">Sub item 12</li>
          <li class="sub-child">Sub item 13</li>
          <li class="sub-child">Sub item 14</li>
          <li class="sub-child">Sub item 15</li>
          <li class="sub-child">Sub item 16</li>
          <li class="sub-child">Sub item 17</li>
          <li class="sub-child">Sub item 18</li>
          <li class="sub-child">Sub item 19</li>
        </ul>

      </li>
      <li class="child">Menu item 4</li>
      <li class="child">Menu item 5</li>
      <li class="child">Menu item 6</li>
    </ul>
  </div>
</header>
<div class="content">
Sub-items should wrap till end of viewport
</div>


</body>
</html>

You can try the below approach. you just need to set the width of .sub-parent class as per your requirement. (as of now I have set width:40%) and I have set flex-direction: column. and overflow: auto.

header {
  position: fixed;
  top: 0;
}

.wrapper {
  background: #8AB9B5;
}

.parent {
  display: flex;
  background: #C8C2AE;
  list-style: none;
  width: 100vw;
}

.child {
  margin: 0.5em;
}

.sub-parent {
  display: flex;
  flex-wrap: wrap;
  background: #D0CDD7;
  position: absolute;
  margin: 0;
  list-style: none;
  padding: 0;
  margin-right: 60px;
}

.sub-child {
  flex: 0 10%;
  background: #ACB0BD;
  display: block;
  margin: 0.5em;
  writing-mode: horizontal-tb;
}

.content {
  margin-top: 100px;
}
<header>
  <div class="wrapper">
    <ul class="parent">
      <li class="child">Menu item 1</li>
      <li class="child">Menu item 2</li>
      <li class="child">Menu item 3
        <ul class="sub-parent">
          <li class="sub-child">Sub item 1</li>
          <li class="sub-child">Sub item 2</li>
          <li class="sub-child">Sub item 3</li>
          <li class="sub-child">Sub item 4</li>
          <li class="sub-child">Sub item 5</li>
          <li class="sub-child">Sub item 6</li>
          <li class="sub-child">Sub item 7</li>
          <li class="sub-child">Sub item 8</li>
          <li class="sub-child">Sub item 9</li>
          <li class="sub-child">Sub item 10</li>
          <li class="sub-child">Sub item 12</li>
          <li class="sub-child">Sub item 13</li>
          <li class="sub-child">Sub item 14</li>
          <li class="sub-child">Sub item 15</li>
          <li class="sub-child">Sub item 16</li>
          <li class="sub-child">Sub item 17</li>
          <li class="sub-child">Sub item 18</li>
          <li class="sub-child">Sub item 19</li>
          <li class="sub-child">Sub item 20</li>
          <li class="sub-child">Sub item 21</li>
          <li class="sub-child">Sub item 22</li>
          <li class="sub-child">Sub item 23</li>
          <li class="sub-child">Sub item 24</li>
          <li class="sub-child">Sub item 25</li>
          <li class="sub-child">Sub item 26</li>
          <li class="sub-child">Sub item 27</li>
          <li class="sub-child">Sub item 28</li>
          <li class="sub-child">Sub item 29</li>
          <li class="sub-child">Sub item 30</li>
          <li class="sub-child">Sub item 31</li>
          <li class="sub-child">Sub item 32</li>
          <li class="sub-child">Sub item 33</li>
          <li class="sub-child">Sub item 34</li>
          <li class="sub-child">Sub item 35</li>
          <li class="sub-child">Sub item 36</li>
          <li class="sub-child">Sub item 37</li>
          <li class="sub-child">Sub item 38</li>
          <li class="sub-child">Sub item 39</li>
          <li class="sub-child">Sub item 40</li>
          <li class="sub-child">Sub item 41</li>
          <li class="sub-child">Sub item 42</li>
          <li class="sub-child">Sub item 43</li>
        </ul>

      </li>
      <li class="child">Menu item 4</li>
      <li class="child">Menu item 5</li>
      <li class="child">Menu item 6</li>
    </ul>
  </div>
</header>
<div class="content">
  Sub-items should wrap till end of viewport
</div>

Related