The parent's height dynamically adjusts based on the height of its visible children using only CSS

I am dealing with the following structure:

<div class="body">
  <div class="wrapper">
    <div class="dialog">
      <div class="content-0"></div>
      <div class="content-1"></div>
      <div class="content-2"></div>
    </div>
  </div>
</div>

The parent element .dialog contains three content items that are aligned horizontally. Only the active .content-* item is visible, while the others remain hidden. When a user clicks a button, the active item slides to the left into the hidden area, and the next item becomes active and visible. Here is a fiddle illustrating this behavior: https://jsfiddle.net/fmbn28xs/

My query is - can I dynamically adjust the height of the parent (.dialog) every time a user clicks a button based on the height of the visible content (.content-*) item using only CSS, is this achievable?

Update: The heights of the content items are not predetermined.

Answer №1

If you want to achieve this using custom CSS properties, here's a preview with the full page:

var index = 0;
function slide() {
  index++;
  var current = index % 3;
  var target = document.querySelector(`.dialog`);
  target.style.setProperty('--index', current);
}
.body {
  background-color: #fff;
  width: 100%;
  height: 100%;
  position: relative;
}

.wrapper {
  background-color: grey;
  position: absolute;
  top: 50%;
  right: 50%;
  transform: translate(50%, 20%);
  overflow: hidden;
}

.dialog {
  --index: 0;
  width: 300px;
  display: flex;
  height: calc(200px + 50px * var(--index));
  transition: transform 400ms, height 400ms;
  transform: translateX(calc(var(--index) * -100%));
}
.content-0, .content-1, .content-2 {
  width: 300px;
  flex: 0 0 100%;
  position: relative;
}

.content-0 {
  background-color: tomato;
  height: calc(200px + 50px * 0);
}

.content-1 {
  background-color: yellow;
  height: calc(200px + 50px * 1);
}

content-2 {
  background-color: green;
  height: calc(200px + 50px * 2);
}

button {
  position: relative;
}
<div class="body">
  <div class="wrapper">
    <div class="dialog">
      <div class="content-0"></div>
      <div class="content-1"></div>
      <div class="content-2"></div>
    </div>
    <button onclick="slide()">Next</button>
  </div>
</div>

It's important to manually assign heights to all content.

If you're using a precompiled CSS library like SCSS, you can automate this process as well:

