Flexbox Responsive Mega Dynamic Content Menu

I am creating a large dynamic navigation menu that I want to look like this:

[----------- 100% PAGE WIDTH -----------] | GROUP A | GROUP C | GROUP F | GROUP G | | item | item | item | item | | item | | item | item | | | GROUP D | item | item | | GROUP B | item | item | | | item | | | | | item | GROUP E | | | | | item | | | |---------------------------------------| | | | | [------------- END OF PAGE -------------]

See my JS Script Example .

 * { padding: 0; margin: 0; } body { background: #ccc; font-family: helvetica, arial; color: #444; } ul { list-style: none; } .mega-menu { display: flex; flex-direction: column; flex-wrap: wrap; padding: 15px; height: 50vh; background: #fff; } .mega-menu > li { display: flex; flex-direction: column; font-size: .7rem; padding-bottom: 15px; } .title { font-size: .7rem; font-weight: bold; line-height: 1; padding-bottom: 5px } 
 <ul class="mega-menu"> <li> <a class="title">News</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Topics</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Networks</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Groups</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Sections</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Pilots</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Locations</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">Cities</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">News</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Topics</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Networks</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Groups</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Sections</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Pilots</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Locations</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">Cities</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">News</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Topics</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Networks</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Groups</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Sections</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Pilots</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Locations</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">Cities</a> <ul> <li>Denver</li> <li>Baltimore</li> <li>LA</li> <li>New York</li> <li>San Francisco</li> <li>New Orleans</li> <li>Jacksonville</li> <li>Calvery</li> <li>August</li> </ul> </li> <li> <a class="title">News</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Topics</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> <li> <a class="title">Shows</a> <ul> <li>CBS</li> <li>NBC</li> </ul> </li> <li> <a class="title">Networks</a> <ul> <li>HBO</li> <li>CBS</li> <li>NBC</li> <li>CNN</li> </ul> </li> <li> <a class="title">Groups</a> <ul> <li>Top Stories</li> <li>Trending Stories</li> <li>Sports</li> <li>US</li> <li>Global</li> </ul> </li> </ul> 

Requirements

  • If the page width grows, I want the columns to be larger there , if they are compressed, I need smaller columns.

  • If I need to add twice as many elements, I want the height of the columns to increase , so there is room for additional elements.

  • Indents / spaces between each group should be the same.

  • Ideally, I will not use JavaScript (but if this is the only way).

Problem

When I reduce the height / width of the screen, the content overflows on the right side of the menu.

Thoughts

I was looking for a CSS solution, but cannot find one that does not add a gap between unequal groups. (For example, Jagged Spaces )

All I can think of is to use JavaScript to dynamically determine the height of the flexbox parent (increase the height until the last group of elements (TITLE F) is fully shown and overflows from the screen.

+8
javascript css flexbox css3
source share
1 answer

Maybe something like this ( jsfiddle ):

 .mega-menu { -webkit-column-count:1; -moz-column-count:1; column-count:1; padding: 15px 15px 0; background: #fff; } @media (min-width: 200px) {.mega-menu{-webkit-column-count:2;-moz-column-count:2;column-count:2;}} @media (min-width: 300px) {.mega-menu{-webkit-column-count:3;-moz-column-count:3;column-count:3;}} @media (min-width: 400px) {.mega-menu{-webkit-column-count:4;-moz-column-count:4;column-count:4;}} // ... @media (min-width: 1800px) {.mega-menu{-webkit-column-count:18;-moz-column-count:18;column-count:18;}} @media (min-width: 1900px) {.mega-menu{-webkit-column-count:19;-moz-column-count:19;column-count:19;}} @media (min-width: 2000px) {.mega-menu{-webkit-column-count:20;-moz-column-count:20;column-count:20;}} .mega-menu > li { display:inline-block; font-size: .7rem; padding-bottom: 15px; } 

It should probably be expanded to at least the width of a 4K monitor. If you have SASS or the like, this will make things less tiring.

It does not give column widths with content support, leaving you to guess the probable minimum column width.

The problem that you mentioned about the menu coming down on the right side, in fact, will not be solved with any solution, when you have many items that can be displayed, but without scrolling. Note that a narrower display width usually also has shorter display heights. The smaller the screen, the less you can fit. You may need to configure smaller screens to have fewer menu options.

+6
source share

All Articles