I'm trying to create a simple mega menu using existing markup of a simple unordered list without changing up the markup.
Some requirements...
- Width is fixed (in my case 100% spanning from left to right) and cannot overflow
- Height can be variable depending on the number of items, but is ideally as small as possible so we don't have just a single column with a ton of items
- First LI element needs to be 100% height due to a design restriction by the client (essentially the first LI will be a highlighted link in the first column and the remaining items are the rest of the navigation items listed vertically in columns.
Here is a quick simplified mockup of the general layout...
Right now I've been able to accomplish most of this with flex, but am having to set a height on the whole container before it starts to wrap into columns and then run into an overflow issue at the right if the content is larger. Here is a simplified example...
.megamenu {
background-color: #ccc;
list-style-type: none;
margin: 0;
padding: 0.6em;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 210px;
}
.megamenu .item {
padding: 0.2em 0.4em;
}
.megamenu .item:first-child {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #FAEAD6;
}
<ul class="megamenu">
<li class="item"><a href="#">Item 1</a></li>
<li class="item"><a href="#">Item 2</a></li>
<li class="item"><a href="#">Item 3 with an extra long string of text for testing purposes</a></li>
<li class="item"><a href="#">Item 4</a></li>
<li class="item"><a href="#">Item 5</a></li>
<li class="item"><a href="#">Item 6</a></li>
<li class="item"><a href="#">Item 7</a></li>
<li class="item"><a href="#">Item 8</a></li>
<li class="item"><a href="#">Item 9</a></li>
<li class="item"><a href="#">Item 10</a></li>
<li class="item"><a href="#">Item 11</a></li>
<li class="item"><a href="#">Item 12 Quam Nibh Cursus Ornare Adipiscing</a></li>
<li class="item"><a href="#">Item 13</a></li>
<li class="item"><a href="#">Item 14</a></li>
<li class="item"><a href="#">Item 15</a></li>
<li class="item"><a href="#">Item 16</a></li>
<li class="item"><a href="#">Item 17</a></li>
<li class="item"><a href="#">Item 18</a></li>
<li class="item"><a href="#">Item 19</a></li>
<li class="item"><a href="#">Item 20</a></li>
<li class="item"><a href="#">Item 21</a></li>
<li class="item"><a href="#">Item 22</a></li>
<li class="item"><a href="#">Item 23</a></li>
<li class="item"><a href="#">Item 24 Amet Tellus Lorem Ligula Euismod</a></li>
<li class="item"><a href="#">Item 25</a></li>
<li class="item"><a href="#">Item 26</a></li>
<li class="item"><a href="#">Item 27</a></li>
<li class="item"><a href="#">Item 28 Maecenas sed diam eget risus varius blandit sit amet non magna. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</a></li>
<li class="item"><a href="#">Item 29</a></li>
<li class="item"><a href="#">Item 30</a></li>
</ul>
I'm not entirely sure it's possible to use flex to accomplish this, but I've tried with grid and plain old columns, but neither worked well.
CodePudding user response:
Sadly Flexbox rows are expected to have fixed sizes.
Flexbox is not meant to recreate Masonry with pure CSS: items in one row cannot occupy space allocated for a preceding/following row (same goes for columns if you're using column orientation). You can use align-items to prevent them from stretching, but that's about it
Try:
.megamenu {
background-color: #ccc;
list-style-type: none;
margin: 0;
padding: 0.6em;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 210px;
}
.megamenu .item {
padding: 0.2em 0.4em;
}
.megamenu .item:first-child {
display: flex;
align-items:flex-start;
justify-content: center;
height: 100%;
background-color: #FAEAD6;
}
Or you can try column orientation or the multi-column module (see this SO answer: https://stackoverflow.com/a/20862961/1652962)
CodePudding user response:
I did fine a solution with display: grid;
. I dont know how many column you wish but it is up to you to fix that into the grid-template-columns
.
In your container set the below code:
display: grid;
grid-template-columns: repeat(4, minmax(100px, 1fr));
grid-template-rows: auto [last-line];
In your first item set like this, it will span for the first item:
/* This make the trick */
grid-row: 1 / span last-line;
grid-row-start: span 9000;
The credit belong to this answer. If you consider my answer as duplicate, please delete your question.
.megamenu {
background-color: #ccc;
list-style-type: none;
margin: 0;
padding: 0.6em;
display: grid;
grid-template-columns: repeat(4, minmax(100px, 1fr));
grid-template-rows: auto [last-line];
}
.megamenu .item {
padding: 0.2em 0.4em;
}
.megamenu .item:first-child {
display: flex;
align-items: center;
justify-content: center;
background-color: #FAEAD6;
/* This make the trick */
grid-row: 1 / span last-line;
grid-row-start: span 9000;
}
<ul class="megamenu">
<li class="item"><a href="#">Item 1</a></li>
<li class="item"><a href="#">Item 2</a></li>
<li class="item"><a href="#">Item 3 with an extra long string of text for testing purposes</a></li>
<li class="item"><a href="#">Item 4</a></li>
<li class="item"><a href="#">Item 5</a></li>
<li class="item"><a href="#">Item 6</a></li>
<li class="item"><a href="#">Item 7</a></li>
<li class="item"><a href="#">Item 8</a></li>
<li class="item"><a href="#">Item 9</a></li>
<li class="item"><a href="#">Item 10</a></li>
<li class="item"><a href="#">Item 11</a></li>
<li class="item"><a href="#">Item 12 Quam Nibh Cursus Ornare Adipiscing</a></li>
<li class="item"><a href="#">Item 13</a></li>
<li class="item"><a href="#">Item 14</a></li>
<li class="item"><a href="#">Item 15</a></li>
<li class="item"><a href="#">Item 16</a></li>
<li class="item"><a href="#">Item 17</a></li>
<li class="item"><a href="#">Item 18</a></li>
<li class="item"><a href="#">Item 19</a></li>
<li class="item"><a href="#">Item 20</a></li>
<li class="item"><a href="#">Item 21</a></li>
<li class="item"><a href="#">Item 22</a></li>
<li class="item"><a href="#">Item 23</a></li>
<li class="item"><a href="#">Item 24 Amet Tellus Lorem Ligula Euismod</a></li>
<li class="item"><a href="#">Item 25</a></li>
<li class="item"><a href="#">Item 26</a></li>
<li class="item"><a href="#">Item 27</a></li>
<li class="item"><a href="#">Item 28 Maecenas sed diam eget risus varius blandit sit amet non magna. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</a></li>
<li class="item"><a href="#">Item 29</a></li>
<li class="item"><a href="#">Item 30</a></li>
</ul>
CodePudding user response:
.megamenu .item:not(:first-child) {
flex: 1 1 0px;
}