ilyachalov (ilyachalov) wrote,
ilyachalov
ilyachalov

Category:

JavaScript: модальное диалоговое окно из HTML-формы (стили CSS)

Начало: JavaScript: модальное диалоговое окно из HTML-формы (каркас).

Продолжаю решать задачу, начатую в предыдущем посте. У нас есть содержимое «главного окна» и «дочернее диалоговое окно», написанные на языке HTML. К этому коду прилагается файл style.css (его полный код можно посмотреть в песочнице) от авторов задачи со стилями, описанными на языке CSS. Разберем эти стили.

Описание первого стиля:
html,
body {                   /* стиль «главного окна» */
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

Здесь убираем внутренние и внешние отступы HTML-страницы и ее тела, которые в браузерах задаются по умолчанию. Кроме этого, растягиваем HTML-страницу (наше «главное окно») на всё пространство области просмотра браузера (как я понимаю, по умолчанию размеры HTML-страницы и ее тела регулируются ее содержимым). Я не знаю, зачем понадобилось так растягивать HTML-страницу. По-моему, можно было обойтись и без этого.

Единственное, я добавил в этот стиль указание overflow: auto;, чтобы убрать вертикальное схлопывание внешних отступов HTML-элемента body и вложенного в него HTML-элемента h2, вызывающее появление вертикальной полосы прокрутки:
html,
body {                   /* стиль «главного окна» */
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: auto;        /* уберем схлопывание внешних отступов */
}
Я подробно разбирал этот случай в отдельном посте.

Добавим к вышеуказанному стилю следующий:
#prompt-form-container { /* стиль «дочернего диалогового окна» */
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
}

Теперь «дочернее диалоговое окно» уже находится над содержимым «главного окна» (изначально контейнер с HTML-формой, изображающий «дочернее диалоговое окно», находится в одном и том же основном потоке HTML-страницы вместе с содержимым «главного окна»).

Однако, это «дочернее диалоговое окно» пока еще не является модальным (достижение модальности, напомню, является нашей целью по условиям задачи). Потому что размеры контейнера (HTML-элемент div) в данном случае регулируются его содержимым, а оно сравнительно маленькое. Таким образом, контейнер скрывает под собой только небольшую часть HTML-страницы, а к части, которая не скрыта под контейнером, пользователь имеет свободный доступ, что нарушает модальность.

Чтобы достичь модальности, растянем контейнер, содержащий HTML-форму «дочернего диалогового окна», на всю область просмотра браузера, тогда он (контейнер) перекроет пользователю доступ к содержимому «главного окна» и модальность будет достигнута:
#prompt-form-container { /* стиль «дочернего диалогового окна» */
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  width: 100%;           /* растянем контейнер на всю область просмотра, */
  height: 100%;          /* чтобы обеспечить модальность */
}

Главная задача, которую предполагалось достичь с помощью описания стилей на языке CSS для рассматриваемой задачи, достигнута. Остальные описания стилей в рассматриваемом файле стилей служат для придания «дочернему диалоговому окну» красоты, что тоже немаловажно.

По условиям задачи «дочернее диалоговое окно» должно быть показано в центре области просмотра браузера. Центрируем HTML-форму «дочернего диалогового окна» в пределах контейнера по горизонтали (я отметил изменение красным цветом):
#prompt-form-container { /* стиль «дочернего диалогового окна» */
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  width: 100%;           /* растянем контейнер на всю область просмотра, */
  height: 100%;          /* чтобы обеспечить модальность */
  text-align: center;
}

Теперь следует центрировать HTML-форму «дочернего диалогового окна» в пределах контейнера по вертикали. Авторы задачи применили для этого способ выравнивания с помощью псевдоэлемента. Подробнее об этом и других способах вертикального выравнивания в CSS можно прочитать по следующей ссылке:

https://habr.com/ru/company/netcracker/blog/277433/

Почему для вертикального выравнивания придумывают такие заковыристые способы? Почему бы просто не добавить указание vertical-align: middle; в стиль HTML-формы, в нашем случае так:
#prompt-form {           /* стиль HTML-формы */
  vertical-align: middle;
}

