3

I have a form (contained in a div) for which I show and hide elements based on the page and on some conditions.

On the bottom of the form I have a previous and next button. Currently their position is changed abruptly if an element is added to the form, so I would like to like the div containing the form to change gradually.

How can I do this? I don't want to add transition to the form elements (as this would be too many transitions) but just for the containing DIV.

Héctor van den Boorn
  • 1,218
  • 13
  • 32
  • You can Check this previous question, it may help https://stackoverflow.com/questions/12070759/make-absolute-positioned-div-expand-parent-div-height – Monty Nabeel Jul 28 '18 at 08:11

2 Answers2

3

You can use transitions on the DIVs. If you are saying it is ok, why not do it?

.myDiv{
    -webkit-transition: height 1s ease;
    -transition: height 1s ease;
}

But, in order for height/width transitions to work, you need to specify a width/height on the div beforehand. If it is unset or set to auto, then the transition will still be abrupt.

Here is an example: https://codepen.io/anon/pen/rrYxQm

George Daniel
  • 570
  • 6
  • 9
0

You can't apply a pure css transition to the sizing change on the parent which occurs when an element is added/deleted from the form.

Here's one solution using transitioned margin-bottom to decrease the space the element takes up in the parent, and scale(1, 0) to make the element visually decrease in size.

setInterval(function() {
  
  let form = document.getElementsByTagName('form')[0];
  let formItem = form.children[Math.floor(Math.random() * 3)];
  formItem.classList.toggle('hidden');
  
}, 1000);
.page {
  position: fixed;
  box-sizing: border-box;
  width: 100%; height: 100%;
  left: 0; top: 0;
  padding: 30px;
}
form {
  position: relative;
  background-color: #a0a0a0;
}
.form-item {
  height: 50px;
  margin-bottom: 0;
  overflow: hidden;
  position: relative;
  outline: 1px solid black;
  background-color: #a0a0a0;
  transform-origin: 0% 0%;
  
  transform: scale(1, 1);
  transition: margin-bottom 1s ease-in-out, transform 1s ease-in-out;
}
.form-item.hidden {
  margin-bottom: -50px;
  transform: scale(1, 0);
}
.form-item > .label {
  margin: 0;
  color: #ffffff;
}
<div class="page">
  <form>

    <div class="form-item">
      <p class="label">Item 1</p>
      <input type="text" name="item1"/>
    </div>
    
    <div class="form-item">
      <p class="label">Item 2</p>
      <input type="text" name="item2"/>
    </div>
    
    <div class="form-item">
      <p class="label">Item 3</p>
      <input type="text" name="item3"/>
    </div>
    
    <div class="form-item">
      <p class="label">Item 4</p>
      <input type="text" name="item4"/>
    </div>
    
    <div>
      <input type="button" name="prev" value="Prev"/>
      <input type="button" name="next" value="Next"/>
    </div>
    
  </form>
</div>

A limitation here is that you need to know the height of the input field ahead of time. You'll note that it's hardcoded to 50px in this example.

Note: Don't worry about "too many transitions". The browser will certainly be able to manage a bunch of height-transitioning child elements.

Gershom Maes
  • 7,358
  • 2
  • 35
  • 55