0

My apologies if the subject is a bit non-descriptive. I'm having a hard time trying to explain what I'm trying to achieve in a one-liner.

But in a few sentences: I'm trying to have an element, a DIV in this case, move smoothly to its new position. But the caveat is that I'm not setting its position manually. It receives a new position because I'm removing other DIVs from the page flow.

<!DOCTYPE html>
<html>
  <head>
    <style>
      .block {
        width: 200px;
        height: 20px;
        border: 1px solid black;
        margin: 20px;
      }
    </style>
    <script>
      function removeBlock() {
        document.getElementById("block2").style.display = "none";
      }
    </script>
  </head>
  <body>
    <div id="block1" class="block">
      This is block 1
    </div>
    <div id="block2" class="block">
      This is block 2
    </div>
    <div id="block3" class="block">
      This is block 3
    </div>

    <button type="button" onclick="removeBlock();">
      Remove block 2
    </button>
  </body>
</html>

Here's the fiddle: https://jsfiddle.net/nfhycrkL/

If you click the button, Block 2 is hidden and Block 3 moves up. I want this move to be smooth. Is this at all possible? I don't want to use absolute positioning since the page is responsive and the position of the DIVs are depending on the page size.

Zippy1970
  • 601
  • 6
  • 20
  • Use jquery effects. – Sumesh TG Dec 13 '18 at 09:49
  • take a look here https://stackoverflow.com/questions/3331353/transitions-on-the-display-property – irshad2809 Dec 13 '18 at 09:50
  • Transition the div that should disappear, e.g. if the divs are stacked you can transition the height of the div that should be removed, and when the height is 0 and the div does not show, you can delete it. The other divs should follow nicely. – Flux Dec 13 '18 at 09:54

5 Answers5

0

Try This Solution

function removeBlock()
{
  document.getElementById("block2").style.height = "0px";
  document.getElementById("block2").style.margin = "0px";
  document.getElementById("block2").style.borderWidth = "0px";
  document.getElementById("block2").style.fontSize = "0px";
}
.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px;
}

#block2 {
  transition:all 0.5s linear;
}
<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="removeBlock();">
  Remove block 2
</button>
Chandresh Polra
  • 229
  • 1
  • 5
0

You could add a new class to an element with javascript that you want to hide and do css transition.

Here's a small example with remove and toggle options https://jsfiddle.net/nfhycrkL/9/

html:

<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="toggleBlock();">
  Toggle block 2
</button>

<button type="button" onclick="removeBlock();">
  Remove block 2
</button>

js :

function toggleBlock() {
  document.getElementById("block2").classList.toggle('block-hidden')
}
function removeBlock() {
  document.getElementById("block2").classList.add('block-hidden')
}

css:

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 0 20px 20px;
  overflow:hidden;
  transition: all .25s;
}

.block-hidden {
  height: 0px;
  margin: 0px;
  border: none;
}
Jimi Pajala
  • 2,358
  • 11
  • 20
0

$(document).ready(function(){
 
  $("button").click(function(){
  //document.getElementById("block2").style.display = "none";
   $("#block2").fadeOut(1000);
  });
});
.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>

<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button">
  Remove block 2
</button>

use Jquery effects. I hope this helps.

Sumesh TG
  • 2,557
  • 2
  • 15
  • 29
0

Here's a simple example in vanillaJS with a CSS transition

Jsfiddle demo


Update your style adding a transition for the .block element

CSS

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px 20px 0;
  max-height: 500px;
  transition: opacity 0s 0s, margin .25s 0s, max-height .25s 0s;
}

.removedBlock {
  box-sizing: border-box;
  opacity: 0;
  margin: 0;
  max-height: 0;
}

so that the function can trigger a max-height animation by adding the removedBlock class

<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="removeBlock('block2');">
  Remove block 2
</button>

JS

function removeBlock(id) {
  var block = document.getElementById(id);
  block.classList.add('removedBlock');
}

When you do a removal, the element disappears due the opacity set to 0, then margin and max-height will make the block collapsing.

Note that since a transition can't be triggered to/from an auto value I've set a huge starting max-height for this purpose. If you want to see a smoother transition either change that property with a lower value or simply increase the duration of the transition.


A more refined version could instead get the height of the element before applying the transition e.g.

function removeBlock(id) {
  var block = document.getElementById(id);
  var blockHeight = block.offsetHeight;
  block.style.height =  blockHeight + 'px';
  block.classList.add('removedBlock');
}

so the style becomes

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px 20px 0;
  transition: opacity 0s 0s, margin .5s 0s, height .5s 0s;
}

.removedBlock {
  box-sizing: border-box;
  opacity: 0;
  margin: 0;
  height: 0 !important;
}

JsFiddle

Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
0

Thanks everybody for your answers! And although all of them work somewhat, they do not work as soon as the layout becomes more complex, or if you try to hide/show more/other objects.

So I spend the past few hours creating a Javascript solution that I think will work in any situation (and on any browser too).

In short, how it works is that you "mark" as many elements as you like to be hidden/shown with the SetDisplay() function (see the first button). Once that has been done, you call the same SetDisplay function without any parameters and see the magic happen! The Javascript actually quickly removes the elements and let the page reflow (all invisible to the viewer). It then examines the new positions, reinserts the elements to hide and move all other elements to their new position by setting style.transition and by using position:relative and new top and left values. Once it's done with the transition, it hides the elements permanently, resets all changed style values and let the page reflow again.

SetDisplay( "block2", "none" );
SetDisplay( "block3", "none" );
SetDisplay( "block4", "none" );
SetDisplay();

You can reinsert elements the same way (the second button).

SetDisplay( "block2", "" );
SetDisplay();

https://jsfiddle.net/yq7xor5j/3/

(Edit: made a change to the fiddle to correct a small bug)

Zippy1970
  • 601
  • 6
  • 20