Why can't we use percentages to change the max-height property in JavaScript?

I am currently working on creating a responsive menu featuring a hamburger icon. My goal is to have the menu list slide in and out without using jQuery, but instead relying purely on JavaScript.

HTML :

<div id="animation">  
</div>
<button id="toggle">Toggle</button>

CSS :

div {
width: 300px;
height: 300px;
background-color: blue;
}

Javascript :

var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback){
var inter = -1, start = 100, end = 0;
if(type==true){
    inter = 1;
    start = 0;
    end = 100;
}
var si = setInterval(function(){
    console.log('maxheight');
    div.style.maxHeight = (start + inter) + '%';
    if(start == end){
        clearInterval(si);
    }
}, 10);
}

var hidden = false;
but.onclick = function(){
animate(hidden, function(){
    hidden = (hidden == false) ? true : false;
});
}

div.style.maxHeight = "50%";

Answer №1

The issue arises from the fact that for proportional height in an element to work properly, a fixed height needs to be set on the parent element. However, in your case, no parent with a fixed height has been provided since the maxHeight property also relies on a percentage value based on the parent element.

To resolve this, you need to enclose your div within a parent container that has a fixed height. Here is the corrected version of your code:

var button = document.getElementById('toggle');
var container = document.getElementById('animation');
var animate = function(type, callback) {
  var interval = -1,
    startPercentageValue = 100,
    endPercentageValue= 0;
  if (type) {
    interval = 1;
    startPercentageValue = 0;
    endPercentageValue = 100;
  }
  var si = setInterval(function() {
    console.log('maxheight');
    container.style.maxHeight = (startPercentageValue + interval) + '%';
    if (startPercentageValue == endPercentageValue) {
      clearInterval(si);
    }
  }, 10);
}
var hidden = false;

button.onclick = function() {
  animate(hidden, function() {
    hidden = !hidden ;
  });
}

container.style.maxHeight = "50%";
#animation {
  width: 300px;
  height: 300px;
  background-color: blue;
}
#parent {
  width: 500px;
  height: 500px;
}
<div id="parent">
  <div id="animation">
  </div>
  <button id="toggle">Toggle</button>
</div>

Note:

It should be noted that there are certain statements in your JavaScript code that require modification:

if(type==true) can be simplified to if(type).

hidden = (hidden == false) ? true : false;
can be shortened to hidden = !hidden

Answer №2

It appears that there are some errors in your code that I have addressed. I have made adjustments to the JavaScript and added comments to clarify the changes I made.

var button = document.getElementById('toggle');
var targetDiv = document.getElementById('animation');
var animateToggle = function (type, callback) {
  var start = 100,
      end = 0;

  if (type) {
    start = 0;
    end = 100;
  }

  var intervalId = setInterval(function () {
    if (type) { 
      start++;
    } else {
      start--
    }

    targetDiv.style.maxHeight = start + '%';

    if (start == end) {
      clearInterval(intervalId);
    }
  }, 10);

  callback.call(this); 
}

var isHidden = false;
button.onclick = function () {
  animateToggle(isHidden, function () {
    isHidden = !isHidden; 
  });
}
/*make sure parent container has a height set or max height won't work*/
html, body {
    height:100%;
    margin:0;
    padding:0;
} 
div {
    width: 300px;
    height: 300px;
    background-color: blue;
}
<div id="animation"></div>
<button id="toggle">Toggle</button>

Example Fiddle

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

Adding pixels to the top position with jQuery in Angular 2

I am trying to adjust the position of my markers when the zoom level is at 18 or higher by adding 10px upwards. However, my current approach doesn't seem to be working as expected. Can someone please assist me with this issue? You can view the code sn ...

Reorganize a list based on another list without generating a new list

Among the elements in my HTML list, there are items with text, input fields, and tables. I also have a specific order list like [3,1,2,0]. Is it feasible to rearrange the items in the HTML list on the page based on this order list without generating a new ...

What is the best way to change the background color for my photo gallery?

I'm currently working on a project to create a unique photo gallery where each image has a different colored background. I have six images in total, but right now all of them have a pink background. I've attempted adding another .popup class in t ...

Positioning Tumblr blockquotes beneath each other, rather than within

Just diving into the world of HTML/CSS and I've been working hard on creating my own Tumblr theme (almost finished!). One issue I'm having is styling the replies, which are in blockquote form. I want them to display one after another in a line li ...

