Флажок внутри метки не проблема. Проблема возникает, когда этот флажок изменен ради доступности вместо полного удаления с помощью display: none
. Если в DOM существует такой интерактивный элемент, как ввод или кнопка, он все равно будет иметь значение, независимо от того, как он скрыт, если не будет применено display: none
.
В O riginal P ost флажок практически невозможно щелкнуть из-за его высоты в 0px и ширины в 1px, и все же при нажатии div, флажок щелкнул ... иногда нет. Обычно, если метка способна обнаружить щелчок, этот щелчок вызовет событие щелчка и для вложенного флажка. В коде OP этого не происходит, потому что у метки pointer-events: none
.
Значит, div получает щелчок, и каким-то волшебным чудом он получает функции, которые обычно не приписывают ему? Div не являются интерактивными, они не могут влиять на элементы, которые не вложены в себя (например, как флажок, расположенный перед div). Нет, div бесполезен, это сам флажок, на который щелкают, потому что это единственный элемент в инертной метке, который получает фокус по умолчанию. Получение фокуса на входе не обязательно гарантирует событие щелчка - фактически событие фокуса выбирает элемент, а событие щелчка устанавливает элемент как активный. Так что же происходит, когда пользователь дважды щелкает или быстро перемещает мышь, прежде чем следующий щелчок очистит ярлык? Нежелательное поведение, как описано в OP.
В следующей демонстрации флажки скрыты в соответствии с OP (также установите ширину и высоту равными 0), удалите pointer-events: none
из метки и добавьте его в флажки. В этой настройке метка получает фокус и события щелчка, а событие щелчка вызывает флажок. Флажок, который был изолирован от любых дополнительных кликов из-за pointer-events: none
и z-index: -1
, должен работать как положено.
В качестве подтверждения концепции я добавил JavaScript, чтобы продемонстрировать стабильность кода. Два обработчика событий предназначены для демонстрационных целей. JS не облегчает, не стабилизирует и не изменяет производительность поведения HTML / CSS.
При любом событии изменения в флажке (через метку) будет срабатывать function changeHandler()
собрать все значения отмеченных флажков и отобразить их в выводе.
- Если в поле есть флажок и отображается значение, соответствующее этому флажку, то оно успешно переходит в правильное состояние.
Нажав button.show
, вы включите function clickHandler()
для переключения класса .reveal
на каждый флажок.
- Быстро нажимая, обратите внимание, что установленные флажки отмечены, а также соответствующая пользовательская метка. Также обратите внимание, что значение также должно отображаться.
BTW
" .... target не работает в IE IIR C "
event.target
- это стандартное свойство, используемое в каждом современном браузере. event.srcElement
является устаревшим свойством, используемым IE, которое почти полностью не поддерживается.
pointer-events: all
присвоено input
и .customCheckbox
Значение all
относится только к SVG. Только значения none
и auto
относятся к HTML. auto
по умолчанию.
Демо
Я не могу воспроизвести описанное поведение, кроме как в коде, представленном в OP. Если вы можете воспроизвести это поведение в моей демоверсии, запишите короткое видео и опубликуйте его, а также машину / устройство, ОС и браузеры (я буду считать, что все достаточно актуально).
const main = document.forms.main;
main.onchange = checkHandler;
function checkHandler(e) {
const fc = this.elements;
const chx = [...fc.hidden];
const ui = e.target;
if (ui.matches('.hidden')) {
let text = chx.flatMap(c => c.checked ? [c.value] : []);
fc.view.value = '';
fc.view.value = text.join(', ');
}
}
main.onclick = clickHandler
function clickHandler(e) {
const fc = this.elements;
const chx = [...fc.hidden];
const ui = e.target;
if (ui.matches('button.show')) {
chx.forEach(c => c.classList.toggle('reveal'));
}
}
:root,
body {
--size: 10rem;
font: 400 small-caps 2vw/1.5 Times;
width: 100%;
height: 100%;
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
font: inherit;
}
.display {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
width: max-content;
max-height: min-content;
margin: 10px;
border: calc(var(--size) / 20) solid #000;
border-radius: 24px;
}
.view {
display: inline-block;
min-width: 35ch;
font-size: 1.5rem;
height: 1.5rem;
line-height: 1;
}
.show {
display: inline-block;
width: 12ch;
padding: 1px 3px;
margin: 4px;
border: 2px solid #000;
border-radius: 8px;
background: none;
text-align: center;
font-size: 1.25rem;
cursor: pointer;
}
.mask {
position: relative;
z-index: 2;
display: block;
width: var(--size);
height: var(--size);
padding: 0;
margin: 0 5px;
border: solid black calc(var(--size) / 10);
border-radius: calc(var(--size) / 4);
font-size: calc(var(--size) * 0.8);
background: none;
cursor: pointer;
}
.icon {
position: absolute;
z-index: 1;
top: -1.5rem;
right: 1rem;
display: inline-block;
margin: 0;
padding: 0;
border: 0;
}
.hidden {
position: relative;
z-index: -1;
display: inline-block;
width: 0;
height: 0;
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
pointer-events: none;
opacity: 0;
}
.reveal {
z-index: 0;
top: -24px;
left: 4px;
width: 1px;
height: 1px;
opacity: 1;
}
.icon::after {
content: attr(data-blank);
}
.hidden:checked+.icon::after {
content: attr(data-check);
}
<!DOCTYPE html>
<html>
<head lang='en'>
<meta charset='utf-8'>
<style></style>
</head>
<body>
<form name='main'>
<fieldset name='display' class='display'>
<output name='view' class='view'></output>
<button name='show' class='show' type='button'>Show</button>
</fieldset>
<fieldset name='display' class='display'>
<label name='mask' class='mask'>
<input name='hidden' class="hidden" type="checkbox" value='Check I'>
<fieldset name='icon' class='icon' data-check='✔' data-blank=' '></fieldset>
</label>
<label name='mask' class='mask'>
<input name='hidden' class="hidden" type="checkbox" value='Check II'>
<fieldset name='icon' class='icon' data-check='✔' data-blank=' '></fieldset>
</label>
<label name='mask' class='mask'>
<input name='hidden' class="hidden" type="checkbox" value='Check III'>
<fieldset name='icon' class='icon' data-check='✔' data-blank=' '></fieldset>
</label>
<label name='mask' class='mask'>
<input name='hidden' class="hidden" type="checkbox" value='Check IV'>
<fieldset name='icon' class='icon' data-check='✔' data-blank=' '></fieldset>
</label>
</fieldset>
</form>
<script></script>
</body>
</html>