为啥 :read-only CSS 伪类应用于此复选框?
Posted
技术标签:
【中文标题】为啥 :read-only CSS 伪类应用于此复选框?【英文标题】:Why is :read-only CSS pseudo-class being applied on this checkbox?为什么 :read-only CSS 伪类应用于此复选框? 【发布时间】:2022-01-19 08:06:30 【问题描述】:我有以下 SCSS 代码:
input[type="checkbox"]
...
&:read-only, &[readonly]
cursor: default;
filter: grayscale(1);
这将应用于 <input type="checkbox" id="checkbox" onChange=this.rememberMe />
遵循MDN: :read-only 文档:
它将选择用户无法编辑的任何元素。
为什么它被应用到我的可编辑输入上?
该问题同时适用于 Firefox 和 Chrome。
【问题讨论】:
【参考方案1】: 因为<input type="checkbox" />
和<input type="radio" />
(以及大多数其他元素)本质上是只读的。
与<input type="text" />
或<input type="date" />
不同,当您与复选框或单选按钮交互(即切换)时,您不会更改其value
,而是更改其checked
状态。
是的,我同意这是违反直觉的。
因此...
-
您不应出于任何目的将
<input readonly
属性应用于radio
或checkbox
。
因为它不会做任何有用的事情。
您不应定义一个 CSS 选择器,该选择器使用 :read-only
伪类来选择具有显式 html <input readonly
属性集的 <input>
元素。
改为使用 has-attribute-selector:input[readonly]
。
完全避免使用:read-only
伪类because it also selects pretty-much every HTML element on the page too; a function with little practical utility, imo 可能是个好主意。
现在,如果您想要一个“只读复选框/收音机”,那么很遗憾,您没有太多好的选项;相反,您有可怕的选择和勉强足够的选择......:
There is this popular QA,但是大多数投票最高的答案都有我认为坏主意的建议:例如依赖客户端脚本来阻止用户交互...very imperfectly (来自那些不知道收音机和复选框可以通过多种方式进行操作的人,而不仅仅是onclick
),或者使用CSS的pointer-events: none;
,而完全无视计算机键盘既存在也经常被人类计算机操作员使用。
我认为最差的建议是使用<input type="checkbox/radio" disabled />
、as demonstrated with this answer。 (The <input type="hidden">
is necessary because disabled (and unchecked) inputs are not submitted,这是 1990 年代后期当时新兴的浏览器供应商对principle of least astonishment 的又一次违反。
如果您想在所有input
元素除了 单选框和复选框上使用:read-only
伪类,那么您需要仔细考虑(并对其进行测试,使用document.querySeletorAll("input:read-only")
的变体)在浏览器的控制台中!)
我建议您不要在没有明确指定 [type=""]
属性选择器的情况下使用 input
元素的选择器应用任何样式 - 这是因为带有“input
”之类选择器的样式(没有任何属性选择器)将应用于我们还不知道的未来 HTML 输入元素,并且可能在不久的将来的任何时候引入,也许下周谷歌浏览器会添加一个新的 <input type="human-dna-sample" />
或微软将 <input type="clippy" />
添加到他们的 Edge 浏览器的特别 retro 版本中 - 所以你绝对不希望将 :read-only
样式应用于这些元素,直到你至少知道它的外观和工作方式 - 并且因此浏览器将使用其默认/本机样式,如果他们碰巧在您的网站上遇到它,这不会违反您的用户/访问者的期望。
...所以这意味着您需要为每个已知的<input type="...">
写出规则作为重复的input[type=""]
样式规则,现在您可能想知道是否有任何基于默认值的input
元素的伪类原生外观,因为它们中的许多确实看起来共享相似(如果不完全相同)的原生外观和视觉语义(以及阴影 DOM 结构,如果适用) - 例如在桌面 Chrome 中,输入类型 text
、password
、@ 987654360@、search
、url
、tel
和更多显然都是围绕同一个原生 textbox 小部件构建的,所以 肯定 肯定是一个伪类对于不同的输入“种类”,对吧?像input:textbox-kind
代表text
、password
等,input:checkbox-kind
代表checkbox
和radio
- 不幸的是这样的东西不存在,如果明天推出,W3C 的 CSS 委员会可能不会批准它至少再过几年——所以在那之前我们需要明确枚举我们所知道的每一个input[type=""]
,以便我们可以准确地预测浏览器将如何使用我们的type=""
-specific 样式呈现它们规则而不是把所有东西都扔成input
看看有什么坚持。
...幸好列表不是too long,所以我刚刚把规则写出来了:
随意复制+粘贴;它甚至几乎没有版权。 我想看看这在我有生之年在互联网上传播到什么程度。
底部是一个 CSS 选择器,它将通过使用一组详尽的 :not([type="..."])
选择器以及不匹配的 input
元素仅选择 未来 的 <input
元素type=""
属性为空或完全缺失。
/* Textbox-kind: */
input[type="text"]:read-only,
input[type="password"]:read-only,
input[type="search"]:read-only,
input[type="tel"]:read-only,
input[type="url"]:read-only,
input[type="email"]:read-only,
input[type="number"]:read-only
background-color: #ccc;
cursor: 'not-allowed';
/* Date/time pickers: */
input[type="date"]:read-only,
input[type="datetime-local"]:read-only,
input[type="time"]:read-only,
input[type="week"]:read-only,
input[type="month"]:read-only
background-color: #ccc;
cursor: 'not-allowed';
/* Button-kind (these are all practically obsolete now btw, as the <button> element is far, far, far superior in every way) */
input[type="button"]:disabled,
input[type="reset"]:disabled,
input[type="submit"]:disabled,
input[type="image"]:disabled
background-color: #ccc;
border: 1px outset #666;
cursor: 'not-allowed';
color: #666;
text-shadow: 0 1px rgba(255,255,255,0.2);
/* Checkbox-kind (Don't use `:read-only` with these): */
input[type="checkbox"]:disabled,
input[type="radio"]:disabled
/* I'm not setting any properties here because it's impossible to effectively style these elements without resorting to image-replacements using the `:checked` state in selectors for their parent or adjacent `<label>` or ::before/::after` of other proximate elements. */
/* Weird-stuff-kind: */
input[type="color"]:read-only,
input[type="file"]:read-only,
input[type="hidden"]:read-only,
input[type="range"]:read-only
/* Again, due to differences in how different browsers and platforms display (and consequently style) these inputs I don't think it's worth doing anything. */
/* If you **really** want to select _future_ <input> elements in-advance... do this: */
input[type]:not([type="text"]):not([type="password"]):not([type="search"]):not([type="tel"]):not([type="url"]):not([type="email"]):not([type="number"]):not([type="date"]):not([type="datetime-local"]):not([type="time"]):not([type="week"]):not([type="month"]):not([type="button"]):not([type="reset"]):not([type="submit"]):not([type="image"]):not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]):not([type="hidden"]):not([type="range"])
【讨论】:
现在很清楚了。谢谢。以上是关于为啥 :read-only CSS 伪类应用于此复选框?的主要内容,如果未能解决你的问题,请参考以下文章
为啥用css中伪类hover实现(鼠标悬停显示文字,鼠标移走文字消失)的效果失败(脚本没有错)?