Я добавил этот стиль к выше описанным, но это не повлекло никаких изменений на HTML-странице. Дело в том, что свойство vertical-align применяется только к строчным элементам и элементам ячеек таблицы, его нельзя использовать для вертикального позиционирования блочных элементов (HTML-форма по умолчанию — блочный элемент). Подробнее об этом можно почитать тут:

https://developer.mozilla.org/ru/docs/Web/CSS/vertical-align

Хорошо, изменим тип отображения HTML-формы на строчно-блочный (я отметил дополнение красным цветом):
#prompt-form {           /* стиль HTML-формы */
  display: inline-block;
  vertical-align: middle;
}

Вертикальное выравнивание всё еще не работает. Почему? Дело в том, что свойство vertical-align вертикально позиционирует строчный элемент внутри области содержащей его строки, а не относительно содержащего его контейнера. В данном случае в строке самым высоким элементом является сама выравниваемая HTML-форма, поэтому высота содержащей HTML-форму строки равна высоте этой HTML-формы и выравнивания по высоте не требуется.

Чтобы обойти описанную ситуацию, в способе выравнивания строчного элемента по вертикали с помощью псевдоэлемента предлагается создать псевдоэлемент высотой во всю высоту области просмотра браузера. Так как этот псевдоэлемент состоит в той же строке, что и выравниваемая HTML-форма, высота строки станет равна высоте псевдоэлемента, как самого высокого в строке, а HTML-форма будет успешно выравнена по высоте области просмотра браузера. Добавим стиль псевдоэлемента:
#prompt-form {           /* стиль HTML-формы */
  display: inline-block;
  vertical-align: middle;
}
                         /* псевдоэлемент для вертикального выравнивания HTML-формы */
#prompt-form-container:before {
  display: inline-block;
  height: 100%;
  content: '';
  vertical-align: middle;
}

Все четыре свойства, указанных здесь в стиле псевдоэлемента, важны. Без свойства content (даже если в нем задана лишь пустая строка, как в данном случае) псевдоэлемент вообще не будет вставлен на HTML-страницу и не появится в DOM-дереве. Указание height: 100%; делает высоту псевдоэлемента равной высоте области просмотра браузера, что, как было описано выше, нужно для центрирования HTML-формы по высоте.

Без указания display: inline-block; псевдоэлементу нельзя будет задать высоту, потому что по умолчанию тип отображения псевдоэлемента — inline (строчный).

По умолчанию тип выравнивания по вертикали псевдоэлемента в строке — baseline, поэтому требуется указание vertical-align: middle;.

Теперь HTML-форма успешно выравнена по вертикали.

Дальнейшие дополнения носят косметический характер (то есть тоже делаются для красоты). Подробно разбирать я их не буду, так как мне они сразу были понятны. Внесем окончательные изменения в стили (я отметил изменения красным цветом):
#prompt-form {           /* стиль HTML-формы */
  display: inline-block;
  padding: 5px 5px 5px 70px;
  width: 200px;
  border: 1px solid black;
  background: white url(https://en.js.cx/clipart/prompt.png) no-repeat left 5px;
  vertical-align: middle;
}
                         /* псевдоэлемент для вертикального выравнивания HTML-формы */
#prompt-form-container:before {
  display: inline-block;
  height: 100%;
  content: '';
  vertical-align: middle;
}
                         /* стиль текстового поля ввода HTML-формы */
#prompt-form input[name="text"] {
  display: block;
  margin: 5px;
  width: 180px;
}

Здесь стоит обратить внимание на значение свойства background в описании стиля HTML-формы. В нем устанавливается заливка фона HTML-формы белым white цветом (по умолчанию фон прозрачный — rgba(0, 0, 0, 0)) и указан путь к картинке, показываемой на фоне HTML-формы слева (на картинке изображены блокнот и карандаш). Именно для этой картинки в свойстве padding (внутренние отступы HTML-формы) оставлен отступ слева в 70px.

Вот как получившееся модальное диалоговое окно выглядит у меня в браузере (это картинка):



Я специально уменьшил область просмотра браузера до небольшого размера 500 × 172 (в пикселях), чтобы открытое модальное диалоговое окно находилось над содержимым «главного окна».

Продолжение тут.
Tags: Образование, Программирование
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments