Gabriel Costache
Gabriel Costache

Reputation: 969

Anomalous padding/margin during slideToggle() jquery

Does slideToggle() change padding or margins during the transition and than bringing them back to normality? Bacause i'm trying to toggle two forms, one for login and one for registration for a static html page, but during the transition something like a top margin is created between my forms and other stuff (A text to be precise) and than everything is resized back to how it is supposed to be.

First screen is with static page and no transition, the latter during the transition: https://i.sstatic.net/dyGjP.jpg Here the code, I'm programming on Atom with live server plugin:

// Example starter JavaScript for disabling form submissions if there are invalid fields

var index_toggle = new Boolean(true);

$(document).ready(function() {
  $("#toggle_home").click(function() {
    $("#login").slideToggle("slow");
    $("#register").slideToggle("slow");
    $("#toggle_home_txt").fadeOut(function() {
      if (index_toggle) {
        $(this).html("↧ LOGIN").fadeIn();
      } else {
        $(this).html("↥ REGISTER").fadeIn();
      }
      index_toggle = !index_toggle;
    });


  });
});
#register {
  display: none;
}

body.index {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  padding-top: 80px;
  padding-bottom: 40px;
  background-color: white;
  color: #6c757d;
}

div.index {
  padding-top: 40px;
  padding-bottom: 0px;
  border-radius: 3%;
  width: 500px;
}

button {
  border-radius: 20%;
  padding-bottom: 10%;
  padding-top: 0;
  background-color: #e9ecef;
  border-color: #6c757d;
  border-style: solid;
  color: #6c757d;
  transition: 0.3s ease;
}

button:focus {
  outline: none;
}

#send_butt {
  width: 40px;
  height: 40px;
}

button:hover {
  background-color: #6c757d;
  color: white;
}

button.toggle_home {
  top: 0px;
  padding-bottom: 2%;
  transform: translate(0, -100%);
}

img.index {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -100%);
  background-color: #e9ecef;
  border-color: white;
  border-style: solid;
}

.form-signin {
  width: 450px;
  padding: 15px;
  margin: auto;
}
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body class="text-center index">
  <div class="jumbotron index form-signin">
    <img src="images/user_index.png" class="index" />
    <p id="index_text" class="my-3">Please fill this form to create an account.</p>



    <form id="login" novalidate>
      <hr>

      <div class="form-row">
        <!-- Username input -->
        <div class="col-md-12 mb-3">
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"> &rsaquo;</span>
            </div>
            <input type="text" class="form-control" id="LoginUsername" placeholder="Username" required>
          </div>
        </div>
      </div>

      <!-- Password input -->

      <div class="form-row">
        <input type="password" class="col-md-6 mb-3 form-control" id="LoginPassword" placeholder="Password" required>

        <div class="text-right col-md-6 mb-3 form-check">
          <input class="form-check-input" type="checkbox" id="LoginRemember">
          <label class="form-check-label" for="LoginRemember">Remember me?</label>
        </div>
      </div>
    </form>

    <div id="div_toggle">
      <hr>
      <div class="toggle_home" style="float:left;">
        <button id="toggle_home" class="toggle_home">
              <div id="toggle_home_txt">
                &#8613; REGISTER
              </div>
            </button>
      </div>
    </div>

    <form id="register" class="form-signin mt-5" novalidate>

      <div class="form-row">
        <div class="col mb-3">
          <input type="text" class="form-control" id="RegName" placeholder="First name" required>
        </div>
        <div class="col-md-6 mb-3">
          <input type="text" class="form-control" id="RegSurname" placeholder="Surname" required>
        </div>
      </div>
      <div class="form-row">
        <div class="col-md-12 mb-3">
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"> &rsaquo;</span>
            </div>
            <input type="text" class="form-control" id="RegUsername" placeholder="Username" required>
          </div>
        </div>
      </div>
      <div class="form-row">
        <div class="col-md-6 mb-3">
          <input type="password" class="form-control" id="RegPassword" placeholder="Password" required>
        </div>
        <div class="col-md-6 mb-3">
          <input type="password" class="form-control" id="RegConfirmPassword" placeholder="Confirm Password" required>
        </div>
      </div>
      <hr/>
    </form>
    <div style="float:right;">
      <button id="send_butt" class="mb-2">&#8250;</button>
    </div>
  </div>
</body>

Upvotes: 0

Views: 577

Answers (2)

Steve de Niese
Steve de Niese

Reputation: 984

For anyone looking for another solution to this issue, you can use a pseudo element with a fixed height in place of margins to stop the collapsing margins effect, e.g:

.hidden-element:before {
  display: block;
  width: 100%;
  height: 24px; /* the top margin height you want */
  content: '';
}

