Как показать содержимое за overflow scroll?
Нужно как-то показать содержимое за проделами overflow.
$blue: #0084ff;
$blue-darker: darken($blue, 5);
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.backpack {
width: 300px;
height: 300px;
background-color: #000;
overflow-y: scroll;
&__container {
display: grid;
grid-template-columns: repeat(3, 85px);
gap: 10px;
}
&__item {
width: 90px;
height: 50px;
position: relative;
background-color: #ff0000;
cursor: pointer;
&:hover > .backpack__itemDescription {
display: block;
}
}
&__itemDescription {
display: none;
width: 150px;
height: 100px;
position: absolute;
background-color: #fff;
top: 0;
left: 0;
z-index: 1000;
}
}
<div class="backpack">
<div class='backpack__container'>
<div class='backpack__item'>
<div class='backpack__itemName'>
item_name
</div>
<div class='backpack__itemDescription'>
item_hover
</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>
item_name
</div>
<div class='backpack__itemDescription'>
item_hover
</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>
item_name
</div>
<div class='backpack__itemDescription'>
item_hover
</div>
</div>
</div>
</div>
Может есть другие способы это сделать? Ссылка на пример: http://jsfiddle.net/3qnjst19/
Ответы (1 шт):
Правильно делать Описание (Description), в виде полноценной всплывающей подсказки или модального окна или, вовсе, отдельной страницей. Но, раз такая задумка, и хочется "по-лёгкому", то могу предложить два варианта (недостатков много, но такова цена простоты):
JS, CSS и "недоподсказка"
- Создаём дополнительный
<div>и используем его в качестве слоя-контейнера для показа описаний. - При наведении на какой-либо
.backpack__item, находим в нём.backpack__itemDescriptionи клонируем найденное в "слой-подсказку", не забывая при этом правильно позиционировать. - После ухода курсора из блока, удаляем клонированное содержимое.
const oB = document.querySelector(".backpack");
const oBC = document.querySelector(".backpack__container");
const oBIDL = document.querySelector(".backpack__itemDescription-layer");
oBC.addEventListener("mouseover", function(ev) {
let oT = ev.target;
if ((oP = oT.closest(".backpack__item"))) {
let oCD = oBIDL.appendChild(
oP.querySelector(".backpack__itemDescription").cloneNode(true)
);
oBIDL.style.left = `${oP.offsetLeft}px`;
oBIDL.style.top = `${oP.offsetTop - oB.scrollTop}px`;
}
});
oBC.addEventListener("mouseout", function() {
oBIDL.innerHTML = "";
});
body {
background: #20262e;
padding: 20px;
font-family: Helvetica;
}
.backpack {
width: 300px; height: 300px;
background-color: #000;
overflow-y: scroll;
}
.backpack__container {
display: grid;
grid-template-columns: repeat(3, 85px);
gap: 10px;
}
.backpack__item {
width: 90px; height: 50px;
position: relative;
background-color: #ff0000;
cursor: pointer;
}
.backpack__itemDescription {
display: none;
width: 150px; height: 100px;
position: absolute;
background-color: #fff;
top: 0; left: 0; z-index: 1000;
}
.backpack__itemDescription-layer .backpack__itemDescription {
display: block;
}
.backpack__itemDescription-layer {
position: absolute;
pointer-events: none;
}
<div class="backpack">
<div class='backpack__container'>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
</div>
</div>
<div class='backpack__itemDescription-layer'></div>
Основной минус данного подхода - проблемы позиционирования (и поведение в целом) при прокрутке блока.
CSS и выравнивание
На мой взгляд, более изящно это можно решить, если не давать описаниям выходить за границы блока.
- Здесь просто задаём выравнивание (влево-центр-вправо), в зависимости от расположения блоков.
body {
background: #20262e;
padding: 20px;
font-family: Helvetica;
}
.backpack {
width: 300px; height: 300px;
background-color: #000;
overflow-y: scroll;
}
.backpack__container {
display: grid;
grid-template-columns: repeat(3, 85px);
gap: 10px;
}
.backpack__item {
width: 90px; height: 50px;
position: relative;
background-color: #ff0000;
cursor: pointer;
}
.backpack__itemDescription {
display: none;
width: 150px; height: 100px;
position: absolute;
background-color: #fff;
top: 0; z-index: 1000;
pointer-events: none;
}
.backpack__item:hover>.backpack__itemDescription {
display: block;
}
.backpack__item:nth-child(3n-2) .backpack__itemDescription {
left: 0;
}
.backpack__item:nth-child(3n-1) .backpack__itemDescription {
left: 50%; transform: translatex(-50%);
}
.backpack__item:nth-child(3n) .backpack__itemDescription {
right: 0;
}
<div class="backpack">
<div class='backpack__container'>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
<div class='backpack__item'>
<div class='backpack__itemName'>item_name</div>
<div class='backpack__itemDescription'>item_hover</div>
</div>
</div>
</div>
Минуса два: описания должны быть довольно краткими и должно быть фиксированное количество блоков в строке.