Search code examples
htmlcssformsflexboxposition

HTML form input elements visually positioned outside form


I have container with height set to 0 which contains form.

<div class="container">
    <div role="button" data-define="show.element">show register form</div>
    <div class="box-wrapper">
      <div class="box">
        <form>
          <input class="form-element" type="text" name="login" placeholder="login"/>
          <input class="form-element" type="password" name="password" placeholder="password"/>
          <input class="form-element-submit" type="submit"/>
        </form>
      </div>
    </div>
  </div>

What I want to achieve, is form sliding out of "box-wrapper" element (which initially has display property visibility set to hidden) after clicking button with "show register form" text. On click I'm adding css class which changes box element height and sets property visibility of box-wrapper element to "visible". However form input elements are "sliding" out not from box-wrapper element as I intented, they seems to have be initially placed at top of "container" element. Here is my CSS code:

body {
  background: #34495E;
}
.container {
  position: absolute;
  left: 50%;
  top: 50%;
  background: #191919;
  transform: translate(-50%, -50%);
  width: 400px;
  height: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
div[data-define="show.element"] {
  width: 150px;
  text-align: center;
  background: none;
  border: 2px solid #3498db;
  border-radius: 15px;
  color: white;
  padding: 5px 10px;
  transition: 0.25s;
  outline: none;
}
div[data-define="show.element"]:hover {
  cursor: pointer;
  border-color: #2ECC71;
}
div[data-define="show.element"]:active {
  transform: translatey(2px);
}
.box {
  width: 300px;
  height: 0;
  border: none;
  transition: 1s;

  &-wrapper {
    position: relative;
    margin: 15px auto;
    width: 300px;
    height: 300px;
    visibility: hidden;

    &-visible {
      visibility: visible;
    }
  }
  &-active {
    height: 300px;
  }
}
form {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.form-element {
  margin: 10px auto;
  width: 150px;
  background: none;
  border: 2px solid #3498db;
  border-radius: 15px;
  color: white;
  padding: 5px 10px;
  transition: width 0.25s;
  text-align: center;
  outline: none;

  &-submit {
    margin: 10px auto;
    width: 150px;
    background: none;
    border: 2px solid #3498db;
    border-radius: 15px;
    color: white;
    padding: 5px 10px;
    transition: 0.25s;
    outline: none;
  }
}
.form-element:focus {
  width: 250px;
  border-color: #2ECC71;
}
.form-element-submit:hover {
  background: #2ECC71;
}

Working codepen: https://codepen.io/Furmanus/pen/oVqKJG?editors=0100

What I did wrong? Thanks for help in advance.


Solution

  • Make body relative. Add z-index and background property to show.element button. Set box height to maybe 20px so that box-wrapper seems to originate from show.element button.

    body {
      background: #34495E;
      position: relative;
    }
    .container {
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -12.5%;
        background: #191919;
        width: 400px;
        height: 400px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    div[data-define="show.element"] {
        width: 150px;
        z-index: 1;
        text-align: center;
        background: #191919;
        border: 2px solid #3498db;
        border-radius: 15px;
        color: white;
        padding: 5px 10px;
        transition: 0.1s;
        outline: none;
    }
    .box {
      width: 300px;
      height: 20px;
    }
    

    Updated codepen - https://codepen.io/anon/pen/QorQrj?editors=0100

    EDIT - Ah like @kukkuz mentioned, justify-content was the problem. When the height of parent is 0 but justify-content is center. It tries to vertically center the child elements whose heights are greater than 0 and ends up going above to vertically center on a parent whose height is 0.

    Removing justify-content will position your input elements the way you desire but there is a problem with slide animation because the input elements stay where they are supposed to and the transition makes no difference because these elements arent affected.

    So set, margin, border, height, padding of input elements to 0 by default. And on click of "show register form", update these properties to what they are supposed to be.

    https://codepen.io/anon/pen/QorQrj?editors=0100