- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的自定义复选框有问题。
如果您单击一个复选框元素,移动鼠标光标然后在复选框区域内释放单击,则该复选框被选中。
但是,如果您对自定义复选框(此处为标签内的 div)执行相同操作,则不会选中该复选框。
这是一个问题,因为如果你想快速选中一个复选框,你可能会在按下鼠标按钮之后和释放鼠标之前移动鼠标,从而不会切换复选框。
用户有义务点击而不移动鼠标。
我知道我可以使用 JS 来模拟带有 div 的复选框,但我希望 HTML 在语义上是正确的,所以:是否可以在没有 js 的情况下修复它?
代码如下:
/* 1. Hide the checkbox */
.hidden {
/* https://zellwk.com/blog/hide-content-accessibly/ */
border: 0;
clip: rect(0, 0, 0, 0);
height: auto;
margin: 0;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
/* 2. Use a label to retrieve the click event */
label {
/* not used directly to prevent the bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=608180 */
pointer-events: none;
display: inline-flex;
}
label > input {
/*usefull for testing only*/
pointer-events : all;
}
label > .customCheckbox {
cursor: pointer;
display: inline-flex;
justify-content: center;
align-items: center;
position: relative;
--size:200px;
width: var(--size);
height: var(--size);
font-size: calc(var(--size)/2);
pointer-events: all;
}
label > .customCheckbox::selection{
/* prevent highliting the text within the custom checkbox */
background: none;
}
label > .customCheckbox:after {
z-index: -1;
content: "✔";
display: inline-flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: calc(var(--size)/4);
border: solid black calc(var(--size)/10);
}
label > input:not(:checked) + div.customCheckbox:after {
background:#0000;
content: "\a0";
}
<input type="checkbox"/>
<label >
<input type="checkbox" class="hidden"/>
<div class="customCheckbox"></div>
</label >
我需要将复选框放在标签内,因为我不能使用“for”属性。
非常感谢您的帮助!
编辑:对于那些想知道的人,这里是 js 解决方案(不理想但因为我不能在 CSS 中做到这一点,总比没有好):
let checkboxes = document.getElementsByClassName("customCheckbox");
for(let i=0; i<checkboxes.length; i++){
checkboxes[i].addEventListener('mouseover', (e)=>{handleMouseOverCheckbox(e)})
checkboxes[i].addEventListener('mousedown', (e)=>{handleMouseOverCheckbox(e)})
}
function handleMouseOverCheckbox(e) {
e.srcElement.previousElementSibling.disabled = "true";
if (e.buttons == 1) {
e.srcElement.previousElementSibling.checked= !e.srcElement.previousElementSibling.checked;
}}
编辑 2:这是我能想到的最佳解决方案,感谢 @zer00ne
最佳答案
标签内的复选框没有问题。当为了可访问性而不是使用 display: none
完全删除该复选框而更改该复选框时,就会出现问题。当 DOM 中存在诸如输入或按钮之类的交互式元素时,无论它如何隐藏,它仍然是一个因素,除非应用 display: none
。
在 Ooriginal Post 中,复选框几乎不可能被点击,因为它的高度为 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
类切换到每个复选框。
"....target doesn't work in IE IIRC"
event.target
是每个现代浏览器中使用的标准属性。 event.srcElement
是 IE 使用的弃用属性,几乎完全不受支持。
pointer-events: all
assigned toinput
and.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>
关于html - 单击并拖动标签时,自定义复选框不会切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61305418/
我有几个系统使用 docker-compose 并且没有问题。 但是,我在这里有一个“向下”根本不做任何事情的地方。 'up'虽然完美。这是在 MacOS 上。 该项目的昵称是“ Storm ”,脚本
解释起来确实很奇怪,所以就这样...... 我正在从 phpmyadmin 获取包含未转义单引号的数据。我正在尝试转换'至'通过使用Content-Type: text/html;在 php
伙计们?在这里需要一些帮助。我使用委托(delegate)协议(protocol)将一些字符串从“第二个 View Controller ”传回给它的前一个。 我的数组附加了我在委托(delegate
我有以下 eval() 东西: c = Customer() eval("c.name = row.value('customer', '{c}')".format(c=column_name), {
我写了这个测试类: @ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" }) public class Candi
我这样写代码: @ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" }) @RunWith(SpringJUnit
假设我更改了文件,然后进行 pull 。 Git 会报错,因为本地仓库还没有保存,将被覆盖。如果我然后删除该添加并使文件与以前相同(与远程 repo 相同),那么会发生 pull 吗? 最佳答案 是的
我正在阅读《Java for Dummies》一书,但遇到了问题。我不明白为什么 @Override 不起作用。我确信这与我的代码有关,因为我之前已经获得了一个多态数组来使用覆盖,但它对我来说太简单了
我从我的项目中提取了这段代码,因为我试图找到我犯的一个错误,该错误使我的 BeginStoryboard 无法自行停止。我尽可能地简化了代码,但仍然没有发现问题。你认为它可能是什么?
这个问题在这里已经有了答案: Difference between char[] and char * in C [duplicate] (3 个答案) 关闭 7 年前。 我想我知道自己问题的答案,
我一直在使用 java 的 Scanner 类时遇到问题。我可以让它很好地读取我的输入,但问题是当我想要输出一些东西时。给定多行输入,我想在完全读取所有输入后只打印一行。这是我用来读取输入的代码:
对于这个问题,我已经用最简单的术语表达了这一点。 如果元素被点击,'active'类被添加到元素,'active'类从其他元素中移除。 但是,如果该元素是“事件的”并且它被第二次单击,则“事件”类不应
这会在桌面上创建一个新文件夹,但不会将文件夹 .pfrom 的内容 move 到文件夹 .pTo。 int main() { SHFILEOPSTRUCT sf = {0}; TCHA
我有一个关于多线程调试 DLL (/MDd) 和多线程调试 (/MTd) 设置的问题。它们之间的区别很明显:一个是使用动态库,一个是使用静态库。当我使用/MDd 编译我的程序时,一切都进行得很好。但是
我的问题是,如果我在页面加载时创建一个克隆变量,jQuery 只会 append 它一次。奇怪! Click to copy This is an element! $(document)
所以...我是一个开发 django 应用程序的新手,但是当我尝试通过 virtualbox heroku 运行 heroku run python manage.py syncdb 时,它一直在下面
我在 Spring Boot 初始化时遇到了问题。我在一个简单的 Spring Boot 项目中有这个结构。 com.project.name |----App.java (Annoted with
我在 www.7hermanosmx.com/menu.php 页面上有以下代码 - 一切正常,除了黄色框(类 menuholder)应该每行三个相互 float 。他们坚决拒绝这样做!我知道我做错了
我正在尝试在我正在构建的小型网站上添加一个下拉菜单。出于某种原因,我可以获得我想要向下滑动到 fadeOut() 的 div 并执行其他类似的操作,但我无法将它获取到 slideDown()。我不知道
我有一个不能正确 float 的 div。当您切换可见性时,它会覆盖一些当前文本,但我可以稍后移动它。只是好奇为什么它不能正确 float ! Simple Tabs with CSS &am
我是一名优秀的程序员,十分优秀!