jQuery: Implementing smooth horizontal scrolling functionality

Here is the code I am working with: // General Function $("li a").click(function() { $("li a").removeClass("active"); $(this).addClass("active"); }); // Horizontal Scroll-to Function $("li a").click(function() { var offset = this.getBounding ...

Utilizing Array Elements to Populate the Title Attribute in <TD> Tags

I am trying to display text on hover of a cell in my dynamically created HTML table, using the title attribute. However, instead of reading the contents of the array, it is displaying the array name as a string. Below is the code for generating the table ...

A guide on showcasing a MultiPolygon GeoJSON on a Leaflet map

I am attempting to showcase a GeoJSON MultiPolygon object on a Leaflet map. I retrieve it from a PostgreSQL database as JSON and transform it into GeoJSON. I have validated the MultiPolygon object on GeoJSONLint and it checks out: However, I am facing di ...

Certain javascript files have had illegal characters mistakenly added to them

There seems to be an issue with the js files or server on certain pages, as they are not loading in Firefox: with firefox: SyntaxError: illegal character 癡爠浥湵楤猠㵛≶敲瑩捡汭敮產崻 ⽅湴敲⁩搨猩映啌敮畳Ⱐ獥灡牡瑥 ...

Is there a way to allow an HTML page rendered by node.js to communicate back to its corresponding node.js file?

I am currently in the process of developing a registry system using node.js and HTML. However, I have encountered an issue where my HTML page is rendered by node.js, but when trying to call it back to the node.js file, it appears that the JS file cannot be ...

Choosing a Component in a Collection with Angular 2

Seeking advice on how to address an issue I'm facing with a sign-up page. Within the page, there are two buttons, represented by components <btn-gender>, each displaying a gender option for selection. The challenge lies in creating a logic to d ...

What is the best way to incorporate an AJAX GET request into an HTML element?

Currently, I am attempting to execute a JavaScript code that will convert all <a></a> elements found within another element <b></b> (the specific name in the HTML) into links that trigger an HTTP get request. However, the code I hav ...

The Scrapy CSS selector is not fetching any prices from the list

Having trouble with the price CSS-selector while scraping an interactive website using Scrapy. Check out the HTML screenshot I captured: https://i.stack.imgur.com/oxULz.png Here are a few selectors that I've already experimented with: price = respon ...

Discovering the quantity of pagination tabs in Selenium WebAutomation

A critical element in the table "ContentPlaceHolder1_gvChannelList" is Pagination, located at the last row. I need to determine how many pages/columns are present in this pagination table. The code driver.findElements(By.id("//*[@id='ContentPlaceHold ...

Ways to delete a tag with jQuery

Currently I'm struggling with hiding elements like delpc and picnam. Here is the structure of my code: <ul id="userpic" class="user pic"> <im class="pict"/> Picture preview </ul> <div id="showpicname"> <div id= ...

I'm encountering a npm error on Windows_NT 10.0.19042, does anyone know how to troubleshoot this issue?

After downgrading to [email protected], I encountered an error message that keeps popping up whenever I try to update npm or install new packages. What steps can I take to resolve this issue? npm ERR! Windows_NT 10.0.19042 npm ERR! argv "C:\ ...

Creating a curved edge for a shape in React Native can add a stylish and

Issue Description I am working on an app and struggling with styling the bottom navigation bar. It's more complex than what I've done before, especially the curved top edge of the white section and the area between the blue/green circle and the ...

Is using CSS as an HTML attribute considered poor practice?

I've been noticing an increasing trend of combining HTML, CSS, and JavaScript together in web development. However, I was taught to keep them separate with HTML linking to the sources/scripts. While using the style attribute in HTML is sometimes acce ...

Manually assigning a value to a model in Angular for data-binding

Currently utilizing angular.js 1.4 and I have a data-binding input setup as follows: <input ng-model="name"> Is there a way to manually change the value without physically entering text into the input field? Perhaps by accessing the angular object, ...

Responsive Alignment of Slanted Edges using CSS

I have been working on creating a responsive diagonal layout with slanted shapes (refer to the image attached). However, I'm facing a challenge with aligning the edges smoothly at different screen sizes, especially when the rows grow and the screen re ...

What is the best way to trigger a snackbar notification when two passwords do not match?

I'm currently developing a full stack application and I am facing an issue with displaying a snackbar in my signup component when the user's password and confirm password do not match. I have been advised to pass the setOpenAlert method as props ...