JSFiddle - React, Tailwind, and code Playground
by LOOnny
HTML
<a href="#" class="show-modal">справа сверху</a>
<a href="#" class="show-modal">справа снизу</a>
<a href="#" class="show-modal">слева сверху</a>
<a href="#" class="show-modal">слева снизу</a>
<a href="#" class="show-modal-center">в центре</a>
<div class="modal-wrapper" id="modal">
<div class="modal">
<h3>Древние священные тексты.</h3>
<p>
<small>Маглам тут не на что смотреть</small>
</p>
<div style="text-align: right">
<i>© Северус Снегг</i>
</div>
</div>
</div>
CSS
body {
margin: 0;
padding: 0;
width: 100vw;
}
a {
position: absolute;
display: inline-block;
width: 130px;
height: 32px;
border-radius: .5em;
font-size: 18px;
line-height: 32px;
text-align: center;
background: lightcoral;
color: white;
text-decoration: none;
}
a:hover {
background: red;
}
a:nth-child(1) {
top: 10px;
left: 10px;
}
a:nth-child(2) {
bottom: 10px;
left: 10px;
}
a:nth-child(3) {
top: 10px;
right: 10px;
}
a:nth-child(4) {
bottom: 10px;
right: 10px;
}
a:nth-child(5) {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.modal-wrapper {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, .2);
}
.modal {
display: block;
position: absolute;
width: 260px;
height: auto;
padding: .8em 1.5em;
border-radius: .5em;
background: white;
box-shadow: 0 1em 3em rgba(0, 0, 0, .2);
}
.modal_center {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
JavaScript
(function(doc, win) {
doc.addEventListener('click', function(e) {
const
modalWrapper = doc.querySelector('#modal'),
modal = modalWrapper.querySelector('.modal');
if (e.target.classList.contains('show-modal')) {
const
clientWidth = doc.documentElement.clientWidth,
clientHeight = doc.documentElement.clientHeight,
mouseX = e.clientX,
mouseY = e.clientY;
/*
Показываем обертку перед тем как выщитывать положение
модального окна потому что когда display: none
его ширина и высота равна нулям.
*/
modalWrapper.style.display = 'block';
const
modalWidth = modal.offsetWidth,
modalHeight = modal.offsetHeight;
let x, y;
x =
clientWidth - mouseX - 8 > modalWidth ?
mouseX + 8 :
mouseX - modalWidth - 8;
y =
clientHeight - mouseY - 8 > modalHeight ?
mouseY + 8 :
mouseY - modalHeight;
modal.style.top = y + 'px';
modal.style.left = x + 'px';
}
if (e.target === modalWrapper) {
modal.style = undefined;
modal.classList.remove('modal_center');
modalWrapper.style.display = 'none';
}
/*
Или можно просто показывать модалку по центру.
Ну или снизу как в мобильном ВК.
*/
if (e.target.classList.contains('show-modal-center')) {
modal.classList.add('modal_center');
modalWrapper.style.display = 'block';
}
});
})(document, window)