To achieve this effect, I recommend utilizing CSS and Mediaqueries. It can actually be accomplished using CSS alone.
Understanding Mediaqueries
Mediaqueries are rules that enable CSS selectors and their style definitions based on specific device/screen attributes such as media type, screen width/height, device width/height, resolution (pixels per inch), device pixel ratio, orientation, and more.
For further details:
Suggested Approach
In my proposed solution, I utilize flexbox to extend the column of prominently displayed buttons across the entire available width while positioning the "More..." button to float right with a fixed width.
As the width decreases and triggers a breakpoint, the mediaquery kicks in by hiding the primary buttons and revealing the submenu buttons instead.
The submenu is designed to open on hover, eliminating the need for any JavaScript functionality.
Explore the Solution on JsFiddle
(Compatibility: Tested in modern browsers, including IE 11, validated primarily in Chrome ~33 and FF ~27)
Further Breakdown
Flex Configuration
HTML Structure
<div id="menu">
<ul class="primary">
...
</ul>
<div class="more">
...
</div>
</div>
CSS Styling
#menu {
display: flex;
...
}
#menu .primary {
margin: 0 50px 0 0;
flex: 1;
}
Implementing Mediaqueries
/* Hide the visible buttons from the primary menu */
#menu .more li:nth-child(1),
#menu .more li:nth-child(2),
#menu .more li:nth-child(3) {
display: none;
}
/* First breakpoint: Conceal primary button, reveal corresponding submenu item */
@media screen and (max-width: 350px) {
#menu .primary li:nth-child(3) {
display: none;
}
#menu .more li:nth-child(3) {
display: block;
}
}
/* Second breakpoint: Continue the same pattern at subsequent breakpoints ... */
@media screen and (max-width: 300px) {
#menu .primary li:nth-child(2) { /* Implement the same action here */ }
#menu .more li:nth-child(2),
#menu .more li:nth-child(3) { /* Repeat the procedure for consistency */ }
}
Complete Code
HTML Layout
<div id="menu">
<ul class="primary">
<li>AAA</li>
<li>BBB</li>
<li>CCC</li>
</ul>
<div class="more">
More...
<ul>
<li>AAA</li>
<li>BBB</li>
<li>CCC</li>
<li>DDD</li>
<li>EEE</li>
</ul>
</div>
</div>
Styling with CSS
/* Apply flex behavior to child elements */
#menu {
display: flex;
height: 30px;
}
#menu ul li {
list-style: none;
}
/* Allow button wrapper to flex and occupy remaining width */
#menu .primary {
margin: 0 50px 0 0;
padding: 0;
display: inline-block;
flex: 1;
}
#menu .primary li {
padding: 5px 10px;
min-width: 50px;
text-align: center;
display: inline-block;
}
/* Position the "More..." button on the right */
#menu .more {
padding: 5px 10px;
width: 50px;
display: inline-block;
float: right;
}
/* Initially conceal hoverable submenu */
#menu .more ul {
display: none;
padding: 0;
margin: 0;
}
/* Reveal submenu on hover */
#menu .more:hover ul {
display: block;
}
/* Default hidden states, activated through Mediaqueries */
#menu .more li:nth-child(1),
#menu .more li:nth-child(2),
#menu .more li:nth-child(3) {
display: none;
}
@media screen and (max-width: 350px) {
#menu .primary li:nth-child(3) {
display: none;
}
#menu .more li:nth-child(3) {
display: block;
}
}
@media screen and (max-width: 300px) {
#menu .primary li:nth-child(2) {
display: none;
}
#menu .more li:nth-child(2), #menu .more li:nth-child(3) {
display: block;
}
}
View the Full Implementation on JsFiddle