Switching between height: 0 and height:auto dynamically with the power of JavaScript and VueJS

Currently, I am changing the height of a container from 0px to auto. Since I do not know the exact final height needed for the container, using max-height could be an option but I prefer this method.

The transition from 0 to auto works smoothly, however, when going back from auto to 0, the animation duration is not as expected compared to collapsing and expanding (height 0 to auto).

To see an example, visit: https://codesandbox.io/s/q3471wj81w

Answer №1

utilize the max-height property for animation, where the height is set to auto and the max-height is set to a value larger than needed. Apply the transition on max-height and set it to 0 when collapsing, utilizing overflow:hidden to hide the text during collapse.

I faced difficulty implementing this in your VueJs environment, but here is an example that you can tailor to your requirements:

let article = document.querySelector('p');
document.querySelector('#btn').addEventListener('click', function() {
  article.classList.toggle('collapsed');
});
p {
  height: auto;
  max-height: 200px;
  transition: max-height .3s linear;
  overflow: hidden;
  background: #aaa;
}

.collapsed {
  max-height: 0;
}
<button id="btn">
collapse
</button>
<article>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at magna ac tellus volutpat cursus sed vitae nisi. Ut pellentesque mauris et orci sagittis placerat. Vivamus a dui sem. Morbi dignissim dictum elit sodales feugiat. Fusce in dolor
    non erat pretium malesuada ac at odio. Nulla consectetur, est et conseqc fringilla ligula egenisi ornare odio, vitae sodales ante ex non mauris. Vivamus iaculis faucibus nibh, nec posuere sapien posuere eget. Nulla ac est est. Nulla interdum vel eros
    vitae lobortis.</p>
</article>

Answer №2

One method to solve this issue is by making adjustments to the startTransition function within your Article component:

startTransition(evt) {
  const _height = this.$refs.articleBody.scrollHeight;
  this.height =  this.show ? `${_height}px` : 0;
  const timeout = setTimeout(() => {
    this.$nextTick(() => {
      this.height =  !this.show ? `${_height}px` : 0;
      this.show = !this.show;
      clearTimeout(timeout);
    });
  }, 50);
}

Although it could be refactored slightly, this approach serves its purpose well. It allows for setting up the height initially before triggering the height change.

Answer №3

After some investigation, I have discovered a solution to this problem. The key issue lies in transitioning between auto and specific height values, so I made some adjustments to address it.

I reverted the height property from auto to pixels by utilizing scrollHeight as a reference point. Then, I implemented a timeout to set the height to 0, allowing enough time for the transition to take effect smoothly.

Visit this link for more details

Answer №4

Apologies for reviving this aged discussion. For those grappling with the same issue as I once did, fret not! A revamped solution awaits. Utilizing directives in Vue makes achieving this a breeze. Moreover, effortlessly animate height adjustments without resorting to unconventional methods such as moving elements out of the DOM or relying on max-height guesswork.

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

A single image with dual clickable areas managed by an interactive image map

Is there a way to attach two href links to one image using CSS? I want it to function like an old school image map, but purely with CSS. Is this something that can be done? The current HTML code looks like the example below. However, I need the image to h ...

Is there a reason why async functions do not function properly within a controller's get() handler?