.dialog > *{
  @for $i from 1 through 3 {
    &:nth-child(#{$i}) {
      height: calc(200px + 50px * #{$i});
    }
  }
}

Update

If the height needs to be dynamic, you can use a trick with animation and switch between relative and absolute positioning to make the container adjust its height accordingly. However, note that in this case, you won't be able to animate the height change due to it being determined by the children's heights.

var index = 0;
function slide() {
  index++;
  var current = index % 3;
  var target = document.querySelector(`.dialog`);
  target.style.setProperty('--index', current);
  target.setAttribute('data-index', current);
}
.body {
  background-color: #fff;
  width: 100%;
  height: 100%;
  position: relative;
}

.wrapper {
  background-color: grey;
  position: absolute;
  top: 50%;
  right: 50%;
  transform: translate(50%, 20%);
  overflow: hidden;
}

.dialog {
  --index: 0;
  width: 300px;
  position: relative;
}

.dialog > * {
  width: 300px;
  position: absolute;
  z-index: 0;
  animation: popout 400ms both;
  top: 0;
}

.dialog[data-index='0'] > *:nth-child(1), 
.dialog[data-index='1'] > *:nth-child(2), 
.dialog[data-index='2'] > *:nth-child(3) {
  position: relative;
  z-index: 1;
  animation: popin 400ms both;
}

.content-0 {
  background-color: tomato;
  height: 200px;
}

.content-1 {
  background-color: yellow;
  height: 250px;
}

content-2 {
  background-color: green;
  height: 300px;
}

button {
  position: relative;
}

@keyframes popin {
  from {
    transform: translateX(100%);
  }
  
  to {
    transform: translateX(0);
  }
}

@keyframes popout {
  from {
    transform: translateX(0);
  }
   
  to {
    transform: translateX(-100%);
  }
}
<div class="body">
  <div class="wrapper">
    <div class="dialog" data-index="0">
      <div class="content-0"></div>
      <div class="content-1"></div>
      <div class="content-2"></div>
    </div>
    <button onclick="slide()">Next</button>
  </div>
</div>

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

Differentiating categories in the second parameter for controller method in AngularJS?

As a newcomer to Angular, I have noticed that the locals argument in the controller function can sometimes be just a function and other times an array. angular.module('contentful').controller( 'FormWidgetsController', ['$s ...

Achieving success by correctly reaching the window's edge during an event (onscroll)

This happens to be my 1st inquiry. Specifically, I have a navigation menu with a transparent background and I am attempting to alter the background once it reaches the top edge of the window. window.addEventListener("scroll", navSticky); function navSt ...

Creating an adaptable grid system in Vue Material

I am working on a project where I am using Vue-Material to display user-inputted cards in a grid layout. While the cards are rendering correctly, I want to optimize the grid to make it flexible, justify the cards, and stagger them in a way that eliminates ...

The initial setTimeout function functions correctly, however the subsequent ones do not operate as expected

I have developed the following code: bot.on('message', message=> { if(message.content === "come here") { message.channel.send('hey'); setTimeout(() => { message.channel.send('i am here' ...

What is the best approach to refreshing a particular div with the contents of a view file?

I have a block of code in PHP/Symfony that looks like this: <div id='content'> <?php include_partial( 'course/content.php', array("param1" => "1", "param2" => "2") ); ?> </div> Now, I am interested in updatin ...

Persisting Undefined Values Even After Proper Prop Passing

I'm currently working on fetching and passing coaching data as props to another component for rendering on the frontend. I need to pass these props to the CoachingCard Component in order to display the coaching values. However, I'm encountering ...

I need help figuring out how to retrieve the full path of an uploaded file in JavaScript. Currently, it only returns "c:fakepath" but I need

Is there a way to obtain the complete file path of an uploaded file in javascript? Currently, it only shows c:\fakepath. The file path is being directly sent to the controller through jquery, and I need the full path for my servlet. Are there any alte ...

Tips for maintaining the navigation tab's consistent appearance

Whenever I click a button on the sidebar and the current tab is the second tab, the navigation bar switches to display the first tab. How can I prevent this switch and keep the second tab displayed when clicking a button on the sidebar? The code for this ...

billboard.js: The 'axis.x.type' property is conflicting with different data types in this context

axis: { x: { type: "category" } }, An issue has arisen: The different types of 'axis.x.type' are not compatible with each other. The value of 'string' cannot be assigned to '"category" | &qu ...

Issue with AjaxComplete function failing to work

Currently, I am tackling the Opera workaround for printing IFrames. As we are aware, the only method to print an IFrame is by opening it in a new window and then printing it. However, I am encountering an issue where a series of ajax calls are triggered wh ...

The initial navigation pill content failed to display in Bootstrap

I am experiencing an issue with my pills that have 4 tabs. Initially, when I reload the page, the content of the first tab does not show up. However, if I navigate to another tab and then back to the first tab, the content appears. Can anyone suggest a fix ...

Animate specifically new items in a list rendered via ngFor in Angular animation

I am working with a list of array items in an ngFor loop. I have a basic button that adds an item to the array. My goal is to apply an animation only to the newly added items, but currently all the existing list items also receive the animation upon page l ...

Verify whether the document includes a class that closely matches the provided string using Javascript

I need help identifying elements that include the letters 'ad'. For example: <iframe class="container" /> <!-- Not relevant --> <a class="adp" /> <!-- Relevant --> <a class="adleft" /> ...

Finding out which carousel the user is currently engaging with in the Slick Carousel can be accomplished by following these steps

I am struggling with applying a class to the carousel container when the first slide is active in a page that contains multiple Slick carousels. Is there a way to update the code below so that the class is only applied to the specific carousel the user is ...

Obtain the selected option from a user list

In my user table, each user is listed with a name, surname, right, and a "commit changes" button. The purpose of this setup is to assign rights to different individuals. Each column contains the userID, and the entire structure is generated from a database ...

Formatting dates in a C# MVC application after parsing JSON

I am working on an MVC application that retrieves data from a SQL database and passes it to a view. One of the views contains a Kendo grid that displays the data, including a date column. The date data is stored in the SQL database as DateTime, while the m ...

What is the role of the equal sign (=) when connecting a function to an event listener in JavaScript?

What is the rationale behind using the equal sign "=" instead of the dot "." when attaching a function to an event listener in JavaScript? Normally, it is the convention to use the dot as notation for perform an action. clickme.onclick = function() { ...

The ExpressJS app generator seems to be struggling to identify and interpret the flags

I seem to be having trouble running the express app generator with flags. For example, when I run express --version, it interprets the --version part as a target directory and creates the app there. This is happening on Windows XP SP3. Could I be doi ...

Having trouble accessing dynamically generated elements using Selenium

I've been attempting to change the router's SSIDs using a Selenium script, but I'm encountering difficulty accessing any JS elements generated by the router page. I've tried various Expected Conditions and methods without success. Here ...

Order the rows being inserted into a table by iterating through them using a foreach loop directly from the

I am currently working on a table that receives its data from a database. The table structure includes the typical header row, and then I use a foreach() loop to fetch information from an included file and display it in the table body (with a new row for e ...