Вывод HTML-элемента на передний план с помощью z-index при переполнении в CSS - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь получить у синего прямоугольного контейнера больший z-index, чем у других полей при наведении на элементы, которые overflow контейнера.

Игра 3 здесь имеет больший z-индекс, но я хочу получить доступ к Loser select в синем круге ниже, однако я не могу, если я не наведусь назад на синий прямоугольник, чтобы получитьфокус.

Есть ли способ обойти это, где он может быть обработан только с помощью CSS или мне нужен JQuery?

Я создал Fiddle, который может копировать это, так что игнорируйте любые ошибки JS, так как для реальной страницы требуетсядовольно много включает, однако проблема в такте.Наведите курсор на 4-ую игру, в которой есть три выпадающих списка: «Источник», «Бассейны», «Семена».Вы можете выбрать Семена просто отлично.Однако, наведите курсор мыши на другую игру вверху, затем вернитесь к «Семенам», вы не сможете выбрать его, если снова не наведите курсор на «Бассейны».Мне нужно, чтобы «Семена» всегда можно было выбирать независимо от того, что является переполнением.

https://jsfiddle.net/cblaze22/qp4L15tj/8/

enter image description here

ТокКод для наведения игры (область синего прямоугольника)

.forward помещает большой zindex в область синего прямоугольника.

$(element).hover(
                function () {
                    if (!$(this).parent().hasClass('editing')) {
                        $(this).addClass('forward');
                    }
                },
                function() {
                    $(this).removeClass('forward');
                }
            );

Ответы [ 3 ]

0 голосов
/ 12 апреля 2019

Чтобы перейти непосредственно к делу: нет чистого решения только для CSS вашей проблемы.
Поскольку все ваши элементы в значительной степени идентичны (и под этим я подразумеваю class дляпример) вы не найдете решение, которое охватывает все конфигурации.Поскольку они не отличаются друг от друга, все они имеют одинаковый z-index, но не одинаковый контекст стека.Если вы не предоставите их родителям другой z-index или не измените контекст стека, вы не сможете получить доступ к заблокированному элементу.Это также сводится к тому, насколько вы ограничены в изменении кода.Код выглядит так, как будто он был собран JS, и вы просто скопировали его на скрипку, чтобы мы могли его протестировать.

Попытка # 1

Попытка # 1 - просто добавить максимум z-index напрямуюсоответствующему родителю.
@ mmshr уже пытался это сделать.Однако он попытался дать всему классу высокий z-index, что, конечно, не сработает, как вы уже указали.

Однако вы можете попытаться дать этому элементу только высокийЭлемент z-index в его атрибуте style.Это сводится к тому, насколько вы ограничены в изменении кода.Вы можете теоретически использовать JQuery для этого, но способ выбора элемента (например, nth-child()) приводит меня к Попытка # 2 , которая использует тот же псевдокласс и является попыткой только CSS, поэтому использованиеJS это ерунда в этом случае.Кстати, если вы можете изменить свой код таким образом, вы можете удалить свою маленькую функцию JQuery, которая добавляет класс forward к hover.

Попытка # 2

Эта попытка работает отлично, и вы не ограничены возможностью изменять код, так как это в значительной степени одна строка CSS.Как уже говорилось в Попытка # 1 , вы можете использовать pseudo-class, чтобы выбрать этот элемент.Однако это не действительно для всех конфигураций.Если вы добавите один элемент
(<div data-bind="template: { name: 'bracket-template', data: $data }">...</div>) до вашего заблокированного элемента, вам придется каждый раз менять свой CSS.Но если нет необходимости менять элементы и конфигурации (или, по крайней мере, не порядок), это правильное решение:

#bracket-wrapper > div > div:nth-child(8) > div > div {
  z-index: 2 !important;
}

В этой попытке вы можете (и должны) удалить свою маленькую функцию JQuery тоже:

$('.bracket-part').hover(
  function() {
    debugger;
    $(this).addClass('forward');
  },
  function() {
    $(this).removeClass('forward');
  }
);

Удалить все целиком.

Попытка # 3

Вероятно, самая чистая и лучшая попытка - использовать stacking context.Контекст стекирования объясняется прямо здесь .Но для простоты обзора ( W3C ):

Каждый блок относится к одному стековому контексту.Каждый позиционированный блок в данном контексте стека имеет целочисленный уровень стека, который является его позицией на оси z относительно других уровней стека в том же контексте стека.Ящики с более высокими уровнями стека всегда форматируются перед ячейками с более низкими уровнями стека.Коробки могут иметь отрицательные уровни стека.Ящики с одинаковым уровнем стека в контексте стекования располагаются задом наперед в соответствии с порядком дерева документов.

Наиболее важной является эта часть, поскольку она применяется к вашей структуре:

Ящики с одним и тем же уровнем стека в контексте стекирования располагаются задом наперед в соответствии с порядком дерева документов.

Если вы посмотрите на свое HTML-дерево, вы увидите следующее:HTML tree