Utilizing Node and Express along with the mssql npm package, I establish a connection to an SQL Server database in my app.js file by setting up a global variable that creates a connectionPool (I've excluded some boilerplate code for brevity): const m ...

Python Selenium for Element Detection

I am a beginner when it comes to using Selenium and I am currently seeking guidance on how to locate the element that is highlighted in this image: https://i.sstatic.net/uXf4u.png Despite my attempts, the following code resulted in an error message being ...

Utilizing THREE.JS Raycaster with JavaScript "entities" rather than just meshes

I am facing a challenge with the Raycaster model. I grasp the concept of how it intersects meshes that can be transformed, but my issue lies in identifying when the specific instance of an object is clicked. Consider a scenario where there is a button. Th ...

Having difficulties hosting static Vue.js files using Express

Take a look at my express code: const express = require('express'); const serveStatic = require('serve-static'); const path = require('path'); // Setting up the express app const app = express(); var cors = require('cors ...

"Enhance your Vue 3 projects with a dynamic library featuring universal components and full

Currently, I am in the process of developing a Vue 3 component library using Vue 3, Vite, and TypeScript. The unique aspect about this library is that it installs as a plugin and registers all components as global entities. Here is an overview of how this ...

Monitor changes in Vue 3 global variables

In my codebase, I initially establish a provider in the main.ts file: app.provide('currentPage','test1') Following this setup, I proceed to inject it into a component named Home.vue: inject: ['currentPage'], By doing so, I ...

The CSS isn't loading properly once the file is uploaded to the server using FileZilla or cPanel

After uploading the file.css file to the server using both FileZilla and cPanel, I noticed that when I visit the website, the CSS is not being applied properly. Specifically, I changed padding-left: 10px; However, upon viewing the Page source, it appears ...

Fetching values from dynamically generated elements in a Vue.js loop

I am currently working on creating a table that includes checkboxes and text fields based on an array of items, essentially building a "questionnaire" where the questions are pulled from a database. My question now is how can I efficiently retrieve inform ...

Ways to verify multiple radio groups to ensure none have been left unchecked

https://i.sstatic.net/EoE1A.png Is there a more elegant solution to check if either "salad" or "side dish" is left unchecked after submission? I currently have a working approach, but it feels overly complex for such a simple task. This is my current me ...

I'm attempting to slightly adjust the alignment of the text to the center, but it keeps causing the text to shift

I am facing an issue where I want to slightly center text, but whenever I add just 1px of padding-left, it moves to a new line. In my layout, I have 2 columns each occupying 50% width of the screen. One column contains only a photo while the other has a ba ...

What is the best way to mirror an image using CSS3?

I'm looking to create a minimalist front page for my wife's jewelry website. I envision a simple layout with a blurred background and a sleek title at the top. In the center of the page, there will be several sections dedicated to different types ...

Creating a new JavaScript object using a Constructor function in Typescript/Angular

Struggling with instantiating an object from an external javascript library in Angular/Typescript development. The constructor function in the javascript library is... var amf = { some declarations etc } amf.Client = function(destination, endpoint, time ...

Adding external stylesheets or libraries in Express is a simple process that can greatly

Currently, I am in the process of developing a todo application using the express framework on a node server. The starting point for my application is an index.ejs file located in the same folder as my jquery.min.js file. However, when I attempt to include ...

What value does the "left" property default to?

When attempting to change the 'left: 0' property to 'left:none', I found that it did not work. Other properties such as margin and padding do work when overwritten. I aim to find a solution for this problem without altering the origina ...

Navigating views with ReactJS using ES5

I have been searching for ReactJs guides, but most of them are based in ES5. As a result, I have begun using ReactJS in this manner. Now that I understand how to create all my components, I am ready to build a small single-page-application. However, I am s ...

Discover the art of customizing child elements using vanilla extract!

I recently started using vanilla extract to add styles to a NextJS application. Is there a way to style child elements within the parent element without having to create another class? My React component has a structure like this: <ul className={style ...

What steps can be taken to address an unusual conflict arising between a form post and an ajax post

One web page features the use of ajax for editing existing values. This is achieved by utilizing jQuery Inline Edit to post new data, update records, and return with success. The process works well initially. Subsequently, I implemented the functionality ...

Iterate through a directory on the local machine and generate elements dynamically

I am looking to create a jQuery-UI tabs menu that includes 54 images on each tab. I have a total of 880 images stored in a folder, and it would be very time-consuming to manually insert an <img> tag for each one. Is there a way to dynamically cycle t ...

Stop the form from refreshing the page after submitting a post request to the backend API

I am facing an issue with my React front end and Express back end integration. I have a form in my front end that sends data to the API using two buttons - Submit and Close. The Close button works perfectly by closing the overlay without leaving the page, ...