Removing menu items based on screen size to create a dynamic user experience

Recently, while browsing a website, I noticed it had multiple tabs labeled A|B|C|D|E|MORE. However, when zooming in on the desktop browser, the tabs changed to A|B|C|MORE. Further zooming resulted in only A|MORE being displayed, and vice versa upon zooming out. I am currently working on populating my menu using AngularJS and was curious about how to create a directive for this specific functionality.

Answer №1

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

Answer №2

If you want a simple way to achieve this, Bootstrap 3 has got you covered. By utilizing the

.hidden-xs, .hidden-sm, .hidden-md, .hidden-lg
classes, you can easily control the visibility of elements without relying heavily on Javascript.

<div class="container">
    <ul class="nav nav-pills nav-stacked">
        <li class="active"><a href="#">Shown 1</a>
        </li>
        <li><a href="#">Shown 2</a>
        </li>
        <li><a href="#">Show 3</a>
        </li>
        <li class="hidden-xs xs"><a href="#">Hidden XS</a>
        </li>
        <li class="hidden-sm sm"><a href="#">Hidden SM</a>
        </li>
        <li class="hidden-md md"><a href="#">Hidden MD</a>
        </li>
        <li class="hidden-lg lg"><a href="#">Hidden LG</a>
        </li>
    </ul>
</div>

http://jsfiddle.net/jLxXz/

Answer №3

After upgrading from Bootstrap 3.0 to 3.1.1, I made use of the new "hidden-xs,visible-lg" classes for better responsiveness in my project. To simplify the process, I created a custom class called "hidden-sm hidden-xs" and utilized ng-class="{{item.class}}" in AngularJS to dynamically add classes based on each menu item. This approach effectively addressed the need to set specific classes for different components.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Oops! Looks like there was a syntax error with the JSON data at position 1. This resulted in a 400

Having issues submitting form data in my Vue app with an express backend API. The endpoint works fine on postman but I keep getting errors like "SyntaxError: Unexpected token g in JSON at position 0" or "400: Bad Request." I've tried using JSON.parse ...

What sets justify-content apart from align-items?

I'm really struggling to grasp the distinction between these two properties. After conducting some research, it appears that justify-content can handle... space-between and space-around, while align-items is capable of... stretch, baseline, initial, a ...

Continuously providing service within the application

In the process of developing my app, I have implemented a feature that sends the user's geolocation data to the server (given proper permissions). Currently, this geolocation data is only pushed to the server when the user navigates to the account pag ...

Deactivate the input field once the submit button has been clicked

I am attempting to deactivate an input field immediately after the submit button is clicked. The recommended Angular method is as follows: In this example, the button is disabled when the checkbox is checked. Similarly, I want to disable the input field w ...

Incorporate user input into Alert Dialog Boxes

Would you be able to assist me in displaying the input value from the "email" field in my alert box? The code seems to be working fine, but I'm having trouble getting the alert box to show the email form value. I decided to use Bootstrap for som ...

Adapting content based on various media queries

After spending more time on this question, I hope to clarify my thoughts better this time around. I am currently designing a responsive layout for my upcoming landing page. The main header in the body changes based on the browser size and device. <h1& ...

Verify that the images have been successfully loaded

I'm in the process of loading 8 images that all share a common class name. For example: <img class="commonClass" src="..." alt="" /> <img class="commonClass" src="..." alt="" /> <img class="commonClass" src="..." alt="" /> How can ...

Error in Uploading Files with AngularJS - Uncaught SyntaxError: Unexpected token

I'm having trouble uploading an image file using Angular and PHP, specifically at the app.service Error line: app.service('fileUpload', ['$https:', function ($https:) { Code app.service('fileUpload', ['$https:&ap ...

Creating an input field within a PixiJS Canvas: Enhancing PixiJS UI with typed-signals for seamless import/export interactions

I am trying to utilize PixiJS UI version 2.1.2 to add an input field to a canvas rendered by PixiJS version 8.2.0. The PixiJS part works fine, but I'm encountering issues with importing @pixi/ui. Firefox displays: "Uncaught SyntaxError: ambiguous ind ...

Arrange ten objects in each of the four JavaScript arrays in ascending order based on a specific value

model with sample data -> [{ date: '13413413', name: 'asdfasdf', other: 'kjh' }] The getJSON function returns 4 arrays, each containing 10 model objects. array1 = 10 resultsObj sorted by date from newest to o ...

What exactly does the ::before pseudo-element accomplish?

After reviewing the documentation, I believe I have a good grasp of the purpose of ::before and ::after. It seems that they are typically used in conjunction with other elements. However, the webpage I am examining contains the following code: <body> ...

What is the best way to add an event listener to the parent component in ReactJS?

I am currently working on creating a customized context menu that will appear when the user right-clicks on a specific area of my webpage, while still allowing the browser's default context menu to be displayed on other parts of the page. From the pa ...

Develop a revolutionary web tool integrating Node.js, MongoDb, and D3.js for unparalleled efficiency and functionality

I am exploring the creation of a web application that will showcase data gathered from various websites. To achieve this, my plan involves automating the process of data collection through web scraping. After collecting the data from these sites, I will fo ...

Tips for organizing child cards within a parent card using Bootstrap

I'm trying to set up my child card within the parent card to look like the image provided. I'm using Bootstrap 4 and the card_deck class. https://i.sstatic.net/ihWrb.png However, I'm facing difficulties in getting the layout to match the p ...

In Internet Explorer 8, experiment with creating a unique event in plain JavaScript and then capturing it using jQuery

Currently, I am facing an issue with IE8 regarding the execution order of scripts. There is a piece of code that needs to run before JQuery is loaded so I can fire a custom event. This event will be detected later by another section of code once JQuery ha ...

Incorporating Javascript into HTML

I have developed a script to randomly change the size of an element, but I am struggling to understand how to incorporate it using HTML or iframe code for randomization. <script type="text/javascript"> var banner1 = ["728", "90"]; var banne ...

Guide on setting up create-next-app with version 12 instead of the latest version 13

For an upcoming Udemy course, I am required to develop a Next.js project. However, it specifically needs to be built using Next.js version 12 rather than the latest version 13. Does anyone know how I can achieve this? ...

JavaScript function occasionally experiences loading issues with CSS images

Have you ever encountered issues with a CSS background image failing to load? What might be the underlying cause? I've written some Javascript code that looks like this: function progressBar(file_id) { pbar = ($("<div />").attr('id&a ...

In Angular 5, a variable's value becomes undefined once it is subscribed to outside of its assigned

I keep encountering an undefined value when trying to assign the subscribed value to a variable in my code snippet below. service.ts getIpAddress() : Observable<any> { return this.http .get(this.Geo_Api) .map((response: ...

Is it possible to use a Javascript onchange function to replace "-" with "/" in a URL string

I am working on an MVC3 web page where a URL parameter is used to represent a date in the format dd-MM-yyyy. public ActionResult Calendar(string startDate, string UserId, string status, bool myPage = false) Within the calendar view, there is a partial vi ...