У меня есть раскрывающийся элемент управления, который реализует диалог (кажется, div будет вести себя так же), есть ли способ разместить его поверх модального диалога, чтобы он вел себя как раскрывающийся список и был независим от модального окна? Пробовал несколько вещей с z-index
, безуспешно:
modal.showModal();
.dialog,
.popup {
z-index: 100000;
position: absolute;
}
#modal {
z-index: 1000;
top: 90px;
}
.popup {
top: 70px;
background: #faa;
border: 1px solid gray;
}
dialog,
.popup {
width: 400px;
height: 300px;
}
<dialog open class = "dialog">Dialog</dialog>
<div class = "popup">Popup</div>
<dialog id = "modal">Modal
<dialog open class = "dialog">Dialog</dialog>
<div class = "popup">Popup</div>
</dialog>
Нет проблем с открытием модального наведения на открытое...
modal1.showModal();
modal2.showModal();
#modal1 {
width: 400px;
height: 300px;
}
#modal1::backdrop {
background: rgba(255,0,0,.4);
}
#modal2 {
width: 200px;
height: 100px;
}
#modal2::backdrop {
background: rgba(0,0,255,.4);
}
<dialog id = "modal1">modal 1 use escape</dialog>
<dialog id = "modal2">modal 2 use escape</dialog>
Открыть <диалог> можно двумя способами:
С помощью метода .showModal()<dialog>
ведет себя как модальное окно. Модальное окно заблокирует остальную часть страницы от взаимодействия с пользователем, поэтому раскрывающийся список определенно будет недоступен, пока модальное окно открыто.
Или с помощью метода .show(), который заставляет его вести себя как диалог. Диалог не мешает взаимодействию пользователя со страницей, поэтому раскрывающийся список определенно доступен, пока диалог открыт.
Если вы хотите, чтобы <dialog>
открывался при загрузке страницы, используйте методы вместо атрибута [open]
, потому что у вас будет больше контроля и больше возможностей. В примере ниже есть два <button>
, которые открывают <dialog>
в обе стороны. Также есть раскрывающийся список для тестирования обоих режимов. Подробности прокомментированы в примере.
// Reference <dialog>
const popup = document.getElementById("popup");
// Reference the first <form>
const bg = document.forms.btnGrp;
// Reference all <button>s in first <form>
const io = bg.elements;
// Reference the second <form>
const df = document.forms.dmForm;
// Reference all <button>s, <fieldset>s, and <output> in second <form>
const oi = df.elements;
// Reference <output>
const msg = oi.message;
// Bind first <form> to the "submit" event in order to prevent redirect
bg.onsubmit = e => e.preventDefault();
/**
* Bind #modBtn to the "click" event. When event is triggered:
* - the .showModal() method open #popup as a modal
* - #message will display blue text
* - #modBtn and #dlgBtn will be disabled
*/
io.modBtn.onclick = e => {
popup.showModal();
msg.value = `This is a modal not a dialog.`;
io.dlgBtn.toggleAttribute("disabled");
e.target.toggleAttribute("disabled");
}
/**
* Bind #dlgBtn to the "click" event. When event is triggered:
* - the .show() method open #popup as a dialog
* - #message will display blue text
* - #modBtn and #dlgBtn will be disabled
*/
io.dlgBtn.onclick = e => {
popup.show();
msg.value = `This is a dialog not a modal.`;
io.modBtn.toggleAttribute("disabled");
e.target.toggleAttribute("disabled");
}
/**
* Bind #popup to the "close" event. When #popup closes #dlgBtn and #modBtn
* will be re-enabled
*/
popup.onclose = e => {
io.modBtn.toggleAttribute("disabled");
io.dlgBtn.toggleAttribute("disabled");
}
:root {
font: 4vmin/1.1 "Segoe UI"
}
body {
background: #bbb;
}
main {
position: relative;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
height: 1.5rem;
padding: 0.5rem 1rem 0.25rem;
border-bottom: 3px outset grey;
}
#dropdown {
position: absolute;
z-index: 100;
top: -0.25rem;
left: 0;
width: 50%;
background: #ddd;
}
summary {
padding: 0.25rem 0.75rem;
cursor: pointer
}
.navLnx {
list-style: none;
padding: 0
}
li {
margin-bottom: 0.25rem
}
a {
display: block;
width: 100%;
}
#btnGrp {
position: absolute;
top: -0.2rem;
right: 0;
height: fit-content;
padding: 0;
}
#dmForm {
display: flex;
justify-content: center;
}
button {
font: inherit;
cursor: pointer
}
#popup {
max-width: 70vw;
border: 0;
background: transparent;
}
#popup::backdrop {
background: rgba(0 0 0 / 50%);
}
fieldset {
padding-bottom: 0.75rem;
border: 0;
border-radius: 8px;
background: #fff;
}
legend {
margin-bottom: 0.5rem;
padding: 0.25rem 0;
border: 0;
font-size: 1.1rem;
transform: translateY(1.25rem);
}
#message {
font: inherit;
font-weight: 500;
color: blue;
}
#popup ul {
margin-right: 1rem;
}
<main>
<header>
<details id = "dropdown">
<summary>Dropdown</summary>
<nav>
<menu class = "navLnx">
<li><a href = "/">0</a></li>
<li><a href = "/">1</a></li>
<li><a href = "/">2</a></li>
<li><a href = "/">3</a></li>
<li><a href = "/">4</a></li>
<li><a href = "/">5</a></li>
<li><a href = "/">6</a></li>
<li><a href = "/">7</a></li>
<li><a href = "/">8</a></li>
<li><a href = "/">9</a></li>
<li><a href = "/">A</a></li>
<li><a href = "/">B</a></li>
<li><a href = "/">C</a></li>
<li><a href = "/">D</a></li>
<li><a href = "/">E</a></li>
<li><a href = "/">F</a></li>
</menu>
</nav>
</details>
<form id = "btnGrp">
<button id = "modBtn">Modal</button>
<button id = "dlgBtn">Dialog</button>
</form>
</header>
<dialog id = "popup">
<fieldset>
<legend>Modal or Dialog?</legend>
<p>
<output id = "message" form = "dmForm"></output>
</p>
<ul>
<li>A modal takes priority and focus from everything else on the page. Normal interaction is blocked with the exception being the modal of course.</li>
<li>A dialog doesn't monopolize the user's attention and interaction with the page is possible whilst the dialog is open.</li>
</ul>
<p>The OP probably wants the latter.</p>
<form id = "dmForm" method = "dialog">
<button>OK</button>
</form>
</fieldset>
</dialog>
</main>
Спасибо за ответы, я только что решил открыть модальный полный размер страницы и использовать его в качестве окна верхнего слоя, где я показываю реальный диалог, такой как контейнер, и все остальные раскрывающиеся списки, добавленные к нему (не к телу), будут вести себя так, как я нуждаться
Хм, я неправильно понял. Выпадающие списки в реальном всплывающем окне кажутся тривиальными... у вас, должно быть, проблема, которую слишком сложно воспроизвести во фрагменте. Я только что нашел это: Popover API , который позволяет вам использовать любой элемент контента в качестве диалога, удачи, сэр. Кстати, этот ответ на самом деле должен быть комментарием.