You can also use an :after for the bottom margin.

Upvotes: 1

showdev
showdev

Reputation: 29188

I believe the changing gap is a result of margin collapse.

Parent and first/last child
If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of its first child block ... then those margins collapse. The collapsed margin ends up outside the parent.

On page load, margins are collapsed between p.index_text and the <hr> inside form#login. When jQuery starts slideDown(), it adds overflow:hidden to the sliding element #form#login. This creates "clearance" between the <p> and the <hr> and the margin stops collapsing. Visually, the gap increases between the two elements.

There are various methods to prevent margin collapse. I chose padding since the other form already has some:

#login {
  padding:15px;
}

Working example:

// Example starter JavaScript for disabling form submissions if there are invalid fields

var index_toggle = new Boolean(true);

$(document).ready(function() {
  $("#toggle_home").click(function() {
    $("#login").slideToggle("slow");
    $("#register").slideToggle("slow");
    $("#toggle_home_txt").fadeOut(function() {
      if (index_toggle) {
        $(this).html("&#8615; LOGIN").fadeIn();
      } else {
        $(this).html("&#8613; REGISTER").fadeIn();
      }
      index_toggle = !index_toggle;
    });


  });
});
#register {
  display: none;
}

body.index {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  padding-top: 80px;
  padding-bottom: 40px;
  background-color: white;
  color: #6c757d;
}

div.index {
  padding-top: 40px;
  padding-bottom: 0px;
  border-radius: 3%;
  width: 500px;
}

button {
  border-radius: 20%;
  background-color: #e9ecef;
  border-color: #6c757d;
  border-style: solid;
  color: #6c757d;
  transition: 0.3s ease;
}

button:focus {
  outline: none;
}

#send_butt {
  width: 40px;
  height: 40px;
}

button:hover {
  background-color: #6c757d;
  color: white;
}

img.index {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -100%);
  background-color: #e9ecef;
  border-color: white;
  border-style: solid;
}

.form-signin {
  width: 450px;
  padding: 15px;
  margin: auto;
}

#login {
  padding:15px;
}

hr,
#register {
  margin: 0 !important;
}

#div_toggle {
  display: flex;
  align-items: center;
}
#div_toggle:after {
  content: "";
  flex: 1 0 auto;
  border-top: 1px solid #CCC;
}
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body class="text-center index">
  <div class="jumbotron index form-signin">
    <img src="images/user_index.png" class="index" />
    <p id="index_text" class="my-3">Please fill this form to create an account.</p>



    <form id="login" novalidate>
      <hr>

      <div class="form-row">
        <!-- Username input -->
        <div class="col-md-12 mb-3">
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"> &rsaquo;</span>
            </div>
            <input type="text" class="form-control" id="LoginUsername" placeholder="Username" required>
          </div>
        </div>
      </div>

      <!-- Password input -->

      <div class="form-row">
        <input type="password" class="col-md-6 mb-3 form-control" id="LoginPassword" placeholder="Password" required>

        <div class="text-right col-md-6 mb-3 form-check">
          <input class="form-check-input" type="checkbox" id="LoginRemember">
          <label class="form-check-label" for="LoginRemember">Remember me?</label>
        </div>
      </div>
    </form>

    <div id="div_toggle">
      <button id="toggle_home" class="toggle_home">
              <div id="toggle_home_txt">
                &#8613; REGISTER
              </div>
            </button>
    </div>

    <form id="register" class="form-signin mt-5" novalidate>

      <div class="form-row">
        <div class="col mb-3">
          <input type="text" class="form-control" id="RegName" placeholder="First name" required>
        </div>
        <div class="col-md-6 mb-3">
          <input type="text" class="form-control" id="RegSurname" placeholder="Surname" required>
        </div>
      </div>
      <div class="form-row">
        <div class="col-md-12 mb-3">
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text"> &rsaquo;</span>
            </div>
            <input type="text" class="form-control" id="RegUsername" placeholder="Username" required>
          </div>
        </div>
      </div>
      <div class="form-row">
        <div class="col-md-6 mb-3">
          <input type="password" class="form-control" id="RegPassword" placeholder="Password" required>
        </div>
        <div class="col-md-6 mb-3">
          <input type="password" class="form-control" id="RegConfirmPassword" placeholder="Confirm Password" required>
        </div>
      </div>
      <hr/>
    </form>
    <div style="float:right;">
      <button id="send_butt" class="mb-2">&#8250;</button>
    </div>
  </div>
</body>

The animations also seem to jump and the end, but that may be a separate issue.


Edit

Further jumping seems to have been caused by margin on the second form, so I removed it. The translated button seemed to cause problems, too, so I rebuilt it. Code above was edited accordingly.

Upvotes: 0

Related Questions