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

Ways to implement distinct values for model and input field in Angular 5

I'm currently working on an Angular 5 application and I have a requirement to format an input field with thousand separators (spaces). However, the model I am using only allows numbers without spaces. Since my application is already fully developed, ...

Which one relies on the other: angular-data or angular-cache?

I'm struggling to get angular-cache set up properly. According to the documentation: Angular-cache is a dependency of angular-data and must be loaded before angular-data if you are using angular-data. That's all well and good, but what if I only ...

Struggling to align a div at the center of a screen

Snippet of HTML Code: <body> <!-- Social Media Icons --> <div id="sm1"><a href="/"><img src="images/facebook.png" height=40 width=40></img></a> </div> <div id="sm2"><a href="/"><img src="image ...

Retrieve the data from a Sequelize Promise without triggering its execution

Forgive me for asking, but I have a curious question. Imagine I have something as simple as this: let query = User.findAll({where: {name: 'something'}}) Is there a way to access the content of query? And when I say "content," I mean the part g ...

The text does not change in the input field even with the .value method

I'm encountering an issue where I want to use .value to set the text of an input field. However, after setting the value of the input field, the text disappears when clicked on. I would like to find a solution where the text does not disappear upon cl ...

javascript string assignment

Is it possible to conditionally assign a string based on the result of a certain condition, but for some reason, it's not working? var message = ""; if (true) { message += "true"; } else { message += "false" } console.log(message); ...

Error encountered: Element cannot be clicked on at specified coordinates - Angular/Protractor

Recently, I have been testing out CRUD functionality in an Angular app using Protractor. One recurring issue I've encountered is with the create/edit buttons, which all open the same modal regardless of the page you're on. The frustrating part i ...

Tips for invoking an asynchronous function within an if condition?

When trying to maintain variables in the background.js of a Chrome extension, I encountered difficulties that require me to reinitialize some global variables. Here is the code snippet (view fiddle) I am using to demonstrate the issue: var temp = null; ...

Differences in layout design when using floats and display: table between Chrome and Firefox can affect the visual appearance

Try out this link on JS Fiddle: https://jsfiddle.net/7p81bnto/2/ Here's the HTML code: <body> <main> <div> <div style=" height: 50px; width: 200px; ...

Setting up of imagemagick node module using linuxbrew

Having trouble installing imagemagick-native as it's showing an error. Tried using the following command to install: npm install imagemaick-native --save > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2c45414d ...

What is the best way to apply filtering to my data source with checkboxes in Angular Material?

Struggling to apply datatable filtering by simply checking checkboxes. Single checkbox works fine, but handling multiple selections becomes a challenge. The lack of clarity in the Angular Material documentation on effective filtering with numerous element ...

How can I position text below a ticked checkbox?

Having an issue with my HTML and jQuery code. Everything is working fine, but when I click on a checkbox, the text "FINISHED" appears below all checkboxes instead of just the one I clicked on. This is my html code: $('.label__checkbox').cli ...

Utilize flex to position content at the bottom

My layout features a fixed header and footer, positioned at the top and bottom respectively. The content section in between fills the remaining space, with a scrollbar available if the content extends beyond the area. <div id="app"> <d ...

Why is my webpage attempting to refresh every time I send an AJAX request?

I have been struggling to send a form using AJAX, but no matter how many times I use e.preventDefault(), the page still tries to reload. Here is my HTML: <form action="/user/changeProfileData" id="edit-profile_form" method="post"> <ul class=& ...

When attempting to create a build using npm run, an error with code ELIFECYCLE occurred despite successfully installing

I've been attempting to run the lodash library on my computer. You can find the library here on GitHub. I went ahead and forked the repository, then cloned it onto my system. I successfully installed all dependencies mentioned in the package.json fil ...

Customizable form fields in AngularJS

Consider the scenario of the form below: First Name: string Last Name: string Married: checkbox % Display the following once the checkbox is selected % Partner First Name: Partner Last Name: [Submit] How can a form with optional fields be created in Angu ...

Syntax error occurs while attempting to render the return statement in a React Component

Just starting out with React and encountering a syntax issue that has me stumped. I'm working on a React Component and I thought I had the opening/closing { & }'s correct, but clearly there's something missing based on the error message it&a ...

What is the solution to the error "Maximum update depth exceeded. Calls to setState inside componentWillUpdate or componentDidUpdate" in React?

Everything was running smoothly until this unexpected issue appeared. I attempted to change the condition to componentDidMount, but unfortunately, that didn't resolve the problem. The error is occurring in this particular function. componentDidUpd ...

Are there any other methods of using HREF in an <asp:Button> besides OnClientClick for invoking an inline div?

I decided to create a concealed <div> on the same page and tried calling it with href="#", which worked perfectly. However, when I attempted to use the same code in ASP.net, I encountered some issues with Javascript or other factors that prevented it ...

Dealing with Laravel and AJAX - Issue with Loading DIV

I find myself in a perplexing situation. Despite not encountering any errors in my apache logs or browser (chrome), I am faced with an issue that has left me baffled. On a specific page (localhost/admin/networks), I can click on an item from a database-ge ...