В соответствии с контекстом стекирования мы должны быть в состоянии дать вашему элементу на заднем плане более высокий порядок стеков, чем ваш элемент впереди, изменив порядок этих элементовв вашем дереве.

Это всего лишь предположение, но у вас, вероятно, есть что-то вроде массива, в котором вы храните данные, а какой-то JS-файл строит из него турнирную сетку.Если бы вы могли как-то изменить порядок этих двух элементов (например, изменив порядок вашего массива), вы бы не использовали CSS и не использовали бы никакого дополнительного JQuery.

Что если нетиз этих работ?

Ну, тогда я не вижу решения, которое требует только CSS.

Я также думал о возможном решении JS, но это сложное решение, и я не мог найти (простое) решение. Позвольте мне объяснить проблему:

Поскольку ваш select находится за элементом div, JQuery не распознает его (например,) на hover, поэтому вам придется снова использовать псевдоклассы, которые я уже рассмотрел при попытке использовать только CSS.
Я также думал о добавлении z-index из -1 к блокирующему элементу, потому что JQuery мог распознать его при наведении курсора. Но это также приводит к проблемам: блокирующий элемент теперь находится на заднем плане, а заблокированный элемент спереди, и вы также можете щелкнуть по нему. Проблема в том, что (прежний) блокирующий элемент теперь стоит за #bracket-wrapper. Это также недопустимое решение, потому что вам придется снова использовать псевдокласс для нацеливания на этот конкретный элемент.

Заключение

Я буду честен с вами: это турнирное дерево плохо спроектировано и структурировано. Не должно быть перекрывающихся элементов или элементов вне контейнера и, конечно, не оба в комбинации. Если ни одна из моих попыток не подходит, я не вижу решения CSS или JS. По крайней мере, не простой. Вы предоставили мало информации о том, как строится дерево турниров, но если вы это сделаете, все может измениться.
В этом состоянии я думаю, что восстановление всей этой структуры - единственное действительно чистое решение.

Редактировать

Решение № 1 от @ Deckerz

@ Deckerz предоставил отличное решение, которое не фокусируется на z-index. Вместо этого он использует pointer-events. Я попробовал этот подход, но потерпел неудачу, потому что я забыл важную часть. Логика этого проста:

Сначала вы отключаете все события щелчка на всем внутри .bracket-part, так как они не нужны. Затем вы добавляете события клика обратно на выбор. Чтобы сделать его более универсальным для более простого использования, вы можете просто изменить select в селекторе CSS на класс .re-enable-events или что-то в этом роде. JS о z-index на самом деле не был нужен.

#bracket-wrapper .bracket-part select {
   pointer-events: all !important;
}
#bracket-wrapper .bracket-part {
   pointer-events: none;
}

Однако это все еще обходной путь. Я все еще рекомендую реструктурировать ваш код и CSS.

0 голосов
/ 12 апреля 2019

Это было на самом деле удивительно легко исправить, когда вы поняли структуру и реальную проблему.Див покрывает див.Сначала вы отключаете все события щелчка на всем внутри .bracket-part, так как они не нужны.Затем вы добавляете события клика обратно на выбор.Чтобы сделать его более универсальным для более легкого использования, вы можете просто изменить select в селекторе CSS на класс .re-enable-events или что-то в этом роде.JS о z-index на самом деле не был необходим.

#bracket-wrapper .bracket-part select {
  pointer-events: all !important;
}
#bracket-wrapper .bracket-part {
  pointer-events: none;
}

См .: https://jsfiddle.net/uws8pf1y/

События указателя имеет очень хороший уровень совместимости, поэтому это решение должно быть в порядкепрактически на всех устройствах.

0 голосов
/ 10 апреля 2019

Если вы хотите, чтобы Seeds на всегда можно было выбирать, почему бы не всегда дать его bracket-part родительскому элементу высокий z-index?

Прямо сейчас, z-index имеет высокий уровень только после зависания bracket-part.Хотя Seeds технически является потомком bracket-part, он расположен за его пределами, поэтому, если селектор Seeds не находится непосредственно после bracket-part, он не будет доступен для выбора.

Если вы добавите z-index: 10000; к родительским стилям Seeds 'bracket-part, Seeds всегда будет доступен для выбора:

<div class="part bracket-part ui-draggable ui-resizable ui-draggable-disabled ui-state-disabled" data-bind="bracketPartInit: { left: $data.left, top: $data.top, height: $data.height, width: $data.width, disabled: $root.members.bracket.disableDrag, minHeight: $data.minHeight }, css: { 'dash-top' : $data.dashedBorderTop(), 'dash-right' : $data.dashedBorderRight(), 'dash-bottom' : $data.dashedBorderBottom(), 'dash-left' : $data.dashedBorderLeft(), 'reverse-bracket' : $data.type() == 2, 'box-bracket': $data.type() == 13, 'bye': $data.bye()}" aria-disabled="true" style="top: 459px; left: 0px; height: 80px; width: 150px; z-index: 10000;">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...