Элементы ввода HTML-формы визуально расположены вне формы - PullRequest
1 голос
/ 16 марта 2019

У меня есть контейнер с высотой 0, который содержит форму.

<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>

То, чего я хочу добиться, - это скольжение формы из элемента «box-wrapper» (который изначально имеет свойство display visibility, установленное в hidden) после нажатия кнопки с текстом «show register form». При нажатии я добавляю класс css, который изменяет высоту элемента box и устанавливает видимость свойства элемента box-wrapper на «visible». Однако элементы ввода формы «выдвигаются» не из элемента box-wrapper, как я и предполагал, они, кажется, изначально были помещены поверх элемента «container». Вот мой код CSS:

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;
}

Рабочий код: https://codepen.io/Furmanus/pen/oVqKJG?editors=0100

Что я сделал не так? Заранее спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 17 марта 2019

Все, что вам нужно сделать, это вывести button над box-wrapper в контексте стека, используя z-index. Поэтому добавьте z-index: 1 к button - поскольку z-index работает только на позиционированных элементах (элемент не должен иметь static position), теперь он будет работать. Вы можете прочитать больше о z-index and stacking context here.

Теперь добавьте фон к button, чтобы мы могли визуально понять глубину - см. Демонстрацию ниже и updated codepen:

const button = document.querySelector('div[role="button"]');
const submit = document.querySelector('input[type="submit"]');
const form = document.querySelector('form');
const box = document.querySelector('.box');
const boxWrapper = document.querySelector('.box-wrapper');
let isVisible = false;

button.addEventListener('click', () => {
  if (isVisible) {
    box.classList.remove('box-active');
    boxWrapper.classList.remove('box-wrapper-visible');
    isVisible = false;
  } else {
    box.classList.add('box-active');
    boxWrapper.classList.add('box-wrapper-visible');
    isVisible = true;
  }
});
form.addEventListener('submit', e => {
  e.preventDefault();
});
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: #191919; /* background added */
  border: 2px solid #3498db;
  border-radius: 15px;
  color: white;
  padding: 5px 10px;
  transition: 0.1s;
  outline: none;
  position: relative; /* positioned the element */
  z-index: 1; /* added z-index */
}
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;
}
.box-wrapper {
  position: relative;
  margin: 15px auto;
  width: 300px;
  height: 300px;
  visibility: hidden;
}
.box-wrapper-visible {
  visibility: visible;
}
.box-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;
}
.form-element-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;
}
<body>
  <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>
</body>

Чтобы решить проблему с элементом формы, расположенным сверху container, а не сверху box-wrapper - посмотрите, что произойдет, когда я добавлю min-height: 0 к элементам input:

const button = document.querySelector('div[role="button"]');
const submit = document.querySelector('input[type="submit"]');
const form = document.querySelector('form');
const box = document.querySelector('.box');
const boxWrapper = document.querySelector('.box-wrapper');
let isVisible = false;

button.addEventListener('click', () => {
  if (isVisible) {
    box.classList.remove('box-active');
    boxWrapper.classList.remove('box-wrapper-visible');
    isVisible = false;
  } else {
    box.classList.add('box-active');
    boxWrapper.classList.add('box-wrapper-visible');
    isVisible = true;
  }
});
form.addEventListener('submit', e => {
  e.preventDefault();
});
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: #191919; /* background added */
  border: 2px solid #3498db;
  border-radius: 15px;
  color: white;
  padding: 5px 10px;
  transition: 0.1s;
  outline: none;
  position: relative; /* positioned the element */
  z-index: 1; /* added z-index */
}
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;
}
.box-wrapper {
  position: relative;
  margin: 15px auto;
  width: 300px;
  height: 300px;
  visibility: hidden;
}
.box-wrapper-visible {
  visibility: visible;
}
.box-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;
  min-height: 0; /* added */
}
.form-element-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;
}
<body>
  <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>
</body>

Эта проблема явно связана со значением по умолчанию min-height: auto для гибкого бокса для столбцов - элементов Flex занимает минимум места, равное их содержанию в направлении Flex.

И еще одна причина небольшого смещения к вершине в том, что у вас есть justify-content: center для вашего form элемента.

1 голос
/ 17 марта 2019

Сделать тело относительным. Добавьте z-index и фоновое свойство к кнопке show.element. Установите высоту коробки равной, возможно, 20 пикселей, так что упаковщик коробки, кажется, происходит от кнопки show.element.

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;
}

Обновлен кодовый блок - https://codepen.io/anon/pen/QorQrj?editors=0100

РЕДАКТИРОВАТЬ - Ах, как упомянуто @kukkuz, проблема в justify-content. Когда высота родителя равна 0, а justify-content находится в центре. Он пытается центрировать по вертикали дочерние элементы, высота которых больше 0, и в конечном итоге идет вверх, чтобы вертикально центрировать родительский элемент, высота которого равна 0.

Удаление justify-content разместит ваши элементы ввода так, как вы хотите, но есть проблема с анимацией слайдов, потому что элементы ввода остаются там, где они должны, и переход не имеет значения, потому что эти элементы не затрагиваются.

По умолчанию для полей ввода, полей, высоты, отступов и отступов установлено значение 0. И по щелчку «Показать форму регистрации», обновите эти свойства до того, что они должны быть.

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

...